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_printf __ARGS((typval_T *argvars, typval_T *rettv)); 566 static void f_range __ARGS((typval_T *argvars, typval_T *rettv)); 567 static void f_readfile __ARGS((typval_T *argvars, typval_T *rettv)); 568 static void f_remote_expr __ARGS((typval_T *argvars, typval_T *rettv)); 569 static void f_remote_foreground __ARGS((typval_T *argvars, typval_T *rettv)); 570 static void f_remote_peek __ARGS((typval_T *argvars, typval_T *rettv)); 571 static void f_remote_read __ARGS((typval_T *argvars, typval_T *rettv)); 572 static void f_remote_send __ARGS((typval_T *argvars, typval_T *rettv)); 573 static void f_remove __ARGS((typval_T *argvars, typval_T *rettv)); 574 static void f_rename __ARGS((typval_T *argvars, typval_T *rettv)); 575 static void f_repeat __ARGS((typval_T *argvars, typval_T *rettv)); 576 static void f_resolve __ARGS((typval_T *argvars, typval_T *rettv)); 577 static void f_reverse __ARGS((typval_T *argvars, typval_T *rettv)); 578 static void f_search __ARGS((typval_T *argvars, typval_T *rettv)); 579 static void f_searchpair __ARGS((typval_T *argvars, typval_T *rettv)); 580 static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); 581 static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); 582 static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); 583 static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); 584 static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); 585 static void f_setqflist __ARGS((typval_T *argvars, typval_T *rettv)); 586 static void f_setreg __ARGS((typval_T *argvars, typval_T *rettv)); 587 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv)); 588 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv)); 589 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv)); 590 static void f_soundfold __ARGS((typval_T *argvars, typval_T *rettv)); 591 static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv)); 592 static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv)); 593 static void f_split __ARGS((typval_T *argvars, typval_T *rettv)); 594 #ifdef HAVE_STRFTIME 595 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv)); 596 #endif 597 static void f_stridx __ARGS((typval_T *argvars, typval_T *rettv)); 598 static void f_string __ARGS((typval_T *argvars, typval_T *rettv)); 599 static void f_strlen __ARGS((typval_T *argvars, typval_T *rettv)); 600 static void f_strpart __ARGS((typval_T *argvars, typval_T *rettv)); 601 static void f_strridx __ARGS((typval_T *argvars, typval_T *rettv)); 602 static void f_strtrans __ARGS((typval_T *argvars, typval_T *rettv)); 603 static void f_submatch __ARGS((typval_T *argvars, typval_T *rettv)); 604 static void f_substitute __ARGS((typval_T *argvars, typval_T *rettv)); 605 static void f_synID __ARGS((typval_T *argvars, typval_T *rettv)); 606 static void f_synIDattr __ARGS((typval_T *argvars, typval_T *rettv)); 607 static void f_synIDtrans __ARGS((typval_T *argvars, typval_T *rettv)); 608 static void f_system __ARGS((typval_T *argvars, typval_T *rettv)); 609 static void f_taglist __ARGS((typval_T *argvars, typval_T *rettv)); 610 static void f_tempname __ARGS((typval_T *argvars, typval_T *rettv)); 611 static void f_tolower __ARGS((typval_T *argvars, typval_T *rettv)); 612 static void f_toupper __ARGS((typval_T *argvars, typval_T *rettv)); 613 static void f_tr __ARGS((typval_T *argvars, typval_T *rettv)); 614 static void f_type __ARGS((typval_T *argvars, typval_T *rettv)); 615 static void f_values __ARGS((typval_T *argvars, typval_T *rettv)); 616 static void f_virtcol __ARGS((typval_T *argvars, typval_T *rettv)); 617 static void f_visualmode __ARGS((typval_T *argvars, typval_T *rettv)); 618 static void f_winbufnr __ARGS((typval_T *argvars, typval_T *rettv)); 619 static void f_wincol __ARGS((typval_T *argvars, typval_T *rettv)); 620 static void f_winheight __ARGS((typval_T *argvars, typval_T *rettv)); 621 static void f_winline __ARGS((typval_T *argvars, typval_T *rettv)); 622 static void f_winnr __ARGS((typval_T *argvars, typval_T *rettv)); 623 static void f_winrestcmd __ARGS((typval_T *argvars, typval_T *rettv)); 624 static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); 625 static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); 626 627 static pos_T *var2fpos __ARGS((typval_T *varp, int lnum)); 628 static int get_env_len __ARGS((char_u **arg)); 629 static int get_id_len __ARGS((char_u **arg)); 630 static int get_name_len __ARGS((char_u **arg, char_u **alias, int evaluate, int verbose)); 631 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end, int flags)); 632 #define FNE_INCL_BR 1 /* find_name_end(): include [] in name */ 633 #define FNE_CHECK_START 2 /* find_name_end(): check name starts with 634 valid character */ 635 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 636 static int eval_isnamec __ARGS((int c)); 637 static int eval_isnamec1 __ARGS((int c)); 638 static int get_var_tv __ARGS((char_u *name, int len, typval_T *rettv, int verbose)); 639 static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate, int verbose)); 640 static typval_T *alloc_tv __ARGS((void)); 641 static typval_T *alloc_string_tv __ARGS((char_u *string)); 642 static void free_tv __ARGS((typval_T *varp)); 643 static void init_tv __ARGS((typval_T *varp)); 644 static long get_tv_number __ARGS((typval_T *varp)); 645 static linenr_T get_tv_lnum __ARGS((typval_T *argvars)); 646 static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf)); 647 static char_u *get_tv_string __ARGS((typval_T *varp)); 648 static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf)); 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 vimL function "func" and return the result as a string. 1409 * Returns NULL when calling the function fails. 1410 * Uses argv[argc] for the function arguments. 1411 */ 1412 void * 1413 call_func_retstr(func, argc, argv, safe) 1414 char_u *func; 1415 int argc; 1416 char_u **argv; 1417 int safe; /* use the sandbox */ 1418 { 1419 typval_T rettv; 1420 char_u *retval; 1421 1422 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1423 return NULL; 1424 1425 retval = vim_strsave(get_tv_string(&rettv)); 1426 clear_tv(&rettv); 1427 return retval; 1428 } 1429 1430 #if defined(FEAT_COMPL_FUNC) || defined(PROTO) 1431 /* 1432 * Call vimL function "func" and return the result as a number. 1433 * Returns -1 when calling the function fails. 1434 * Uses argv[argc] for the function arguments. 1435 */ 1436 long 1437 call_func_retnr(func, argc, argv, safe) 1438 char_u *func; 1439 int argc; 1440 char_u **argv; 1441 int safe; /* use the sandbox */ 1442 { 1443 typval_T rettv; 1444 long retval; 1445 1446 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1447 return -1; 1448 1449 retval = get_tv_number_chk(&rettv, NULL); 1450 clear_tv(&rettv); 1451 return retval; 1452 } 1453 #endif 1454 1455 /* 1456 * Call vimL function "func" and return the result as a list 1457 * Uses argv[argc] for the function arguments. 1458 */ 1459 void * 1460 call_func_retlist(func, argc, argv, safe) 1461 char_u *func; 1462 int argc; 1463 char_u **argv; 1464 int safe; /* use the sandbox */ 1465 { 1466 typval_T rettv; 1467 1468 if (call_vim_function(func, argc, argv, safe, &rettv) == FAIL) 1469 return NULL; 1470 1471 if (rettv.v_type != VAR_LIST) 1472 { 1473 clear_tv(&rettv); 1474 return NULL; 1475 } 1476 1477 return rettv.vval.v_list; 1478 } 1479 1480 #endif 1481 1482 /* 1483 * Save the current function call pointer, and set it to NULL. 1484 * Used when executing autocommands and for ":source". 1485 */ 1486 void * 1487 save_funccal() 1488 { 1489 funccall_T *fc = current_funccal; 1490 1491 current_funccal = NULL; 1492 return (void *)fc; 1493 } 1494 1495 void 1496 restore_funccal(vfc) 1497 void *vfc; 1498 { 1499 funccall_T *fc = (funccall_T *)vfc; 1500 1501 current_funccal = fc; 1502 } 1503 1504 #if defined(FEAT_PROFILE) || defined(PROTO) 1505 /* 1506 * Prepare profiling for entering a child or something else that is not 1507 * counted for the script/function itself. 1508 * Should always be called in pair with prof_child_exit(). 1509 */ 1510 void 1511 prof_child_enter(tm) 1512 proftime_T *tm; /* place to store waittime */ 1513 { 1514 funccall_T *fc = current_funccal; 1515 1516 if (fc != NULL && fc->func->uf_profiling) 1517 profile_start(&fc->prof_child); 1518 script_prof_save(tm); 1519 } 1520 1521 /* 1522 * Take care of time spent in a child. 1523 * Should always be called after prof_child_enter(). 1524 */ 1525 void 1526 prof_child_exit(tm) 1527 proftime_T *tm; /* where waittime was stored */ 1528 { 1529 funccall_T *fc = current_funccal; 1530 1531 if (fc != NULL && fc->func->uf_profiling) 1532 { 1533 profile_end(&fc->prof_child); 1534 profile_sub_wait(tm, &fc->prof_child); /* don't count waiting time */ 1535 profile_add(&fc->func->uf_tm_children, &fc->prof_child); 1536 profile_add(&fc->func->uf_tml_children, &fc->prof_child); 1537 } 1538 script_prof_restore(tm); 1539 } 1540 #endif 1541 1542 1543 #ifdef FEAT_FOLDING 1544 /* 1545 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 1546 * it in "*cp". Doesn't give error messages. 1547 */ 1548 int 1549 eval_foldexpr(arg, cp) 1550 char_u *arg; 1551 int *cp; 1552 { 1553 typval_T tv; 1554 int retval; 1555 char_u *s; 1556 1557 ++emsg_off; 1558 ++sandbox; 1559 *cp = NUL; 1560 if (eval0(arg, &tv, NULL, TRUE) == FAIL) 1561 retval = 0; 1562 else 1563 { 1564 /* If the result is a number, just return the number. */ 1565 if (tv.v_type == VAR_NUMBER) 1566 retval = tv.vval.v_number; 1567 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) 1568 retval = 0; 1569 else 1570 { 1571 /* If the result is a string, check if there is a non-digit before 1572 * the number. */ 1573 s = tv.vval.v_string; 1574 if (!VIM_ISDIGIT(*s) && *s != '-') 1575 *cp = *s++; 1576 retval = atol((char *)s); 1577 } 1578 clear_tv(&tv); 1579 } 1580 --emsg_off; 1581 --sandbox; 1582 1583 return retval; 1584 } 1585 #endif 1586 1587 /* 1588 * ":let" list all variable values 1589 * ":let var1 var2" list variable values 1590 * ":let var = expr" assignment command. 1591 * ":let var += expr" assignment command. 1592 * ":let var -= expr" assignment command. 1593 * ":let var .= expr" assignment command. 1594 * ":let [var1, var2] = expr" unpack list. 1595 */ 1596 void 1597 ex_let(eap) 1598 exarg_T *eap; 1599 { 1600 char_u *arg = eap->arg; 1601 char_u *expr = NULL; 1602 typval_T rettv; 1603 int i; 1604 int var_count = 0; 1605 int semicolon = 0; 1606 char_u op[2]; 1607 1608 expr = skip_var_list(arg, &var_count, &semicolon); 1609 if (expr == NULL) 1610 return; 1611 expr = vim_strchr(expr, '='); 1612 if (expr == NULL) 1613 { 1614 /* 1615 * ":let" without "=": list variables 1616 */ 1617 if (*arg == '[') 1618 EMSG(_(e_invarg)); 1619 else if (!ends_excmd(*arg)) 1620 /* ":let var1 var2" */ 1621 arg = list_arg_vars(eap, arg); 1622 else if (!eap->skip) 1623 { 1624 /* ":let" */ 1625 list_glob_vars(); 1626 list_buf_vars(); 1627 list_win_vars(); 1628 list_vim_vars(); 1629 } 1630 eap->nextcmd = check_nextcmd(arg); 1631 } 1632 else 1633 { 1634 op[0] = '='; 1635 op[1] = NUL; 1636 if (expr > arg) 1637 { 1638 if (vim_strchr((char_u *)"+-.", expr[-1]) != NULL) 1639 op[0] = expr[-1]; /* +=, -= or .= */ 1640 } 1641 expr = skipwhite(expr + 1); 1642 1643 if (eap->skip) 1644 ++emsg_skip; 1645 i = eval0(expr, &rettv, &eap->nextcmd, !eap->skip); 1646 if (eap->skip) 1647 { 1648 if (i != FAIL) 1649 clear_tv(&rettv); 1650 --emsg_skip; 1651 } 1652 else if (i != FAIL) 1653 { 1654 (void)ex_let_vars(eap->arg, &rettv, FALSE, semicolon, var_count, 1655 op); 1656 clear_tv(&rettv); 1657 } 1658 } 1659 } 1660 1661 /* 1662 * Assign the typevalue "tv" to the variable or variables at "arg_start". 1663 * Handles both "var" with any type and "[var, var; var]" with a list type. 1664 * When "nextchars" is not NULL it points to a string with characters that 1665 * must appear after the variable(s). Use "+", "-" or "." for add, subtract 1666 * or concatenate. 1667 * Returns OK or FAIL; 1668 */ 1669 static int 1670 ex_let_vars(arg_start, tv, copy, semicolon, var_count, nextchars) 1671 char_u *arg_start; 1672 typval_T *tv; 1673 int copy; /* copy values from "tv", don't move */ 1674 int semicolon; /* from skip_var_list() */ 1675 int var_count; /* from skip_var_list() */ 1676 char_u *nextchars; 1677 { 1678 char_u *arg = arg_start; 1679 list_T *l; 1680 int i; 1681 listitem_T *item; 1682 typval_T ltv; 1683 1684 if (*arg != '[') 1685 { 1686 /* 1687 * ":let var = expr" or ":for var in list" 1688 */ 1689 if (ex_let_one(arg, tv, copy, nextchars, nextchars) == NULL) 1690 return FAIL; 1691 return OK; 1692 } 1693 1694 /* 1695 * ":let [v1, v2] = list" or ":for [v1, v2] in listlist" 1696 */ 1697 if (tv->v_type != VAR_LIST || (l = tv->vval.v_list) == NULL) 1698 { 1699 EMSG(_(e_listreq)); 1700 return FAIL; 1701 } 1702 1703 i = list_len(l); 1704 if (semicolon == 0 && var_count < i) 1705 { 1706 EMSG(_("E687: Less targets than List items")); 1707 return FAIL; 1708 } 1709 if (var_count - semicolon > i) 1710 { 1711 EMSG(_("E688: More targets than List items")); 1712 return FAIL; 1713 } 1714 1715 item = l->lv_first; 1716 while (*arg != ']') 1717 { 1718 arg = skipwhite(arg + 1); 1719 arg = ex_let_one(arg, &item->li_tv, TRUE, (char_u *)",;]", nextchars); 1720 item = item->li_next; 1721 if (arg == NULL) 1722 return FAIL; 1723 1724 arg = skipwhite(arg); 1725 if (*arg == ';') 1726 { 1727 /* Put the rest of the list (may be empty) in the var after ';'. 1728 * Create a new list for this. */ 1729 l = list_alloc(); 1730 if (l == NULL) 1731 return FAIL; 1732 while (item != NULL) 1733 { 1734 list_append_tv(l, &item->li_tv); 1735 item = item->li_next; 1736 } 1737 1738 ltv.v_type = VAR_LIST; 1739 ltv.v_lock = 0; 1740 ltv.vval.v_list = l; 1741 l->lv_refcount = 1; 1742 1743 arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, 1744 (char_u *)"]", nextchars); 1745 clear_tv(<v); 1746 if (arg == NULL) 1747 return FAIL; 1748 break; 1749 } 1750 else if (*arg != ',' && *arg != ']') 1751 { 1752 EMSG2(_(e_intern2), "ex_let_vars()"); 1753 return FAIL; 1754 } 1755 } 1756 1757 return OK; 1758 } 1759 1760 /* 1761 * Skip over assignable variable "var" or list of variables "[var, var]". 1762 * Used for ":let varvar = expr" and ":for varvar in expr". 1763 * For "[var, var]" increment "*var_count" for each variable. 1764 * for "[var, var; var]" set "semicolon". 1765 * Return NULL for an error. 1766 */ 1767 static char_u * 1768 skip_var_list(arg, var_count, semicolon) 1769 char_u *arg; 1770 int *var_count; 1771 int *semicolon; 1772 { 1773 char_u *p, *s; 1774 1775 if (*arg == '[') 1776 { 1777 /* "[var, var]": find the matching ']'. */ 1778 p = arg; 1779 for (;;) 1780 { 1781 p = skipwhite(p + 1); /* skip whites after '[', ';' or ',' */ 1782 s = skip_var_one(p); 1783 if (s == p) 1784 { 1785 EMSG2(_(e_invarg2), p); 1786 return NULL; 1787 } 1788 ++*var_count; 1789 1790 p = skipwhite(s); 1791 if (*p == ']') 1792 break; 1793 else if (*p == ';') 1794 { 1795 if (*semicolon == 1) 1796 { 1797 EMSG(_("Double ; in list of variables")); 1798 return NULL; 1799 } 1800 *semicolon = 1; 1801 } 1802 else if (*p != ',') 1803 { 1804 EMSG2(_(e_invarg2), p); 1805 return NULL; 1806 } 1807 } 1808 return p + 1; 1809 } 1810 else 1811 return skip_var_one(arg); 1812 } 1813 1814 /* 1815 * Skip one (assignable) variable name, includig @r, $VAR, &option, d.key, 1816 * l[idx]. 1817 */ 1818 static char_u * 1819 skip_var_one(arg) 1820 char_u *arg; 1821 { 1822 if (*arg == '@' && arg[1] != NUL) 1823 return arg + 2; 1824 return find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg, 1825 NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1826 } 1827 1828 /* 1829 * List variables for hashtab "ht" with prefix "prefix". 1830 * If "empty" is TRUE also list NULL strings as empty strings. 1831 */ 1832 static void 1833 list_hashtable_vars(ht, prefix, empty) 1834 hashtab_T *ht; 1835 char_u *prefix; 1836 int empty; 1837 { 1838 hashitem_T *hi; 1839 dictitem_T *di; 1840 int todo; 1841 1842 todo = ht->ht_used; 1843 for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) 1844 { 1845 if (!HASHITEM_EMPTY(hi)) 1846 { 1847 --todo; 1848 di = HI2DI(hi); 1849 if (empty || di->di_tv.v_type != VAR_STRING 1850 || di->di_tv.vval.v_string != NULL) 1851 list_one_var(di, prefix); 1852 } 1853 } 1854 } 1855 1856 /* 1857 * List global variables. 1858 */ 1859 static void 1860 list_glob_vars() 1861 { 1862 list_hashtable_vars(&globvarht, (char_u *)"", TRUE); 1863 } 1864 1865 /* 1866 * List buffer variables. 1867 */ 1868 static void 1869 list_buf_vars() 1870 { 1871 char_u numbuf[NUMBUFLEN]; 1872 1873 list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:", TRUE); 1874 1875 sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick); 1876 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, numbuf); 1877 } 1878 1879 /* 1880 * List window variables. 1881 */ 1882 static void 1883 list_win_vars() 1884 { 1885 list_hashtable_vars(&curwin->w_vars.dv_hashtab, (char_u *)"w:", TRUE); 1886 } 1887 1888 /* 1889 * List Vim variables. 1890 */ 1891 static void 1892 list_vim_vars() 1893 { 1894 list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE); 1895 } 1896 1897 /* 1898 * List variables in "arg". 1899 */ 1900 static char_u * 1901 list_arg_vars(eap, arg) 1902 exarg_T *eap; 1903 char_u *arg; 1904 { 1905 int error = FALSE; 1906 int len; 1907 char_u *name; 1908 char_u *name_start; 1909 char_u *arg_subsc; 1910 char_u *tofree; 1911 typval_T tv; 1912 1913 while (!ends_excmd(*arg) && !got_int) 1914 { 1915 if (error || eap->skip) 1916 { 1917 arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); 1918 if (!vim_iswhite(*arg) && !ends_excmd(*arg)) 1919 { 1920 emsg_severe = TRUE; 1921 EMSG(_(e_trailing)); 1922 break; 1923 } 1924 } 1925 else 1926 { 1927 /* get_name_len() takes care of expanding curly braces */ 1928 name_start = name = arg; 1929 len = get_name_len(&arg, &tofree, TRUE, TRUE); 1930 if (len <= 0) 1931 { 1932 /* This is mainly to keep test 49 working: when expanding 1933 * curly braces fails overrule the exception error message. */ 1934 if (len < 0 && !aborting()) 1935 { 1936 emsg_severe = TRUE; 1937 EMSG2(_(e_invarg2), arg); 1938 break; 1939 } 1940 error = TRUE; 1941 } 1942 else 1943 { 1944 if (tofree != NULL) 1945 name = tofree; 1946 if (get_var_tv(name, len, &tv, TRUE) == FAIL) 1947 error = TRUE; 1948 else 1949 { 1950 /* handle d.key, l[idx], f(expr) */ 1951 arg_subsc = arg; 1952 if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) 1953 error = TRUE; 1954 else 1955 { 1956 if (arg == arg_subsc && len == 2 && name[1] == ':') 1957 { 1958 switch (*name) 1959 { 1960 case 'g': list_glob_vars(); break; 1961 case 'b': list_buf_vars(); break; 1962 case 'w': list_win_vars(); break; 1963 case 'v': list_vim_vars(); break; 1964 default: 1965 EMSG2(_("E738: Can't list variables for %s"), name); 1966 } 1967 } 1968 else 1969 { 1970 char_u numbuf[NUMBUFLEN]; 1971 char_u *tf; 1972 int c; 1973 char_u *s; 1974 1975 s = echo_string(&tv, &tf, numbuf); 1976 c = *arg; 1977 *arg = NUL; 1978 list_one_var_a((char_u *)"", 1979 arg == arg_subsc ? name : name_start, 1980 tv.v_type, s == NULL ? (char_u *)"" : s); 1981 *arg = c; 1982 vim_free(tf); 1983 } 1984 clear_tv(&tv); 1985 } 1986 } 1987 } 1988 1989 vim_free(tofree); 1990 } 1991 1992 arg = skipwhite(arg); 1993 } 1994 1995 return arg; 1996 } 1997 1998 /* 1999 * Set one item of ":let var = expr" or ":let [v1, v2] = list" to its value. 2000 * Returns a pointer to the char just after the var name. 2001 * Returns NULL if there is an error. 2002 */ 2003 static char_u * 2004 ex_let_one(arg, tv, copy, endchars, op) 2005 char_u *arg; /* points to variable name */ 2006 typval_T *tv; /* value to assign to variable */ 2007 int copy; /* copy value from "tv" */ 2008 char_u *endchars; /* valid chars after variable name or NULL */ 2009 char_u *op; /* "+", "-", "." or NULL*/ 2010 { 2011 int c1; 2012 char_u *name; 2013 char_u *p; 2014 char_u *arg_end = NULL; 2015 int len; 2016 int opt_flags; 2017 char_u *tofree = NULL; 2018 2019 /* 2020 * ":let $VAR = expr": Set environment variable. 2021 */ 2022 if (*arg == '$') 2023 { 2024 /* Find the end of the name. */ 2025 ++arg; 2026 name = arg; 2027 len = get_env_len(&arg); 2028 if (len == 0) 2029 EMSG2(_(e_invarg2), name - 1); 2030 else 2031 { 2032 if (op != NULL && (*op == '+' || *op == '-')) 2033 EMSG2(_(e_letwrong), op); 2034 else if (endchars != NULL 2035 && vim_strchr(endchars, *skipwhite(arg)) == NULL) 2036 EMSG(_(e_letunexp)); 2037 else 2038 { 2039 c1 = name[len]; 2040 name[len] = NUL; 2041 p = get_tv_string_chk(tv); 2042 if (p != NULL && op != NULL && *op == '.') 2043 { 2044 int mustfree = FALSE; 2045 char_u *s = vim_getenv(name, &mustfree); 2046 2047 if (s != NULL) 2048 { 2049 p = tofree = concat_str(s, p); 2050 if (mustfree) 2051 vim_free(s); 2052 } 2053 } 2054 if (p != NULL) 2055 { 2056 vim_setenv(name, p); 2057 if (STRICMP(name, "HOME") == 0) 2058 init_homedir(); 2059 else if (didset_vim && STRICMP(name, "VIM") == 0) 2060 didset_vim = FALSE; 2061 else if (didset_vimruntime 2062 && STRICMP(name, "VIMRUNTIME") == 0) 2063 didset_vimruntime = FALSE; 2064 arg_end = arg; 2065 } 2066 name[len] = c1; 2067 vim_free(tofree); 2068 } 2069 } 2070 } 2071 2072 /* 2073 * ":let &option = expr": Set option value. 2074 * ":let &l:option = expr": Set local option value. 2075 * ":let &g:option = expr": Set global option value. 2076 */ 2077 else if (*arg == '&') 2078 { 2079 /* Find the end of the name. */ 2080 p = find_option_end(&arg, &opt_flags); 2081 if (p == NULL || (endchars != NULL 2082 && vim_strchr(endchars, *skipwhite(p)) == NULL)) 2083 EMSG(_(e_letunexp)); 2084 else 2085 { 2086 long n; 2087 int opt_type; 2088 long numval; 2089 char_u *stringval = NULL; 2090 char_u *s; 2091 2092 c1 = *p; 2093 *p = NUL; 2094 2095 n = get_tv_number(tv); 2096 s = get_tv_string_chk(tv); /* != NULL if number or string */ 2097 if (s != NULL && op != NULL && *op != '=') 2098 { 2099 opt_type = get_option_value(arg, &numval, 2100 &stringval, opt_flags); 2101 if ((opt_type == 1 && *op == '.') 2102 || (opt_type == 0 && *op != '.')) 2103 EMSG2(_(e_letwrong), op); 2104 else 2105 { 2106 if (opt_type == 1) /* number */ 2107 { 2108 if (*op == '+') 2109 n = numval + n; 2110 else 2111 n = numval - n; 2112 } 2113 else if (opt_type == 0 && stringval != NULL) /* string */ 2114 { 2115 s = concat_str(stringval, s); 2116 vim_free(stringval); 2117 stringval = s; 2118 } 2119 } 2120 } 2121 if (s != NULL) 2122 { 2123 set_option_value(arg, n, s, opt_flags); 2124 arg_end = p; 2125 } 2126 *p = c1; 2127 vim_free(stringval); 2128 } 2129 } 2130 2131 /* 2132 * ":let @r = expr": Set register contents. 2133 */ 2134 else if (*arg == '@') 2135 { 2136 ++arg; 2137 if (op != NULL && (*op == '+' || *op == '-')) 2138 EMSG2(_(e_letwrong), op); 2139 else if (endchars != NULL 2140 && vim_strchr(endchars, *skipwhite(arg + 1)) == NULL) 2141 EMSG(_(e_letunexp)); 2142 else 2143 { 2144 char_u *tofree = NULL; 2145 char_u *s; 2146 2147 p = get_tv_string_chk(tv); 2148 if (p != NULL && op != NULL && *op == '.') 2149 { 2150 s = get_reg_contents(*arg == '@' ? '"' : *arg, TRUE, TRUE); 2151 if (s != NULL) 2152 { 2153 p = tofree = concat_str(s, p); 2154 vim_free(s); 2155 } 2156 } 2157 if (p != NULL) 2158 { 2159 write_reg_contents(*arg == '@' ? '"' : *arg, p, -1, FALSE); 2160 arg_end = arg + 1; 2161 } 2162 vim_free(tofree); 2163 } 2164 } 2165 2166 /* 2167 * ":let var = expr": Set internal variable. 2168 * ":let {expr} = expr": Idem, name made with curly braces 2169 */ 2170 else if (eval_isnamec1(*arg) || *arg == '{') 2171 { 2172 lval_T lv; 2173 2174 p = get_lval(arg, tv, &lv, FALSE, FALSE, FALSE, FNE_CHECK_START); 2175 if (p != NULL && lv.ll_name != NULL) 2176 { 2177 if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) 2178 EMSG(_(e_letunexp)); 2179 else 2180 { 2181 set_var_lval(&lv, p, tv, copy, op); 2182 arg_end = p; 2183 } 2184 } 2185 clear_lval(&lv); 2186 } 2187 2188 else 2189 EMSG2(_(e_invarg2), arg); 2190 2191 return arg_end; 2192 } 2193 2194 /* 2195 * If "arg" is equal to "b:changedtick" give an error and return TRUE. 2196 */ 2197 static int 2198 check_changedtick(arg) 2199 char_u *arg; 2200 { 2201 if (STRNCMP(arg, "b:changedtick", 13) == 0 && !eval_isnamec(arg[13])) 2202 { 2203 EMSG2(_(e_readonlyvar), arg); 2204 return TRUE; 2205 } 2206 return FALSE; 2207 } 2208 2209 /* 2210 * Get an lval: variable, Dict item or List item that can be assigned a value 2211 * to: "name", "na{me}", "name[expr]", "name[expr:expr]", "name[expr][expr]", 2212 * "name.key", "name.key[expr]" etc. 2213 * Indexing only works if "name" is an existing List or Dictionary. 2214 * "name" points to the start of the name. 2215 * If "rettv" is not NULL it points to the value to be assigned. 2216 * "unlet" is TRUE for ":unlet": slightly different behavior when something is 2217 * wrong; must end in space or cmd separator. 2218 * 2219 * Returns a pointer to just after the name, including indexes. 2220 * When an evaluation error occurs "lp->ll_name" is NULL; 2221 * Returns NULL for a parsing error. Still need to free items in "lp"! 2222 */ 2223 static char_u * 2224 get_lval(name, rettv, lp, unlet, skip, quiet, fne_flags) 2225 char_u *name; 2226 typval_T *rettv; 2227 lval_T *lp; 2228 int unlet; 2229 int skip; 2230 int quiet; /* don't give error messages */ 2231 int fne_flags; /* flags for find_name_end() */ 2232 { 2233 char_u *p; 2234 char_u *expr_start, *expr_end; 2235 int cc; 2236 dictitem_T *v; 2237 typval_T var1; 2238 typval_T var2; 2239 int empty1 = FALSE; 2240 listitem_T *ni; 2241 char_u *key = NULL; 2242 int len; 2243 hashtab_T *ht; 2244 2245 /* Clear everything in "lp". */ 2246 vim_memset(lp, 0, sizeof(lval_T)); 2247 2248 if (skip) 2249 { 2250 /* When skipping just find the end of the name. */ 2251 lp->ll_name = name; 2252 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); 2253 } 2254 2255 /* Find the end of the name. */ 2256 p = find_name_end(name, &expr_start, &expr_end, fne_flags); 2257 if (expr_start != NULL) 2258 { 2259 /* Don't expand the name when we already know there is an error. */ 2260 if (unlet && !vim_iswhite(*p) && !ends_excmd(*p) 2261 && *p != '[' && *p != '.') 2262 { 2263 EMSG(_(e_trailing)); 2264 return NULL; 2265 } 2266 2267 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); 2268 if (lp->ll_exp_name == NULL) 2269 { 2270 /* Report an invalid expression in braces, unless the 2271 * expression evaluation has been cancelled due to an 2272 * aborting error, an interrupt, or an exception. */ 2273 if (!aborting() && !quiet) 2274 { 2275 emsg_severe = TRUE; 2276 EMSG2(_(e_invarg2), name); 2277 return NULL; 2278 } 2279 } 2280 lp->ll_name = lp->ll_exp_name; 2281 } 2282 else 2283 lp->ll_name = name; 2284 2285 /* Without [idx] or .key we are done. */ 2286 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) 2287 return p; 2288 2289 cc = *p; 2290 *p = NUL; 2291 v = find_var(lp->ll_name, &ht); 2292 if (v == NULL && !quiet) 2293 EMSG2(_(e_undefvar), lp->ll_name); 2294 *p = cc; 2295 if (v == NULL) 2296 return NULL; 2297 2298 /* 2299 * Loop until no more [idx] or .key is following. 2300 */ 2301 lp->ll_tv = &v->di_tv; 2302 while (*p == '[' || (*p == '.' && lp->ll_tv->v_type == VAR_DICT)) 2303 { 2304 if (!(lp->ll_tv->v_type == VAR_LIST && lp->ll_tv->vval.v_list != NULL) 2305 && !(lp->ll_tv->v_type == VAR_DICT 2306 && lp->ll_tv->vval.v_dict != NULL)) 2307 { 2308 if (!quiet) 2309 EMSG(_("E689: Can only index a List or Dictionary")); 2310 return NULL; 2311 } 2312 if (lp->ll_range) 2313 { 2314 if (!quiet) 2315 EMSG(_("E708: [:] must come last")); 2316 return NULL; 2317 } 2318 2319 len = -1; 2320 if (*p == '.') 2321 { 2322 key = p + 1; 2323 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 2324 ; 2325 if (len == 0) 2326 { 2327 if (!quiet) 2328 EMSG(_(e_emptykey)); 2329 return NULL; 2330 } 2331 p = key + len; 2332 } 2333 else 2334 { 2335 /* Get the index [expr] or the first index [expr: ]. */ 2336 p = skipwhite(p + 1); 2337 if (*p == ':') 2338 empty1 = TRUE; 2339 else 2340 { 2341 empty1 = FALSE; 2342 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ 2343 return NULL; 2344 if (get_tv_string_chk(&var1) == NULL) 2345 { 2346 /* not a number or string */ 2347 clear_tv(&var1); 2348 return NULL; 2349 } 2350 } 2351 2352 /* Optionally get the second index [ :expr]. */ 2353 if (*p == ':') 2354 { 2355 if (lp->ll_tv->v_type == VAR_DICT) 2356 { 2357 if (!quiet) 2358 EMSG(_(e_dictrange)); 2359 if (!empty1) 2360 clear_tv(&var1); 2361 return NULL; 2362 } 2363 if (rettv != NULL && (rettv->v_type != VAR_LIST 2364 || rettv->vval.v_list == NULL)) 2365 { 2366 if (!quiet) 2367 EMSG(_("E709: [:] requires a List value")); 2368 if (!empty1) 2369 clear_tv(&var1); 2370 return NULL; 2371 } 2372 p = skipwhite(p + 1); 2373 if (*p == ']') 2374 lp->ll_empty2 = TRUE; 2375 else 2376 { 2377 lp->ll_empty2 = FALSE; 2378 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ 2379 { 2380 if (!empty1) 2381 clear_tv(&var1); 2382 return NULL; 2383 } 2384 if (get_tv_string_chk(&var2) == NULL) 2385 { 2386 /* not a number or string */ 2387 if (!empty1) 2388 clear_tv(&var1); 2389 clear_tv(&var2); 2390 return NULL; 2391 } 2392 } 2393 lp->ll_range = TRUE; 2394 } 2395 else 2396 lp->ll_range = FALSE; 2397 2398 if (*p != ']') 2399 { 2400 if (!quiet) 2401 EMSG(_(e_missbrac)); 2402 if (!empty1) 2403 clear_tv(&var1); 2404 if (lp->ll_range && !lp->ll_empty2) 2405 clear_tv(&var2); 2406 return NULL; 2407 } 2408 2409 /* Skip to past ']'. */ 2410 ++p; 2411 } 2412 2413 if (lp->ll_tv->v_type == VAR_DICT) 2414 { 2415 if (len == -1) 2416 { 2417 /* "[key]": get key from "var1" */ 2418 key = get_tv_string(&var1); /* is number or string */ 2419 if (*key == NUL) 2420 { 2421 if (!quiet) 2422 EMSG(_(e_emptykey)); 2423 clear_tv(&var1); 2424 return NULL; 2425 } 2426 } 2427 lp->ll_list = NULL; 2428 lp->ll_dict = lp->ll_tv->vval.v_dict; 2429 lp->ll_di = dict_find(lp->ll_dict, key, len); 2430 if (lp->ll_di == NULL) 2431 { 2432 /* Key does not exist in dict: may need to add it. */ 2433 if (*p == '[' || *p == '.' || unlet) 2434 { 2435 if (!quiet) 2436 EMSG2(_(e_dictkey), key); 2437 if (len == -1) 2438 clear_tv(&var1); 2439 return NULL; 2440 } 2441 if (len == -1) 2442 lp->ll_newkey = vim_strsave(key); 2443 else 2444 lp->ll_newkey = vim_strnsave(key, len); 2445 if (len == -1) 2446 clear_tv(&var1); 2447 if (lp->ll_newkey == NULL) 2448 p = NULL; 2449 break; 2450 } 2451 if (len == -1) 2452 clear_tv(&var1); 2453 lp->ll_tv = &lp->ll_di->di_tv; 2454 } 2455 else 2456 { 2457 /* 2458 * Get the number and item for the only or first index of the List. 2459 */ 2460 if (empty1) 2461 lp->ll_n1 = 0; 2462 else 2463 { 2464 lp->ll_n1 = get_tv_number(&var1); /* is number or string */ 2465 clear_tv(&var1); 2466 } 2467 lp->ll_dict = NULL; 2468 lp->ll_list = lp->ll_tv->vval.v_list; 2469 lp->ll_li = list_find(lp->ll_list, lp->ll_n1); 2470 if (lp->ll_li == NULL) 2471 { 2472 if (!quiet) 2473 EMSGN(_(e_listidx), lp->ll_n1); 2474 if (lp->ll_range && !lp->ll_empty2) 2475 clear_tv(&var2); 2476 return NULL; 2477 } 2478 2479 /* 2480 * May need to find the item or absolute index for the second 2481 * index of a range. 2482 * When no index given: "lp->ll_empty2" is TRUE. 2483 * Otherwise "lp->ll_n2" is set to the second index. 2484 */ 2485 if (lp->ll_range && !lp->ll_empty2) 2486 { 2487 lp->ll_n2 = get_tv_number(&var2); /* is number or string */ 2488 clear_tv(&var2); 2489 if (lp->ll_n2 < 0) 2490 { 2491 ni = list_find(lp->ll_list, lp->ll_n2); 2492 if (ni == NULL) 2493 { 2494 if (!quiet) 2495 EMSGN(_(e_listidx), lp->ll_n2); 2496 return NULL; 2497 } 2498 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); 2499 } 2500 2501 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ 2502 if (lp->ll_n1 < 0) 2503 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); 2504 if (lp->ll_n2 < lp->ll_n1) 2505 { 2506 if (!quiet) 2507 EMSGN(_(e_listidx), lp->ll_n2); 2508 return NULL; 2509 } 2510 } 2511 2512 lp->ll_tv = &lp->ll_li->li_tv; 2513 } 2514 } 2515 2516 return p; 2517 } 2518 2519 /* 2520 * Clear lval "lp" that was filled by get_lval(). 2521 */ 2522 static void 2523 clear_lval(lp) 2524 lval_T *lp; 2525 { 2526 vim_free(lp->ll_exp_name); 2527 vim_free(lp->ll_newkey); 2528 } 2529 2530 /* 2531 * Set a variable that was parsed by get_lval() to "rettv". 2532 * "endp" points to just after the parsed name. 2533 * "op" is NULL, "+" for "+=", "-" for "-=", "." for ".=" or "=" for "=". 2534 */ 2535 static void 2536 set_var_lval(lp, endp, rettv, copy, op) 2537 lval_T *lp; 2538 char_u *endp; 2539 typval_T *rettv; 2540 int copy; 2541 char_u *op; 2542 { 2543 int cc; 2544 listitem_T *ni; 2545 listitem_T *ri; 2546 dictitem_T *di; 2547 2548 if (lp->ll_tv == NULL) 2549 { 2550 if (!check_changedtick(lp->ll_name)) 2551 { 2552 cc = *endp; 2553 *endp = NUL; 2554 if (op != NULL && *op != '=') 2555 { 2556 typval_T tv; 2557 2558 /* handle +=, -= and .= */ 2559 if (get_var_tv(lp->ll_name, STRLEN(lp->ll_name), 2560 &tv, TRUE) == OK) 2561 { 2562 if (tv_op(&tv, rettv, op) == OK) 2563 set_var(lp->ll_name, &tv, FALSE); 2564 clear_tv(&tv); 2565 } 2566 } 2567 else 2568 set_var(lp->ll_name, rettv, copy); 2569 *endp = cc; 2570 } 2571 } 2572 else if (tv_check_lock(lp->ll_newkey == NULL 2573 ? lp->ll_tv->v_lock 2574 : lp->ll_tv->vval.v_dict->dv_lock, lp->ll_name)) 2575 ; 2576 else if (lp->ll_range) 2577 { 2578 /* 2579 * Assign the List values to the list items. 2580 */ 2581 for (ri = rettv->vval.v_list->lv_first; ri != NULL; ) 2582 { 2583 if (op != NULL && *op != '=') 2584 tv_op(&lp->ll_li->li_tv, &ri->li_tv, op); 2585 else 2586 { 2587 clear_tv(&lp->ll_li->li_tv); 2588 copy_tv(&ri->li_tv, &lp->ll_li->li_tv); 2589 } 2590 ri = ri->li_next; 2591 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) 2592 break; 2593 if (lp->ll_li->li_next == NULL) 2594 { 2595 /* Need to add an empty item. */ 2596 ni = listitem_alloc(); 2597 if (ni == NULL) 2598 { 2599 ri = NULL; 2600 break; 2601 } 2602 ni->li_tv.v_type = VAR_NUMBER; 2603 ni->li_tv.v_lock = 0; 2604 ni->li_tv.vval.v_number = 0; 2605 list_append(lp->ll_list, ni); 2606 } 2607 lp->ll_li = lp->ll_li->li_next; 2608 ++lp->ll_n1; 2609 } 2610 if (ri != NULL) 2611 EMSG(_("E710: List value has more items than target")); 2612 else if (lp->ll_empty2 2613 ? (lp->ll_li != NULL && lp->ll_li->li_next != NULL) 2614 : lp->ll_n1 != lp->ll_n2) 2615 EMSG(_("E711: List value has not enough items")); 2616 } 2617 else 2618 { 2619 /* 2620 * Assign to a List or Dictionary item. 2621 */ 2622 if (lp->ll_newkey != NULL) 2623 { 2624 if (op != NULL && *op != '=') 2625 { 2626 EMSG2(_(e_letwrong), op); 2627 return; 2628 } 2629 2630 /* Need to add an item to the Dictionary. */ 2631 di = dictitem_alloc(lp->ll_newkey); 2632 if (di == NULL) 2633 return; 2634 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) 2635 { 2636 vim_free(di); 2637 return; 2638 } 2639 lp->ll_tv = &di->di_tv; 2640 } 2641 else if (op != NULL && *op != '=') 2642 { 2643 tv_op(lp->ll_tv, rettv, op); 2644 return; 2645 } 2646 else 2647 clear_tv(lp->ll_tv); 2648 2649 /* 2650 * Assign the value to the variable or list item. 2651 */ 2652 if (copy) 2653 copy_tv(rettv, lp->ll_tv); 2654 else 2655 { 2656 *lp->ll_tv = *rettv; 2657 lp->ll_tv->v_lock = 0; 2658 init_tv(rettv); 2659 } 2660 } 2661 } 2662 2663 /* 2664 * Handle "tv1 += tv2", "tv1 -= tv2" and "tv1 .= tv2" 2665 * Returns OK or FAIL. 2666 */ 2667 static int 2668 tv_op(tv1, tv2, op) 2669 typval_T *tv1; 2670 typval_T *tv2; 2671 char_u *op; 2672 { 2673 long n; 2674 char_u numbuf[NUMBUFLEN]; 2675 char_u *s; 2676 2677 /* Can't do anything with a Funcref or a Dict on the right. */ 2678 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) 2679 { 2680 switch (tv1->v_type) 2681 { 2682 case VAR_DICT: 2683 case VAR_FUNC: 2684 break; 2685 2686 case VAR_LIST: 2687 if (*op != '+' || tv2->v_type != VAR_LIST) 2688 break; 2689 /* List += List */ 2690 if (tv1->vval.v_list != NULL && tv2->vval.v_list != NULL) 2691 list_extend(tv1->vval.v_list, tv2->vval.v_list, NULL); 2692 return OK; 2693 2694 case VAR_NUMBER: 2695 case VAR_STRING: 2696 if (tv2->v_type == VAR_LIST) 2697 break; 2698 if (*op == '+' || *op == '-') 2699 { 2700 /* nr += nr or nr -= nr*/ 2701 n = get_tv_number(tv1); 2702 if (*op == '+') 2703 n += get_tv_number(tv2); 2704 else 2705 n -= get_tv_number(tv2); 2706 clear_tv(tv1); 2707 tv1->v_type = VAR_NUMBER; 2708 tv1->vval.v_number = n; 2709 } 2710 else 2711 { 2712 /* str .= str */ 2713 s = get_tv_string(tv1); 2714 s = concat_str(s, get_tv_string_buf(tv2, numbuf)); 2715 clear_tv(tv1); 2716 tv1->v_type = VAR_STRING; 2717 tv1->vval.v_string = s; 2718 } 2719 return OK; 2720 } 2721 } 2722 2723 EMSG2(_(e_letwrong), op); 2724 return FAIL; 2725 } 2726 2727 /* 2728 * Add a watcher to a list. 2729 */ 2730 static void 2731 list_add_watch(l, lw) 2732 list_T *l; 2733 listwatch_T *lw; 2734 { 2735 lw->lw_next = l->lv_watch; 2736 l->lv_watch = lw; 2737 } 2738 2739 /* 2740 * Remove a watcher from a list. 2741 * No warning when it isn't found... 2742 */ 2743 static void 2744 list_rem_watch(l, lwrem) 2745 list_T *l; 2746 listwatch_T *lwrem; 2747 { 2748 listwatch_T *lw, **lwp; 2749 2750 lwp = &l->lv_watch; 2751 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2752 { 2753 if (lw == lwrem) 2754 { 2755 *lwp = lw->lw_next; 2756 break; 2757 } 2758 lwp = &lw->lw_next; 2759 } 2760 } 2761 2762 /* 2763 * Just before removing an item from a list: advance watchers to the next 2764 * item. 2765 */ 2766 static void 2767 list_fix_watch(l, item) 2768 list_T *l; 2769 listitem_T *item; 2770 { 2771 listwatch_T *lw; 2772 2773 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) 2774 if (lw->lw_item == item) 2775 lw->lw_item = item->li_next; 2776 } 2777 2778 /* 2779 * Evaluate the expression used in a ":for var in expr" command. 2780 * "arg" points to "var". 2781 * Set "*errp" to TRUE for an error, FALSE otherwise; 2782 * Return a pointer that holds the info. Null when there is an error. 2783 */ 2784 void * 2785 eval_for_line(arg, errp, nextcmdp, skip) 2786 char_u *arg; 2787 int *errp; 2788 char_u **nextcmdp; 2789 int skip; 2790 { 2791 forinfo_T *fi; 2792 char_u *expr; 2793 typval_T tv; 2794 list_T *l; 2795 2796 *errp = TRUE; /* default: there is an error */ 2797 2798 fi = (forinfo_T *)alloc_clear(sizeof(forinfo_T)); 2799 if (fi == NULL) 2800 return NULL; 2801 2802 expr = skip_var_list(arg, &fi->fi_varcount, &fi->fi_semicolon); 2803 if (expr == NULL) 2804 return fi; 2805 2806 expr = skipwhite(expr); 2807 if (expr[0] != 'i' || expr[1] != 'n' || !vim_iswhite(expr[2])) 2808 { 2809 EMSG(_("E690: Missing \"in\" after :for")); 2810 return fi; 2811 } 2812 2813 if (skip) 2814 ++emsg_skip; 2815 if (eval0(skipwhite(expr + 2), &tv, nextcmdp, !skip) == OK) 2816 { 2817 *errp = FALSE; 2818 if (!skip) 2819 { 2820 l = tv.vval.v_list; 2821 if (tv.v_type != VAR_LIST || l == NULL) 2822 { 2823 EMSG(_(e_listreq)); 2824 clear_tv(&tv); 2825 } 2826 else 2827 { 2828 fi->fi_list = l; 2829 list_add_watch(l, &fi->fi_lw); 2830 fi->fi_lw.lw_item = l->lv_first; 2831 } 2832 } 2833 } 2834 if (skip) 2835 --emsg_skip; 2836 2837 return fi; 2838 } 2839 2840 /* 2841 * Use the first item in a ":for" list. Advance to the next. 2842 * Assign the values to the variable (list). "arg" points to the first one. 2843 * Return TRUE when a valid item was found, FALSE when at end of list or 2844 * something wrong. 2845 */ 2846 int 2847 next_for_item(fi_void, arg) 2848 void *fi_void; 2849 char_u *arg; 2850 { 2851 forinfo_T *fi = (forinfo_T *)fi_void; 2852 int result; 2853 listitem_T *item; 2854 2855 item = fi->fi_lw.lw_item; 2856 if (item == NULL) 2857 result = FALSE; 2858 else 2859 { 2860 fi->fi_lw.lw_item = item->li_next; 2861 result = (ex_let_vars(arg, &item->li_tv, TRUE, 2862 fi->fi_semicolon, fi->fi_varcount, NULL) == OK); 2863 } 2864 return result; 2865 } 2866 2867 /* 2868 * Free the structure used to store info used by ":for". 2869 */ 2870 void 2871 free_for_info(fi_void) 2872 void *fi_void; 2873 { 2874 forinfo_T *fi = (forinfo_T *)fi_void; 2875 2876 if (fi != NULL && fi->fi_list != NULL) 2877 { 2878 list_rem_watch(fi->fi_list, &fi->fi_lw); 2879 list_unref(fi->fi_list); 2880 } 2881 vim_free(fi); 2882 } 2883 2884 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2885 2886 void 2887 set_context_for_expression(xp, arg, cmdidx) 2888 expand_T *xp; 2889 char_u *arg; 2890 cmdidx_T cmdidx; 2891 { 2892 int got_eq = FALSE; 2893 int c; 2894 char_u *p; 2895 2896 if (cmdidx == CMD_let) 2897 { 2898 xp->xp_context = EXPAND_USER_VARS; 2899 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) 2900 { 2901 /* ":let var1 var2 ...": find last space. */ 2902 for (p = arg + STRLEN(arg); p >= arg; ) 2903 { 2904 xp->xp_pattern = p; 2905 mb_ptr_back(arg, p); 2906 if (vim_iswhite(*p)) 2907 break; 2908 } 2909 return; 2910 } 2911 } 2912 else 2913 xp->xp_context = cmdidx == CMD_call ? EXPAND_FUNCTIONS 2914 : EXPAND_EXPRESSION; 2915 while ((xp->xp_pattern = vim_strpbrk(arg, 2916 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 2917 { 2918 c = *xp->xp_pattern; 2919 if (c == '&') 2920 { 2921 c = xp->xp_pattern[1]; 2922 if (c == '&') 2923 { 2924 ++xp->xp_pattern; 2925 xp->xp_context = cmdidx != CMD_let || got_eq 2926 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 2927 } 2928 else if (c != ' ') 2929 { 2930 xp->xp_context = EXPAND_SETTINGS; 2931 if ((c == 'l' || c == 'g') && xp->xp_pattern[2] == ':') 2932 xp->xp_pattern += 2; 2933 2934 } 2935 } 2936 else if (c == '$') 2937 { 2938 /* environment variable */ 2939 xp->xp_context = EXPAND_ENV_VARS; 2940 } 2941 else if (c == '=') 2942 { 2943 got_eq = TRUE; 2944 xp->xp_context = EXPAND_EXPRESSION; 2945 } 2946 else if (c == '<' 2947 && xp->xp_context == EXPAND_FUNCTIONS 2948 && vim_strchr(xp->xp_pattern, '(') == NULL) 2949 { 2950 /* Function name can start with "<SNR>" */ 2951 break; 2952 } 2953 else if (cmdidx != CMD_let || got_eq) 2954 { 2955 if (c == '"') /* string */ 2956 { 2957 while ((c = *++xp->xp_pattern) != NUL && c != '"') 2958 if (c == '\\' && xp->xp_pattern[1] != NUL) 2959 ++xp->xp_pattern; 2960 xp->xp_context = EXPAND_NOTHING; 2961 } 2962 else if (c == '\'') /* literal string */ 2963 { 2964 /* Trick: '' is like stopping and starting a literal string. */ 2965 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 2966 /* skip */ ; 2967 xp->xp_context = EXPAND_NOTHING; 2968 } 2969 else if (c == '|') 2970 { 2971 if (xp->xp_pattern[1] == '|') 2972 { 2973 ++xp->xp_pattern; 2974 xp->xp_context = EXPAND_EXPRESSION; 2975 } 2976 else 2977 xp->xp_context = EXPAND_COMMANDS; 2978 } 2979 else 2980 xp->xp_context = EXPAND_EXPRESSION; 2981 } 2982 else 2983 /* Doesn't look like something valid, expand as an expression 2984 * anyway. */ 2985 xp->xp_context = EXPAND_EXPRESSION; 2986 arg = xp->xp_pattern; 2987 if (*arg != NUL) 2988 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 2989 /* skip */ ; 2990 } 2991 xp->xp_pattern = arg; 2992 } 2993 2994 #endif /* FEAT_CMDL_COMPL */ 2995 2996 /* 2997 * ":1,25call func(arg1, arg2)" function call. 2998 */ 2999 void 3000 ex_call(eap) 3001 exarg_T *eap; 3002 { 3003 char_u *arg = eap->arg; 3004 char_u *startarg; 3005 char_u *name; 3006 char_u *tofree; 3007 int len; 3008 typval_T rettv; 3009 linenr_T lnum; 3010 int doesrange; 3011 int failed = FALSE; 3012 funcdict_T fudi; 3013 3014 tofree = trans_function_name(&arg, eap->skip, TFN_INT, &fudi); 3015 vim_free(fudi.fd_newkey); 3016 if (tofree == NULL) 3017 return; 3018 3019 /* Increase refcount on dictionary, it could get deleted when evaluating 3020 * the arguments. */ 3021 if (fudi.fd_dict != NULL) 3022 ++fudi.fd_dict->dv_refcount; 3023 3024 /* If it is the name of a variable of type VAR_FUNC use its contents. */ 3025 len = STRLEN(tofree); 3026 name = deref_func_name(tofree, &len); 3027 3028 /* Skip white space to allow ":call func ()". Not good, but required for 3029 * backward compatibility. */ 3030 startarg = skipwhite(arg); 3031 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 3032 3033 if (*startarg != '(') 3034 { 3035 EMSG2(_("E107: Missing braces: %s"), eap->arg); 3036 goto end; 3037 } 3038 3039 /* 3040 * When skipping, evaluate the function once, to find the end of the 3041 * arguments. 3042 * When the function takes a range, this is discovered after the first 3043 * call, and the loop is broken. 3044 */ 3045 if (eap->skip) 3046 { 3047 ++emsg_skip; 3048 lnum = eap->line2; /* do it once, also with an invalid range */ 3049 } 3050 else 3051 lnum = eap->line1; 3052 for ( ; lnum <= eap->line2; ++lnum) 3053 { 3054 if (!eap->skip && eap->addr_count > 0) 3055 { 3056 curwin->w_cursor.lnum = lnum; 3057 curwin->w_cursor.col = 0; 3058 } 3059 arg = startarg; 3060 if (get_func_tv(name, STRLEN(name), &rettv, &arg, 3061 eap->line1, eap->line2, &doesrange, 3062 !eap->skip, fudi.fd_dict) == FAIL) 3063 { 3064 failed = TRUE; 3065 break; 3066 } 3067 clear_tv(&rettv); 3068 if (doesrange || eap->skip) 3069 break; 3070 /* Stop when immediately aborting on error, or when an interrupt 3071 * occurred or an exception was thrown but not caught. 3072 * get_func_tv() returned OK, so that the check for trailing 3073 * characters below is executed. */ 3074 if (aborting()) 3075 break; 3076 } 3077 if (eap->skip) 3078 --emsg_skip; 3079 3080 if (!failed) 3081 { 3082 /* Check for trailing illegal characters and a following command. */ 3083 if (!ends_excmd(*arg)) 3084 { 3085 emsg_severe = TRUE; 3086 EMSG(_(e_trailing)); 3087 } 3088 else 3089 eap->nextcmd = check_nextcmd(arg); 3090 } 3091 3092 end: 3093 dict_unref(fudi.fd_dict); 3094 vim_free(tofree); 3095 } 3096 3097 /* 3098 * ":unlet[!] var1 ... " command. 3099 */ 3100 void 3101 ex_unlet(eap) 3102 exarg_T *eap; 3103 { 3104 ex_unletlock(eap, eap->arg, 0); 3105 } 3106 3107 /* 3108 * ":lockvar" and ":unlockvar" commands 3109 */ 3110 void 3111 ex_lockvar(eap) 3112 exarg_T *eap; 3113 { 3114 char_u *arg = eap->arg; 3115 int deep = 2; 3116 3117 if (eap->forceit) 3118 deep = -1; 3119 else if (vim_isdigit(*arg)) 3120 { 3121 deep = getdigits(&arg); 3122 arg = skipwhite(arg); 3123 } 3124 3125 ex_unletlock(eap, arg, deep); 3126 } 3127 3128 /* 3129 * ":unlet", ":lockvar" and ":unlockvar" are quite similar. 3130 */ 3131 static void 3132 ex_unletlock(eap, argstart, deep) 3133 exarg_T *eap; 3134 char_u *argstart; 3135 int deep; 3136 { 3137 char_u *arg = argstart; 3138 char_u *name_end; 3139 int error = FALSE; 3140 lval_T lv; 3141 3142 do 3143 { 3144 /* Parse the name and find the end. */ 3145 name_end = get_lval(arg, NULL, &lv, TRUE, eap->skip || error, FALSE, 3146 FNE_CHECK_START); 3147 if (lv.ll_name == NULL) 3148 error = TRUE; /* error but continue parsing */ 3149 if (name_end == NULL || (!vim_iswhite(*name_end) 3150 && !ends_excmd(*name_end))) 3151 { 3152 if (name_end != NULL) 3153 { 3154 emsg_severe = TRUE; 3155 EMSG(_(e_trailing)); 3156 } 3157 if (!(eap->skip || error)) 3158 clear_lval(&lv); 3159 break; 3160 } 3161 3162 if (!error && !eap->skip) 3163 { 3164 if (eap->cmdidx == CMD_unlet) 3165 { 3166 if (do_unlet_var(&lv, name_end, eap->forceit) == FAIL) 3167 error = TRUE; 3168 } 3169 else 3170 { 3171 if (do_lock_var(&lv, name_end, deep, 3172 eap->cmdidx == CMD_lockvar) == FAIL) 3173 error = TRUE; 3174 } 3175 } 3176 3177 if (!eap->skip) 3178 clear_lval(&lv); 3179 3180 arg = skipwhite(name_end); 3181 } while (!ends_excmd(*arg)); 3182 3183 eap->nextcmd = check_nextcmd(arg); 3184 } 3185 3186 static int 3187 do_unlet_var(lp, name_end, forceit) 3188 lval_T *lp; 3189 char_u *name_end; 3190 int forceit; 3191 { 3192 int ret = OK; 3193 int cc; 3194 3195 if (lp->ll_tv == NULL) 3196 { 3197 cc = *name_end; 3198 *name_end = NUL; 3199 3200 /* Normal name or expanded name. */ 3201 if (check_changedtick(lp->ll_name)) 3202 ret = FAIL; 3203 else if (do_unlet(lp->ll_name, forceit) == FAIL) 3204 ret = FAIL; 3205 *name_end = cc; 3206 } 3207 else if (tv_check_lock(lp->ll_tv->v_lock, lp->ll_name)) 3208 return FAIL; 3209 else if (lp->ll_range) 3210 { 3211 listitem_T *li; 3212 3213 /* Delete a range of List items. */ 3214 while (lp->ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3215 { 3216 li = lp->ll_li->li_next; 3217 listitem_remove(lp->ll_list, lp->ll_li); 3218 lp->ll_li = li; 3219 ++lp->ll_n1; 3220 } 3221 } 3222 else 3223 { 3224 if (lp->ll_list != NULL) 3225 /* unlet a List item. */ 3226 listitem_remove(lp->ll_list, lp->ll_li); 3227 else 3228 /* unlet a Dictionary item. */ 3229 dictitem_remove(lp->ll_dict, lp->ll_di); 3230 } 3231 3232 return ret; 3233 } 3234 3235 /* 3236 * "unlet" a variable. Return OK if it existed, FAIL if not. 3237 * When "forceit" is TRUE don't complain if the variable doesn't exist. 3238 */ 3239 int 3240 do_unlet(name, forceit) 3241 char_u *name; 3242 int forceit; 3243 { 3244 hashtab_T *ht; 3245 hashitem_T *hi; 3246 char_u *varname; 3247 3248 ht = find_var_ht(name, &varname); 3249 if (ht != NULL && *varname != NUL) 3250 { 3251 hi = hash_find(ht, varname); 3252 if (!HASHITEM_EMPTY(hi)) 3253 { 3254 if (var_check_ro(HI2DI(hi)->di_flags, name)) 3255 return FAIL; 3256 delete_var(ht, hi); 3257 return OK; 3258 } 3259 } 3260 if (forceit) 3261 return OK; 3262 EMSG2(_("E108: No such variable: \"%s\""), name); 3263 return FAIL; 3264 } 3265 3266 /* 3267 * Lock or unlock variable indicated by "lp". 3268 * "deep" is the levels to go (-1 for unlimited); 3269 * "lock" is TRUE for ":lockvar", FALSE for ":unlockvar". 3270 */ 3271 static int 3272 do_lock_var(lp, name_end, deep, lock) 3273 lval_T *lp; 3274 char_u *name_end; 3275 int deep; 3276 int lock; 3277 { 3278 int ret = OK; 3279 int cc; 3280 dictitem_T *di; 3281 3282 if (deep == 0) /* nothing to do */ 3283 return OK; 3284 3285 if (lp->ll_tv == NULL) 3286 { 3287 cc = *name_end; 3288 *name_end = NUL; 3289 3290 /* Normal name or expanded name. */ 3291 if (check_changedtick(lp->ll_name)) 3292 ret = FAIL; 3293 else 3294 { 3295 di = find_var(lp->ll_name, NULL); 3296 if (di == NULL) 3297 ret = FAIL; 3298 else 3299 { 3300 if (lock) 3301 di->di_flags |= DI_FLAGS_LOCK; 3302 else 3303 di->di_flags &= ~DI_FLAGS_LOCK; 3304 item_lock(&di->di_tv, deep, lock); 3305 } 3306 } 3307 *name_end = cc; 3308 } 3309 else if (lp->ll_range) 3310 { 3311 listitem_T *li = lp->ll_li; 3312 3313 /* (un)lock a range of List items. */ 3314 while (li != NULL && (lp->ll_empty2 || lp->ll_n2 >= lp->ll_n1)) 3315 { 3316 item_lock(&li->li_tv, deep, lock); 3317 li = li->li_next; 3318 ++lp->ll_n1; 3319 } 3320 } 3321 else if (lp->ll_list != NULL) 3322 /* (un)lock a List item. */ 3323 item_lock(&lp->ll_li->li_tv, deep, lock); 3324 else 3325 /* un(lock) a Dictionary item. */ 3326 item_lock(&lp->ll_di->di_tv, deep, lock); 3327 3328 return ret; 3329 } 3330 3331 /* 3332 * Lock or unlock an item. "deep" is nr of levels to go. 3333 */ 3334 static void 3335 item_lock(tv, deep, lock) 3336 typval_T *tv; 3337 int deep; 3338 int lock; 3339 { 3340 static int recurse = 0; 3341 list_T *l; 3342 listitem_T *li; 3343 dict_T *d; 3344 hashitem_T *hi; 3345 int todo; 3346 3347 if (recurse >= DICT_MAXNEST) 3348 { 3349 EMSG(_("E743: variable nested too deep for (un)lock")); 3350 return; 3351 } 3352 if (deep == 0) 3353 return; 3354 ++recurse; 3355 3356 /* lock/unlock the item itself */ 3357 if (lock) 3358 tv->v_lock |= VAR_LOCKED; 3359 else 3360 tv->v_lock &= ~VAR_LOCKED; 3361 3362 switch (tv->v_type) 3363 { 3364 case VAR_LIST: 3365 if ((l = tv->vval.v_list) != NULL) 3366 { 3367 if (lock) 3368 l->lv_lock |= VAR_LOCKED; 3369 else 3370 l->lv_lock &= ~VAR_LOCKED; 3371 if (deep < 0 || deep > 1) 3372 /* recursive: lock/unlock the items the List contains */ 3373 for (li = l->lv_first; li != NULL; li = li->li_next) 3374 item_lock(&li->li_tv, deep - 1, lock); 3375 } 3376 break; 3377 case VAR_DICT: 3378 if ((d = tv->vval.v_dict) != NULL) 3379 { 3380 if (lock) 3381 d->dv_lock |= VAR_LOCKED; 3382 else 3383 d->dv_lock &= ~VAR_LOCKED; 3384 if (deep < 0 || deep > 1) 3385 { 3386 /* recursive: lock/unlock the items the List contains */ 3387 todo = d->dv_hashtab.ht_used; 3388 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 3389 { 3390 if (!HASHITEM_EMPTY(hi)) 3391 { 3392 --todo; 3393 item_lock(&HI2DI(hi)->di_tv, deep - 1, lock); 3394 } 3395 } 3396 } 3397 } 3398 } 3399 --recurse; 3400 } 3401 3402 /* 3403 * Return TRUE if typeval "tv" is locked: Either tha value is locked itself or 3404 * it refers to a List or Dictionary that is locked. 3405 */ 3406 static int 3407 tv_islocked(tv) 3408 typval_T *tv; 3409 { 3410 return (tv->v_lock & VAR_LOCKED) 3411 || (tv->v_type == VAR_LIST 3412 && tv->vval.v_list != NULL 3413 && (tv->vval.v_list->lv_lock & VAR_LOCKED)) 3414 || (tv->v_type == VAR_DICT 3415 && tv->vval.v_dict != NULL 3416 && (tv->vval.v_dict->dv_lock & VAR_LOCKED)); 3417 } 3418 3419 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 3420 /* 3421 * Delete all "menutrans_" variables. 3422 */ 3423 void 3424 del_menutrans_vars() 3425 { 3426 hashitem_T *hi; 3427 int todo; 3428 3429 hash_lock(&globvarht); 3430 todo = globvarht.ht_used; 3431 for (hi = globvarht.ht_array; todo > 0 && !got_int; ++hi) 3432 { 3433 if (!HASHITEM_EMPTY(hi)) 3434 { 3435 --todo; 3436 if (STRNCMP(HI2DI(hi)->di_key, "menutrans_", 10) == 0) 3437 delete_var(&globvarht, hi); 3438 } 3439 } 3440 hash_unlock(&globvarht); 3441 } 3442 #endif 3443 3444 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3445 3446 /* 3447 * Local string buffer for the next two functions to store a variable name 3448 * with its prefix. Allocated in cat_prefix_varname(), freed later in 3449 * get_user_var_name(). 3450 */ 3451 3452 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 3453 3454 static char_u *varnamebuf = NULL; 3455 static int varnamebuflen = 0; 3456 3457 /* 3458 * Function to concatenate a prefix and a variable name. 3459 */ 3460 static char_u * 3461 cat_prefix_varname(prefix, name) 3462 int prefix; 3463 char_u *name; 3464 { 3465 int len; 3466 3467 len = (int)STRLEN(name) + 3; 3468 if (len > varnamebuflen) 3469 { 3470 vim_free(varnamebuf); 3471 len += 10; /* some additional space */ 3472 varnamebuf = alloc(len); 3473 if (varnamebuf == NULL) 3474 { 3475 varnamebuflen = 0; 3476 return NULL; 3477 } 3478 varnamebuflen = len; 3479 } 3480 *varnamebuf = prefix; 3481 varnamebuf[1] = ':'; 3482 STRCPY(varnamebuf + 2, name); 3483 return varnamebuf; 3484 } 3485 3486 /* 3487 * Function given to ExpandGeneric() to obtain the list of user defined 3488 * (global/buffer/window/built-in) variable names. 3489 */ 3490 /*ARGSUSED*/ 3491 char_u * 3492 get_user_var_name(xp, idx) 3493 expand_T *xp; 3494 int idx; 3495 { 3496 static long_u gdone; 3497 static long_u bdone; 3498 static long_u wdone; 3499 static int vidx; 3500 static hashitem_T *hi; 3501 hashtab_T *ht; 3502 3503 if (idx == 0) 3504 gdone = bdone = wdone = vidx = 0; 3505 3506 /* Global variables */ 3507 if (gdone < globvarht.ht_used) 3508 { 3509 if (gdone++ == 0) 3510 hi = globvarht.ht_array; 3511 else 3512 ++hi; 3513 while (HASHITEM_EMPTY(hi)) 3514 ++hi; 3515 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 3516 return cat_prefix_varname('g', hi->hi_key); 3517 return hi->hi_key; 3518 } 3519 3520 /* b: variables */ 3521 ht = &curbuf->b_vars.dv_hashtab; 3522 if (bdone < ht->ht_used) 3523 { 3524 if (bdone++ == 0) 3525 hi = ht->ht_array; 3526 else 3527 ++hi; 3528 while (HASHITEM_EMPTY(hi)) 3529 ++hi; 3530 return cat_prefix_varname('b', hi->hi_key); 3531 } 3532 if (bdone == ht->ht_used) 3533 { 3534 ++bdone; 3535 return (char_u *)"b:changedtick"; 3536 } 3537 3538 /* w: variables */ 3539 ht = &curwin->w_vars.dv_hashtab; 3540 if (wdone < ht->ht_used) 3541 { 3542 if (wdone++ == 0) 3543 hi = ht->ht_array; 3544 else 3545 ++hi; 3546 while (HASHITEM_EMPTY(hi)) 3547 ++hi; 3548 return cat_prefix_varname('w', hi->hi_key); 3549 } 3550 3551 /* v: variables */ 3552 if (vidx < VV_LEN) 3553 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].vv_name); 3554 3555 vim_free(varnamebuf); 3556 varnamebuf = NULL; 3557 varnamebuflen = 0; 3558 return NULL; 3559 } 3560 3561 #endif /* FEAT_CMDL_COMPL */ 3562 3563 /* 3564 * types for expressions. 3565 */ 3566 typedef enum 3567 { 3568 TYPE_UNKNOWN = 0 3569 , TYPE_EQUAL /* == */ 3570 , TYPE_NEQUAL /* != */ 3571 , TYPE_GREATER /* > */ 3572 , TYPE_GEQUAL /* >= */ 3573 , TYPE_SMALLER /* < */ 3574 , TYPE_SEQUAL /* <= */ 3575 , TYPE_MATCH /* =~ */ 3576 , TYPE_NOMATCH /* !~ */ 3577 } exptype_T; 3578 3579 /* 3580 * The "evaluate" argument: When FALSE, the argument is only parsed but not 3581 * executed. The function may return OK, but the rettv will be of type 3582 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 3583 */ 3584 3585 /* 3586 * Handle zero level expression. 3587 * This calls eval1() and handles error message and nextcmd. 3588 * Put the result in "rettv" when returning OK and "evaluate" is TRUE. 3589 * Return OK or FAIL. 3590 */ 3591 static int 3592 eval0(arg, rettv, nextcmd, evaluate) 3593 char_u *arg; 3594 typval_T *rettv; 3595 char_u **nextcmd; 3596 int evaluate; 3597 { 3598 int ret; 3599 char_u *p; 3600 3601 p = skipwhite(arg); 3602 ret = eval1(&p, rettv, evaluate); 3603 if (ret == FAIL || !ends_excmd(*p)) 3604 { 3605 if (ret != FAIL) 3606 clear_tv(rettv); 3607 /* 3608 * Report the invalid expression unless the expression evaluation has 3609 * been cancelled due to an aborting error, an interrupt, or an 3610 * exception. 3611 */ 3612 if (!aborting()) 3613 EMSG2(_(e_invexpr2), arg); 3614 ret = FAIL; 3615 } 3616 if (nextcmd != NULL) 3617 *nextcmd = check_nextcmd(p); 3618 3619 return ret; 3620 } 3621 3622 /* 3623 * Handle top level expression: 3624 * expr1 ? expr0 : expr0 3625 * 3626 * "arg" must point to the first non-white of the expression. 3627 * "arg" is advanced to the next non-white after the recognized expression. 3628 * 3629 * Return OK or FAIL. 3630 */ 3631 static int 3632 eval1(arg, rettv, evaluate) 3633 char_u **arg; 3634 typval_T *rettv; 3635 int evaluate; 3636 { 3637 int result; 3638 typval_T var2; 3639 3640 /* 3641 * Get the first variable. 3642 */ 3643 if (eval2(arg, rettv, evaluate) == FAIL) 3644 return FAIL; 3645 3646 if ((*arg)[0] == '?') 3647 { 3648 result = FALSE; 3649 if (evaluate) 3650 { 3651 int error = FALSE; 3652 3653 if (get_tv_number_chk(rettv, &error) != 0) 3654 result = TRUE; 3655 clear_tv(rettv); 3656 if (error) 3657 return FAIL; 3658 } 3659 3660 /* 3661 * Get the second variable. 3662 */ 3663 *arg = skipwhite(*arg + 1); 3664 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ 3665 return FAIL; 3666 3667 /* 3668 * Check for the ":". 3669 */ 3670 if ((*arg)[0] != ':') 3671 { 3672 EMSG(_("E109: Missing ':' after '?'")); 3673 if (evaluate && result) 3674 clear_tv(rettv); 3675 return FAIL; 3676 } 3677 3678 /* 3679 * Get the third variable. 3680 */ 3681 *arg = skipwhite(*arg + 1); 3682 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 3683 { 3684 if (evaluate && result) 3685 clear_tv(rettv); 3686 return FAIL; 3687 } 3688 if (evaluate && !result) 3689 *rettv = var2; 3690 } 3691 3692 return OK; 3693 } 3694 3695 /* 3696 * Handle first level expression: 3697 * expr2 || expr2 || expr2 logical OR 3698 * 3699 * "arg" must point to the first non-white of the expression. 3700 * "arg" is advanced to the next non-white after the recognized expression. 3701 * 3702 * Return OK or FAIL. 3703 */ 3704 static int 3705 eval2(arg, rettv, evaluate) 3706 char_u **arg; 3707 typval_T *rettv; 3708 int evaluate; 3709 { 3710 typval_T var2; 3711 long result; 3712 int first; 3713 int error = FALSE; 3714 3715 /* 3716 * Get the first variable. 3717 */ 3718 if (eval3(arg, rettv, evaluate) == FAIL) 3719 return FAIL; 3720 3721 /* 3722 * Repeat until there is no following "||". 3723 */ 3724 first = TRUE; 3725 result = FALSE; 3726 while ((*arg)[0] == '|' && (*arg)[1] == '|') 3727 { 3728 if (evaluate && first) 3729 { 3730 if (get_tv_number_chk(rettv, &error) != 0) 3731 result = TRUE; 3732 clear_tv(rettv); 3733 if (error) 3734 return FAIL; 3735 first = FALSE; 3736 } 3737 3738 /* 3739 * Get the second variable. 3740 */ 3741 *arg = skipwhite(*arg + 2); 3742 if (eval3(arg, &var2, evaluate && !result) == FAIL) 3743 return FAIL; 3744 3745 /* 3746 * Compute the result. 3747 */ 3748 if (evaluate && !result) 3749 { 3750 if (get_tv_number_chk(&var2, &error) != 0) 3751 result = TRUE; 3752 clear_tv(&var2); 3753 if (error) 3754 return FAIL; 3755 } 3756 if (evaluate) 3757 { 3758 rettv->v_type = VAR_NUMBER; 3759 rettv->vval.v_number = result; 3760 } 3761 } 3762 3763 return OK; 3764 } 3765 3766 /* 3767 * Handle second level expression: 3768 * expr3 && expr3 && expr3 logical AND 3769 * 3770 * "arg" must point to the first non-white of the expression. 3771 * "arg" is advanced to the next non-white after the recognized expression. 3772 * 3773 * Return OK or FAIL. 3774 */ 3775 static int 3776 eval3(arg, rettv, evaluate) 3777 char_u **arg; 3778 typval_T *rettv; 3779 int evaluate; 3780 { 3781 typval_T var2; 3782 long result; 3783 int first; 3784 int error = FALSE; 3785 3786 /* 3787 * Get the first variable. 3788 */ 3789 if (eval4(arg, rettv, evaluate) == FAIL) 3790 return FAIL; 3791 3792 /* 3793 * Repeat until there is no following "&&". 3794 */ 3795 first = TRUE; 3796 result = TRUE; 3797 while ((*arg)[0] == '&' && (*arg)[1] == '&') 3798 { 3799 if (evaluate && first) 3800 { 3801 if (get_tv_number_chk(rettv, &error) == 0) 3802 result = FALSE; 3803 clear_tv(rettv); 3804 if (error) 3805 return FAIL; 3806 first = FALSE; 3807 } 3808 3809 /* 3810 * Get the second variable. 3811 */ 3812 *arg = skipwhite(*arg + 2); 3813 if (eval4(arg, &var2, evaluate && result) == FAIL) 3814 return FAIL; 3815 3816 /* 3817 * Compute the result. 3818 */ 3819 if (evaluate && result) 3820 { 3821 if (get_tv_number_chk(&var2, &error) == 0) 3822 result = FALSE; 3823 clear_tv(&var2); 3824 if (error) 3825 return FAIL; 3826 } 3827 if (evaluate) 3828 { 3829 rettv->v_type = VAR_NUMBER; 3830 rettv->vval.v_number = result; 3831 } 3832 } 3833 3834 return OK; 3835 } 3836 3837 /* 3838 * Handle third level expression: 3839 * var1 == var2 3840 * var1 =~ var2 3841 * var1 != var2 3842 * var1 !~ var2 3843 * var1 > var2 3844 * var1 >= var2 3845 * var1 < var2 3846 * var1 <= var2 3847 * var1 is var2 3848 * var1 isnot var2 3849 * 3850 * "arg" must point to the first non-white of the expression. 3851 * "arg" is advanced to the next non-white after the recognized expression. 3852 * 3853 * Return OK or FAIL. 3854 */ 3855 static int 3856 eval4(arg, rettv, evaluate) 3857 char_u **arg; 3858 typval_T *rettv; 3859 int evaluate; 3860 { 3861 typval_T var2; 3862 char_u *p; 3863 int i; 3864 exptype_T type = TYPE_UNKNOWN; 3865 int type_is = FALSE; /* TRUE for "is" and "isnot" */ 3866 int len = 2; 3867 long n1, n2; 3868 char_u *s1, *s2; 3869 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 3870 regmatch_T regmatch; 3871 int ic; 3872 char_u *save_cpo; 3873 3874 /* 3875 * Get the first variable. 3876 */ 3877 if (eval5(arg, rettv, evaluate) == FAIL) 3878 return FAIL; 3879 3880 p = *arg; 3881 switch (p[0]) 3882 { 3883 case '=': if (p[1] == '=') 3884 type = TYPE_EQUAL; 3885 else if (p[1] == '~') 3886 type = TYPE_MATCH; 3887 break; 3888 case '!': if (p[1] == '=') 3889 type = TYPE_NEQUAL; 3890 else if (p[1] == '~') 3891 type = TYPE_NOMATCH; 3892 break; 3893 case '>': if (p[1] != '=') 3894 { 3895 type = TYPE_GREATER; 3896 len = 1; 3897 } 3898 else 3899 type = TYPE_GEQUAL; 3900 break; 3901 case '<': if (p[1] != '=') 3902 { 3903 type = TYPE_SMALLER; 3904 len = 1; 3905 } 3906 else 3907 type = TYPE_SEQUAL; 3908 break; 3909 case 'i': if (p[1] == 's') 3910 { 3911 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') 3912 len = 5; 3913 if (!vim_isIDc(p[len])) 3914 { 3915 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; 3916 type_is = TRUE; 3917 } 3918 } 3919 break; 3920 } 3921 3922 /* 3923 * If there is a comparitive operator, use it. 3924 */ 3925 if (type != TYPE_UNKNOWN) 3926 { 3927 /* extra question mark appended: ignore case */ 3928 if (p[len] == '?') 3929 { 3930 ic = TRUE; 3931 ++len; 3932 } 3933 /* extra '#' appended: match case */ 3934 else if (p[len] == '#') 3935 { 3936 ic = FALSE; 3937 ++len; 3938 } 3939 /* nothing appened: use 'ignorecase' */ 3940 else 3941 ic = p_ic; 3942 3943 /* 3944 * Get the second variable. 3945 */ 3946 *arg = skipwhite(p + len); 3947 if (eval5(arg, &var2, evaluate) == FAIL) 3948 { 3949 clear_tv(rettv); 3950 return FAIL; 3951 } 3952 3953 if (evaluate) 3954 { 3955 if (type_is && rettv->v_type != var2.v_type) 3956 { 3957 /* For "is" a different type always means FALSE, for "notis" 3958 * it means TRUE. */ 3959 n1 = (type == TYPE_NEQUAL); 3960 } 3961 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) 3962 { 3963 if (type_is) 3964 { 3965 n1 = (rettv->v_type == var2.v_type 3966 && rettv->vval.v_list == var2.vval.v_list); 3967 if (type == TYPE_NEQUAL) 3968 n1 = !n1; 3969 } 3970 else if (rettv->v_type != var2.v_type 3971 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 3972 { 3973 if (rettv->v_type != var2.v_type) 3974 EMSG(_("E691: Can only compare List with List")); 3975 else 3976 EMSG(_("E692: Invalid operation for Lists")); 3977 clear_tv(rettv); 3978 clear_tv(&var2); 3979 return FAIL; 3980 } 3981 else 3982 { 3983 /* Compare two Lists for being equal or unequal. */ 3984 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); 3985 if (type == TYPE_NEQUAL) 3986 n1 = !n1; 3987 } 3988 } 3989 3990 else if (rettv->v_type == VAR_DICT || var2.v_type == VAR_DICT) 3991 { 3992 if (type_is) 3993 { 3994 n1 = (rettv->v_type == var2.v_type 3995 && rettv->vval.v_dict == var2.vval.v_dict); 3996 if (type == TYPE_NEQUAL) 3997 n1 = !n1; 3998 } 3999 else if (rettv->v_type != var2.v_type 4000 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4001 { 4002 if (rettv->v_type != var2.v_type) 4003 EMSG(_("E735: Can only compare Dictionary with Dictionary")); 4004 else 4005 EMSG(_("E736: Invalid operation for Dictionary")); 4006 clear_tv(rettv); 4007 clear_tv(&var2); 4008 return FAIL; 4009 } 4010 else 4011 { 4012 /* Compare two Dictionaries for being equal or unequal. */ 4013 n1 = dict_equal(rettv->vval.v_dict, var2.vval.v_dict, ic); 4014 if (type == TYPE_NEQUAL) 4015 n1 = !n1; 4016 } 4017 } 4018 4019 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) 4020 { 4021 if (rettv->v_type != var2.v_type 4022 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) 4023 { 4024 if (rettv->v_type != var2.v_type) 4025 EMSG(_("E693: Can only compare Funcref with Funcref")); 4026 else 4027 EMSG(_("E694: Invalid operation for Funcrefs")); 4028 clear_tv(rettv); 4029 clear_tv(&var2); 4030 return FAIL; 4031 } 4032 else 4033 { 4034 /* Compare two Funcrefs for being equal or unequal. */ 4035 if (rettv->vval.v_string == NULL 4036 || var2.vval.v_string == NULL) 4037 n1 = FALSE; 4038 else 4039 n1 = STRCMP(rettv->vval.v_string, 4040 var2.vval.v_string) == 0; 4041 if (type == TYPE_NEQUAL) 4042 n1 = !n1; 4043 } 4044 } 4045 4046 /* 4047 * If one of the two variables is a number, compare as a number. 4048 * When using "=~" or "!~", always compare as string. 4049 */ 4050 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) 4051 && type != TYPE_MATCH && type != TYPE_NOMATCH) 4052 { 4053 n1 = get_tv_number(rettv); 4054 n2 = get_tv_number(&var2); 4055 switch (type) 4056 { 4057 case TYPE_EQUAL: n1 = (n1 == n2); break; 4058 case TYPE_NEQUAL: n1 = (n1 != n2); break; 4059 case TYPE_GREATER: n1 = (n1 > n2); break; 4060 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 4061 case TYPE_SMALLER: n1 = (n1 < n2); break; 4062 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 4063 case TYPE_UNKNOWN: 4064 case TYPE_MATCH: 4065 case TYPE_NOMATCH: break; /* avoid gcc warning */ 4066 } 4067 } 4068 else 4069 { 4070 s1 = get_tv_string_buf(rettv, buf1); 4071 s2 = get_tv_string_buf(&var2, buf2); 4072 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 4073 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 4074 else 4075 i = 0; 4076 n1 = FALSE; 4077 switch (type) 4078 { 4079 case TYPE_EQUAL: n1 = (i == 0); break; 4080 case TYPE_NEQUAL: n1 = (i != 0); break; 4081 case TYPE_GREATER: n1 = (i > 0); break; 4082 case TYPE_GEQUAL: n1 = (i >= 0); break; 4083 case TYPE_SMALLER: n1 = (i < 0); break; 4084 case TYPE_SEQUAL: n1 = (i <= 0); break; 4085 4086 case TYPE_MATCH: 4087 case TYPE_NOMATCH: 4088 /* avoid 'l' flag in 'cpoptions' */ 4089 save_cpo = p_cpo; 4090 p_cpo = (char_u *)""; 4091 regmatch.regprog = vim_regcomp(s2, 4092 RE_MAGIC + RE_STRING); 4093 regmatch.rm_ic = ic; 4094 if (regmatch.regprog != NULL) 4095 { 4096 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 4097 vim_free(regmatch.regprog); 4098 if (type == TYPE_NOMATCH) 4099 n1 = !n1; 4100 } 4101 p_cpo = save_cpo; 4102 break; 4103 4104 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 4105 } 4106 } 4107 clear_tv(rettv); 4108 clear_tv(&var2); 4109 rettv->v_type = VAR_NUMBER; 4110 rettv->vval.v_number = n1; 4111 } 4112 } 4113 4114 return OK; 4115 } 4116 4117 /* 4118 * Handle fourth level expression: 4119 * + number addition 4120 * - number subtraction 4121 * . string concatenation 4122 * 4123 * "arg" must point to the first non-white of the expression. 4124 * "arg" is advanced to the next non-white after the recognized expression. 4125 * 4126 * Return OK or FAIL. 4127 */ 4128 static int 4129 eval5(arg, rettv, evaluate) 4130 char_u **arg; 4131 typval_T *rettv; 4132 int evaluate; 4133 { 4134 typval_T var2; 4135 typval_T var3; 4136 int op; 4137 long n1, n2; 4138 char_u *s1, *s2; 4139 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 4140 char_u *p; 4141 4142 /* 4143 * Get the first variable. 4144 */ 4145 if (eval6(arg, rettv, evaluate) == FAIL) 4146 return FAIL; 4147 4148 /* 4149 * Repeat computing, until no '+', '-' or '.' is following. 4150 */ 4151 for (;;) 4152 { 4153 op = **arg; 4154 if (op != '+' && op != '-' && op != '.') 4155 break; 4156 4157 if (op != '+' || rettv->v_type != VAR_LIST) 4158 { 4159 /* For "list + ...", an illegal use of the first operand as 4160 * a number cannot be determined before evaluating the 2nd 4161 * operand: if this is also a list, all is ok. 4162 * For "something . ...", "something - ..." or "non-list + ...", 4163 * we know that the first operand needs to be a string or number 4164 * without evaluating the 2nd operand. So check before to avoid 4165 * side effects after an error. */ 4166 if (evaluate && get_tv_string_chk(rettv) == NULL) 4167 { 4168 clear_tv(rettv); 4169 return FAIL; 4170 } 4171 } 4172 4173 /* 4174 * Get the second variable. 4175 */ 4176 *arg = skipwhite(*arg + 1); 4177 if (eval6(arg, &var2, evaluate) == FAIL) 4178 { 4179 clear_tv(rettv); 4180 return FAIL; 4181 } 4182 4183 if (evaluate) 4184 { 4185 /* 4186 * Compute the result. 4187 */ 4188 if (op == '.') 4189 { 4190 s1 = get_tv_string_buf(rettv, buf1); /* already checked */ 4191 s2 = get_tv_string_buf_chk(&var2, buf2); 4192 if (s2 == NULL) /* type error ? */ 4193 { 4194 clear_tv(rettv); 4195 clear_tv(&var2); 4196 return FAIL; 4197 } 4198 p = concat_str(s1, s2); 4199 clear_tv(rettv); 4200 rettv->v_type = VAR_STRING; 4201 rettv->vval.v_string = p; 4202 } 4203 else if (op == '+' && rettv->v_type == VAR_LIST 4204 && var2.v_type == VAR_LIST) 4205 { 4206 /* concatenate Lists */ 4207 if (list_concat(rettv->vval.v_list, var2.vval.v_list, 4208 &var3) == FAIL) 4209 { 4210 clear_tv(rettv); 4211 clear_tv(&var2); 4212 return FAIL; 4213 } 4214 clear_tv(rettv); 4215 *rettv = var3; 4216 } 4217 else 4218 { 4219 int error = FALSE; 4220 4221 n1 = get_tv_number_chk(rettv, &error); 4222 if (error) 4223 { 4224 /* This can only happen for "list + non-list". 4225 * For "non-list + ..." or "something - ...", we returned 4226 * before evaluating the 2nd operand. */ 4227 clear_tv(rettv); 4228 return FAIL; 4229 } 4230 n2 = get_tv_number_chk(&var2, &error); 4231 if (error) 4232 { 4233 clear_tv(rettv); 4234 clear_tv(&var2); 4235 return FAIL; 4236 } 4237 clear_tv(rettv); 4238 if (op == '+') 4239 n1 = n1 + n2; 4240 else 4241 n1 = n1 - n2; 4242 rettv->v_type = VAR_NUMBER; 4243 rettv->vval.v_number = n1; 4244 } 4245 clear_tv(&var2); 4246 } 4247 } 4248 return OK; 4249 } 4250 4251 /* 4252 * Handle fifth level expression: 4253 * * number multiplication 4254 * / number division 4255 * % number modulo 4256 * 4257 * "arg" must point to the first non-white of the expression. 4258 * "arg" is advanced to the next non-white after the recognized expression. 4259 * 4260 * Return OK or FAIL. 4261 */ 4262 static int 4263 eval6(arg, rettv, evaluate) 4264 char_u **arg; 4265 typval_T *rettv; 4266 int evaluate; 4267 { 4268 typval_T var2; 4269 int op; 4270 long n1, n2; 4271 int error = FALSE; 4272 4273 /* 4274 * Get the first variable. 4275 */ 4276 if (eval7(arg, rettv, evaluate) == FAIL) 4277 return FAIL; 4278 4279 /* 4280 * Repeat computing, until no '*', '/' or '%' is following. 4281 */ 4282 for (;;) 4283 { 4284 op = **arg; 4285 if (op != '*' && op != '/' && op != '%') 4286 break; 4287 4288 if (evaluate) 4289 { 4290 n1 = get_tv_number_chk(rettv, &error); 4291 clear_tv(rettv); 4292 if (error) 4293 return FAIL; 4294 } 4295 else 4296 n1 = 0; 4297 4298 /* 4299 * Get the second variable. 4300 */ 4301 *arg = skipwhite(*arg + 1); 4302 if (eval7(arg, &var2, evaluate) == FAIL) 4303 return FAIL; 4304 4305 if (evaluate) 4306 { 4307 n2 = get_tv_number_chk(&var2, &error); 4308 clear_tv(&var2); 4309 if (error) 4310 return FAIL; 4311 4312 /* 4313 * Compute the result. 4314 */ 4315 if (op == '*') 4316 n1 = n1 * n2; 4317 else if (op == '/') 4318 { 4319 if (n2 == 0) /* give an error message? */ 4320 n1 = 0x7fffffffL; 4321 else 4322 n1 = n1 / n2; 4323 } 4324 else 4325 { 4326 if (n2 == 0) /* give an error message? */ 4327 n1 = 0; 4328 else 4329 n1 = n1 % n2; 4330 } 4331 rettv->v_type = VAR_NUMBER; 4332 rettv->vval.v_number = n1; 4333 } 4334 } 4335 4336 return OK; 4337 } 4338 4339 /* 4340 * Handle sixth level expression: 4341 * number number constant 4342 * "string" string contstant 4343 * 'string' literal string contstant 4344 * &option-name option value 4345 * @r register contents 4346 * identifier variable value 4347 * function() function call 4348 * $VAR environment variable 4349 * (expression) nested expression 4350 * [expr, expr] List 4351 * {key: val, key: val} Dictionary 4352 * 4353 * Also handle: 4354 * ! in front logical NOT 4355 * - in front unary minus 4356 * + in front unary plus (ignored) 4357 * trailing [] subscript in String or List 4358 * trailing .name entry in Dictionary 4359 * 4360 * "arg" must point to the first non-white of the expression. 4361 * "arg" is advanced to the next non-white after the recognized expression. 4362 * 4363 * Return OK or FAIL. 4364 */ 4365 static int 4366 eval7(arg, rettv, evaluate) 4367 char_u **arg; 4368 typval_T *rettv; 4369 int evaluate; 4370 { 4371 long n; 4372 int len; 4373 char_u *s; 4374 int val; 4375 char_u *start_leader, *end_leader; 4376 int ret = OK; 4377 char_u *alias; 4378 4379 /* 4380 * Initialise variable so that clear_tv() can't mistake this for a 4381 * string and free a string that isn't there. 4382 */ 4383 rettv->v_type = VAR_UNKNOWN; 4384 4385 /* 4386 * Skip '!' and '-' characters. They are handled later. 4387 */ 4388 start_leader = *arg; 4389 while (**arg == '!' || **arg == '-' || **arg == '+') 4390 *arg = skipwhite(*arg + 1); 4391 end_leader = *arg; 4392 4393 switch (**arg) 4394 { 4395 /* 4396 * Number constant. 4397 */ 4398 case '0': 4399 case '1': 4400 case '2': 4401 case '3': 4402 case '4': 4403 case '5': 4404 case '6': 4405 case '7': 4406 case '8': 4407 case '9': 4408 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 4409 *arg += len; 4410 if (evaluate) 4411 { 4412 rettv->v_type = VAR_NUMBER; 4413 rettv->vval.v_number = n; 4414 } 4415 break; 4416 4417 /* 4418 * String constant: "string". 4419 */ 4420 case '"': ret = get_string_tv(arg, rettv, evaluate); 4421 break; 4422 4423 /* 4424 * Literal string constant: 'str''ing'. 4425 */ 4426 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); 4427 break; 4428 4429 /* 4430 * List: [expr, expr] 4431 */ 4432 case '[': ret = get_list_tv(arg, rettv, evaluate); 4433 break; 4434 4435 /* 4436 * Dictionary: {key: val, key: val} 4437 */ 4438 case '{': ret = get_dict_tv(arg, rettv, evaluate); 4439 break; 4440 4441 /* 4442 * Option value: &name 4443 */ 4444 case '&': ret = get_option_tv(arg, rettv, evaluate); 4445 break; 4446 4447 /* 4448 * Environment variable: $VAR. 4449 */ 4450 case '$': ret = get_env_tv(arg, rettv, evaluate); 4451 break; 4452 4453 /* 4454 * Register contents: @r. 4455 */ 4456 case '@': ++*arg; 4457 if (evaluate) 4458 { 4459 rettv->v_type = VAR_STRING; 4460 rettv->vval.v_string = get_reg_contents(**arg, TRUE, TRUE); 4461 } 4462 if (**arg != NUL) 4463 ++*arg; 4464 break; 4465 4466 /* 4467 * nested expression: (expression). 4468 */ 4469 case '(': *arg = skipwhite(*arg + 1); 4470 ret = eval1(arg, rettv, evaluate); /* recursive! */ 4471 if (**arg == ')') 4472 ++*arg; 4473 else if (ret == OK) 4474 { 4475 EMSG(_("E110: Missing ')'")); 4476 clear_tv(rettv); 4477 ret = FAIL; 4478 } 4479 break; 4480 4481 default: ret = NOTDONE; 4482 break; 4483 } 4484 4485 if (ret == NOTDONE) 4486 { 4487 /* 4488 * Must be a variable or function name. 4489 * Can also be a curly-braces kind of name: {expr}. 4490 */ 4491 s = *arg; 4492 len = get_name_len(arg, &alias, evaluate, TRUE); 4493 if (alias != NULL) 4494 s = alias; 4495 4496 if (len <= 0) 4497 ret = FAIL; 4498 else 4499 { 4500 if (**arg == '(') /* recursive! */ 4501 { 4502 /* If "s" is the name of a variable of type VAR_FUNC 4503 * use its contents. */ 4504 s = deref_func_name(s, &len); 4505 4506 /* Invoke the function. */ 4507 ret = get_func_tv(s, len, rettv, arg, 4508 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 4509 &len, evaluate, NULL); 4510 /* Stop the expression evaluation when immediately 4511 * aborting on error, or when an interrupt occurred or 4512 * an exception was thrown but not caught. */ 4513 if (aborting()) 4514 { 4515 if (ret == OK) 4516 clear_tv(rettv); 4517 ret = FAIL; 4518 } 4519 } 4520 else if (evaluate) 4521 ret = get_var_tv(s, len, rettv, TRUE); 4522 else 4523 ret = OK; 4524 } 4525 4526 if (alias != NULL) 4527 vim_free(alias); 4528 } 4529 4530 *arg = skipwhite(*arg); 4531 4532 /* Handle following '[', '(' and '.' for expr[expr], expr.name, 4533 * expr(expr). */ 4534 if (ret == OK) 4535 ret = handle_subscript(arg, rettv, evaluate, TRUE); 4536 4537 /* 4538 * Apply logical NOT and unary '-', from right to left, ignore '+'. 4539 */ 4540 if (ret == OK && evaluate && end_leader > start_leader) 4541 { 4542 int error = FALSE; 4543 4544 val = get_tv_number_chk(rettv, &error); 4545 if (error) 4546 { 4547 clear_tv(rettv); 4548 ret = FAIL; 4549 } 4550 else 4551 { 4552 while (end_leader > start_leader) 4553 { 4554 --end_leader; 4555 if (*end_leader == '!') 4556 val = !val; 4557 else if (*end_leader == '-') 4558 val = -val; 4559 } 4560 clear_tv(rettv); 4561 rettv->v_type = VAR_NUMBER; 4562 rettv->vval.v_number = val; 4563 } 4564 } 4565 4566 return ret; 4567 } 4568 4569 /* 4570 * Evaluate an "[expr]" or "[expr:expr]" index. 4571 * "*arg" points to the '['. 4572 * Returns FAIL or OK. "*arg" is advanced to after the ']'. 4573 */ 4574 static int 4575 eval_index(arg, rettv, evaluate, verbose) 4576 char_u **arg; 4577 typval_T *rettv; 4578 int evaluate; 4579 int verbose; /* give error messages */ 4580 { 4581 int empty1 = FALSE, empty2 = FALSE; 4582 typval_T var1, var2; 4583 long n1, n2 = 0; 4584 long len = -1; 4585 int range = FALSE; 4586 char_u *s; 4587 char_u *key = NULL; 4588 4589 if (rettv->v_type == VAR_FUNC) 4590 { 4591 if (verbose) 4592 EMSG(_("E695: Cannot index a Funcref")); 4593 return FAIL; 4594 } 4595 4596 if (**arg == '.') 4597 { 4598 /* 4599 * dict.name 4600 */ 4601 key = *arg + 1; 4602 for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; ++len) 4603 ; 4604 if (len == 0) 4605 return FAIL; 4606 *arg = skipwhite(key + len); 4607 } 4608 else 4609 { 4610 /* 4611 * something[idx] 4612 * 4613 * Get the (first) variable from inside the []. 4614 */ 4615 *arg = skipwhite(*arg + 1); 4616 if (**arg == ':') 4617 empty1 = TRUE; 4618 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ 4619 return FAIL; 4620 else if (evaluate && get_tv_string_chk(&var1) == NULL) 4621 { 4622 /* not a number or string */ 4623 clear_tv(&var1); 4624 return FAIL; 4625 } 4626 4627 /* 4628 * Get the second variable from inside the [:]. 4629 */ 4630 if (**arg == ':') 4631 { 4632 range = TRUE; 4633 *arg = skipwhite(*arg + 1); 4634 if (**arg == ']') 4635 empty2 = TRUE; 4636 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 4637 { 4638 if (!empty1) 4639 clear_tv(&var1); 4640 return FAIL; 4641 } 4642 else if (evaluate && get_tv_string_chk(&var2) == NULL) 4643 { 4644 /* not a number or string */ 4645 if (!empty1) 4646 clear_tv(&var1); 4647 clear_tv(&var2); 4648 return FAIL; 4649 } 4650 } 4651 4652 /* Check for the ']'. */ 4653 if (**arg != ']') 4654 { 4655 if (verbose) 4656 EMSG(_(e_missbrac)); 4657 clear_tv(&var1); 4658 if (range) 4659 clear_tv(&var2); 4660 return FAIL; 4661 } 4662 *arg = skipwhite(*arg + 1); /* skip the ']' */ 4663 } 4664 4665 if (evaluate) 4666 { 4667 n1 = 0; 4668 if (!empty1 && rettv->v_type != VAR_DICT) 4669 { 4670 n1 = get_tv_number(&var1); 4671 clear_tv(&var1); 4672 } 4673 if (range) 4674 { 4675 if (empty2) 4676 n2 = -1; 4677 else 4678 { 4679 n2 = get_tv_number(&var2); 4680 clear_tv(&var2); 4681 } 4682 } 4683 4684 switch (rettv->v_type) 4685 { 4686 case VAR_NUMBER: 4687 case VAR_STRING: 4688 s = get_tv_string(rettv); 4689 len = (long)STRLEN(s); 4690 if (range) 4691 { 4692 /* The resulting variable is a substring. If the indexes 4693 * are out of range the result is empty. */ 4694 if (n1 < 0) 4695 { 4696 n1 = len + n1; 4697 if (n1 < 0) 4698 n1 = 0; 4699 } 4700 if (n2 < 0) 4701 n2 = len + n2; 4702 else if (n2 >= len) 4703 n2 = len; 4704 if (n1 >= len || n2 < 0 || n1 > n2) 4705 s = NULL; 4706 else 4707 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); 4708 } 4709 else 4710 { 4711 /* The resulting variable is a string of a single 4712 * character. If the index is too big or negative the 4713 * result is empty. */ 4714 if (n1 >= len || n1 < 0) 4715 s = NULL; 4716 else 4717 s = vim_strnsave(s + n1, 1); 4718 } 4719 clear_tv(rettv); 4720 rettv->v_type = VAR_STRING; 4721 rettv->vval.v_string = s; 4722 break; 4723 4724 case VAR_LIST: 4725 len = list_len(rettv->vval.v_list); 4726 if (n1 < 0) 4727 n1 = len + n1; 4728 if (!empty1 && (n1 < 0 || n1 >= len)) 4729 { 4730 if (verbose) 4731 EMSGN(_(e_listidx), n1); 4732 return FAIL; 4733 } 4734 if (range) 4735 { 4736 list_T *l; 4737 listitem_T *item; 4738 4739 if (n2 < 0) 4740 n2 = len + n2; 4741 if (!empty2 && (n2 < 0 || n2 >= len || n2 + 1 < n1)) 4742 { 4743 if (verbose) 4744 EMSGN(_(e_listidx), n2); 4745 return FAIL; 4746 } 4747 l = list_alloc(); 4748 if (l == NULL) 4749 return FAIL; 4750 for (item = list_find(rettv->vval.v_list, n1); 4751 n1 <= n2; ++n1) 4752 { 4753 if (list_append_tv(l, &item->li_tv) == FAIL) 4754 { 4755 list_free(l); 4756 return FAIL; 4757 } 4758 item = item->li_next; 4759 } 4760 clear_tv(rettv); 4761 rettv->v_type = VAR_LIST; 4762 rettv->vval.v_list = l; 4763 ++l->lv_refcount; 4764 } 4765 else 4766 { 4767 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 4768 &var1); 4769 clear_tv(rettv); 4770 *rettv = var1; 4771 } 4772 break; 4773 4774 case VAR_DICT: 4775 if (range) 4776 { 4777 if (verbose) 4778 EMSG(_(e_dictrange)); 4779 if (len == -1) 4780 clear_tv(&var1); 4781 return FAIL; 4782 } 4783 { 4784 dictitem_T *item; 4785 4786 if (len == -1) 4787 { 4788 key = get_tv_string(&var1); 4789 if (*key == NUL) 4790 { 4791 if (verbose) 4792 EMSG(_(e_emptykey)); 4793 clear_tv(&var1); 4794 return FAIL; 4795 } 4796 } 4797 4798 item = dict_find(rettv->vval.v_dict, key, (int)len); 4799 4800 if (item == NULL && verbose) 4801 EMSG2(_(e_dictkey), key); 4802 if (len == -1) 4803 clear_tv(&var1); 4804 if (item == NULL) 4805 return FAIL; 4806 4807 copy_tv(&item->di_tv, &var1); 4808 clear_tv(rettv); 4809 *rettv = var1; 4810 } 4811 break; 4812 } 4813 } 4814 4815 return OK; 4816 } 4817 4818 /* 4819 * Get an option value. 4820 * "arg" points to the '&' or '+' before the option name. 4821 * "arg" is advanced to character after the option name. 4822 * Return OK or FAIL. 4823 */ 4824 static int 4825 get_option_tv(arg, rettv, evaluate) 4826 char_u **arg; 4827 typval_T *rettv; /* when NULL, only check if option exists */ 4828 int evaluate; 4829 { 4830 char_u *option_end; 4831 long numval; 4832 char_u *stringval; 4833 int opt_type; 4834 int c; 4835 int working = (**arg == '+'); /* has("+option") */ 4836 int ret = OK; 4837 int opt_flags; 4838 4839 /* 4840 * Isolate the option name and find its value. 4841 */ 4842 option_end = find_option_end(arg, &opt_flags); 4843 if (option_end == NULL) 4844 { 4845 if (rettv != NULL) 4846 EMSG2(_("E112: Option name missing: %s"), *arg); 4847 return FAIL; 4848 } 4849 4850 if (!evaluate) 4851 { 4852 *arg = option_end; 4853 return OK; 4854 } 4855 4856 c = *option_end; 4857 *option_end = NUL; 4858 opt_type = get_option_value(*arg, &numval, 4859 rettv == NULL ? NULL : &stringval, opt_flags); 4860 4861 if (opt_type == -3) /* invalid name */ 4862 { 4863 if (rettv != NULL) 4864 EMSG2(_("E113: Unknown option: %s"), *arg); 4865 ret = FAIL; 4866 } 4867 else if (rettv != NULL) 4868 { 4869 if (opt_type == -2) /* hidden string option */ 4870 { 4871 rettv->v_type = VAR_STRING; 4872 rettv->vval.v_string = NULL; 4873 } 4874 else if (opt_type == -1) /* hidden number option */ 4875 { 4876 rettv->v_type = VAR_NUMBER; 4877 rettv->vval.v_number = 0; 4878 } 4879 else if (opt_type == 1) /* number option */ 4880 { 4881 rettv->v_type = VAR_NUMBER; 4882 rettv->vval.v_number = numval; 4883 } 4884 else /* string option */ 4885 { 4886 rettv->v_type = VAR_STRING; 4887 rettv->vval.v_string = stringval; 4888 } 4889 } 4890 else if (working && (opt_type == -2 || opt_type == -1)) 4891 ret = FAIL; 4892 4893 *option_end = c; /* put back for error messages */ 4894 *arg = option_end; 4895 4896 return ret; 4897 } 4898 4899 /* 4900 * Allocate a variable for a string constant. 4901 * Return OK or FAIL. 4902 */ 4903 static int 4904 get_string_tv(arg, rettv, evaluate) 4905 char_u **arg; 4906 typval_T *rettv; 4907 int evaluate; 4908 { 4909 char_u *p; 4910 char_u *name; 4911 int extra = 0; 4912 4913 /* 4914 * Find the end of the string, skipping backslashed characters. 4915 */ 4916 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) 4917 { 4918 if (*p == '\\' && p[1] != NUL) 4919 { 4920 ++p; 4921 /* A "\<x>" form occupies at least 4 characters, and produces up 4922 * to 6 characters: reserve space for 2 extra */ 4923 if (*p == '<') 4924 extra += 2; 4925 } 4926 } 4927 4928 if (*p != '"') 4929 { 4930 EMSG2(_("E114: Missing quote: %s"), *arg); 4931 return FAIL; 4932 } 4933 4934 /* If only parsing, set *arg and return here */ 4935 if (!evaluate) 4936 { 4937 *arg = p + 1; 4938 return OK; 4939 } 4940 4941 /* 4942 * Copy the string into allocated memory, handling backslashed 4943 * characters. 4944 */ 4945 name = alloc((unsigned)(p - *arg + extra)); 4946 if (name == NULL) 4947 return FAIL; 4948 rettv->v_type = VAR_STRING; 4949 rettv->vval.v_string = name; 4950 4951 for (p = *arg + 1; *p != NUL && *p != '"'; ) 4952 { 4953 if (*p == '\\') 4954 { 4955 switch (*++p) 4956 { 4957 case 'b': *name++ = BS; ++p; break; 4958 case 'e': *name++ = ESC; ++p; break; 4959 case 'f': *name++ = FF; ++p; break; 4960 case 'n': *name++ = NL; ++p; break; 4961 case 'r': *name++ = CAR; ++p; break; 4962 case 't': *name++ = TAB; ++p; break; 4963 4964 case 'X': /* hex: "\x1", "\x12" */ 4965 case 'x': 4966 case 'u': /* Unicode: "\u0023" */ 4967 case 'U': 4968 if (vim_isxdigit(p[1])) 4969 { 4970 int n, nr; 4971 int c = toupper(*p); 4972 4973 if (c == 'X') 4974 n = 2; 4975 else 4976 n = 4; 4977 nr = 0; 4978 while (--n >= 0 && vim_isxdigit(p[1])) 4979 { 4980 ++p; 4981 nr = (nr << 4) + hex2nr(*p); 4982 } 4983 ++p; 4984 #ifdef FEAT_MBYTE 4985 /* For "\u" store the number according to 4986 * 'encoding'. */ 4987 if (c != 'X') 4988 name += (*mb_char2bytes)(nr, name); 4989 else 4990 #endif 4991 *name++ = nr; 4992 } 4993 break; 4994 4995 /* octal: "\1", "\12", "\123" */ 4996 case '0': 4997 case '1': 4998 case '2': 4999 case '3': 5000 case '4': 5001 case '5': 5002 case '6': 5003 case '7': *name = *p++ - '0'; 5004 if (*p >= '0' && *p <= '7') 5005 { 5006 *name = (*name << 3) + *p++ - '0'; 5007 if (*p >= '0' && *p <= '7') 5008 *name = (*name << 3) + *p++ - '0'; 5009 } 5010 ++name; 5011 break; 5012 5013 /* Special key, e.g.: "\<C-W>" */ 5014 case '<': extra = trans_special(&p, name, TRUE); 5015 if (extra != 0) 5016 { 5017 name += extra; 5018 break; 5019 } 5020 /* FALLTHROUGH */ 5021 5022 default: MB_COPY_CHAR(p, name); 5023 break; 5024 } 5025 } 5026 else 5027 MB_COPY_CHAR(p, name); 5028 5029 } 5030 *name = NUL; 5031 *arg = p + 1; 5032 5033 return OK; 5034 } 5035 5036 /* 5037 * Allocate a variable for a 'str''ing' constant. 5038 * Return OK or FAIL. 5039 */ 5040 static int 5041 get_lit_string_tv(arg, rettv, evaluate) 5042 char_u **arg; 5043 typval_T *rettv; 5044 int evaluate; 5045 { 5046 char_u *p; 5047 char_u *str; 5048 int reduce = 0; 5049 5050 /* 5051 * Find the end of the string, skipping ''. 5052 */ 5053 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) 5054 { 5055 if (*p == '\'') 5056 { 5057 if (p[1] != '\'') 5058 break; 5059 ++reduce; 5060 ++p; 5061 } 5062 } 5063 5064 if (*p != '\'') 5065 { 5066 EMSG2(_("E115: Missing quote: %s"), *arg); 5067 return FAIL; 5068 } 5069 5070 /* If only parsing return after setting "*arg" */ 5071 if (!evaluate) 5072 { 5073 *arg = p + 1; 5074 return OK; 5075 } 5076 5077 /* 5078 * Copy the string into allocated memory, handling '' to ' reduction. 5079 */ 5080 str = alloc((unsigned)((p - *arg) - reduce)); 5081 if (str == NULL) 5082 return FAIL; 5083 rettv->v_type = VAR_STRING; 5084 rettv->vval.v_string = str; 5085 5086 for (p = *arg + 1; *p != NUL; ) 5087 { 5088 if (*p == '\'') 5089 { 5090 if (p[1] != '\'') 5091 break; 5092 ++p; 5093 } 5094 MB_COPY_CHAR(p, str); 5095 } 5096 *str = NUL; 5097 *arg = p + 1; 5098 5099 return OK; 5100 } 5101 5102 /* 5103 * Allocate a variable for a List and fill it from "*arg". 5104 * Return OK or FAIL. 5105 */ 5106 static int 5107 get_list_tv(arg, rettv, evaluate) 5108 char_u **arg; 5109 typval_T *rettv; 5110 int evaluate; 5111 { 5112 list_T *l = NULL; 5113 typval_T tv; 5114 listitem_T *item; 5115 5116 if (evaluate) 5117 { 5118 l = list_alloc(); 5119 if (l == NULL) 5120 return FAIL; 5121 } 5122 5123 *arg = skipwhite(*arg + 1); 5124 while (**arg != ']' && **arg != NUL) 5125 { 5126 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 5127 goto failret; 5128 if (evaluate) 5129 { 5130 item = listitem_alloc(); 5131 if (item != NULL) 5132 { 5133 item->li_tv = tv; 5134 item->li_tv.v_lock = 0; 5135 list_append(l, item); 5136 } 5137 else 5138 clear_tv(&tv); 5139 } 5140 5141 if (**arg == ']') 5142 break; 5143 if (**arg != ',') 5144 { 5145 EMSG2(_("E696: Missing comma in List: %s"), *arg); 5146 goto failret; 5147 } 5148 *arg = skipwhite(*arg + 1); 5149 } 5150 5151 if (**arg != ']') 5152 { 5153 EMSG2(_("E697: Missing end of List ']': %s"), *arg); 5154 failret: 5155 if (evaluate) 5156 list_free(l); 5157 return FAIL; 5158 } 5159 5160 *arg = skipwhite(*arg + 1); 5161 if (evaluate) 5162 { 5163 rettv->v_type = VAR_LIST; 5164 rettv->vval.v_list = l; 5165 ++l->lv_refcount; 5166 } 5167 5168 return OK; 5169 } 5170 5171 /* 5172 * Allocate an empty header for a list. 5173 */ 5174 static list_T * 5175 list_alloc() 5176 { 5177 list_T *l; 5178 5179 l = (list_T *)alloc_clear(sizeof(list_T)); 5180 if (l != NULL) 5181 { 5182 /* Prepend the list to the list of lists for garbage collection. */ 5183 if (first_list != NULL) 5184 first_list->lv_used_prev = l; 5185 l->lv_used_prev = NULL; 5186 l->lv_used_next = first_list; 5187 first_list = l; 5188 } 5189 return l; 5190 } 5191 5192 /* 5193 * Unreference a list: decrement the reference count and free it when it 5194 * becomes zero. 5195 */ 5196 void 5197 list_unref(l) 5198 list_T *l; 5199 { 5200 if (l != NULL && l->lv_refcount != DEL_REFCOUNT && --l->lv_refcount <= 0) 5201 list_free(l); 5202 } 5203 5204 /* 5205 * Free a list, including all items it points to. 5206 * Ignores the reference count. 5207 */ 5208 static void 5209 list_free(l) 5210 list_T *l; 5211 { 5212 listitem_T *item; 5213 5214 /* Avoid that recursive reference to the list frees us again. */ 5215 l->lv_refcount = DEL_REFCOUNT; 5216 5217 /* Remove the list from the list of lists for garbage collection. */ 5218 if (l->lv_used_prev == NULL) 5219 first_list = l->lv_used_next; 5220 else 5221 l->lv_used_prev->lv_used_next = l->lv_used_next; 5222 if (l->lv_used_next != NULL) 5223 l->lv_used_next->lv_used_prev = l->lv_used_prev; 5224 5225 for (item = l->lv_first; item != NULL; item = l->lv_first) 5226 { 5227 /* Remove the item before deleting it. */ 5228 l->lv_first = item->li_next; 5229 listitem_free(item); 5230 } 5231 vim_free(l); 5232 } 5233 5234 /* 5235 * Allocate a list item. 5236 */ 5237 static listitem_T * 5238 listitem_alloc() 5239 { 5240 return (listitem_T *)alloc(sizeof(listitem_T)); 5241 } 5242 5243 /* 5244 * Free a list item. Also clears the value. Does not notify watchers. 5245 */ 5246 static void 5247 listitem_free(item) 5248 listitem_T *item; 5249 { 5250 clear_tv(&item->li_tv); 5251 vim_free(item); 5252 } 5253 5254 /* 5255 * Remove a list item from a List and free it. Also clears the value. 5256 */ 5257 static void 5258 listitem_remove(l, item) 5259 list_T *l; 5260 listitem_T *item; 5261 { 5262 list_remove(l, item, item); 5263 listitem_free(item); 5264 } 5265 5266 /* 5267 * Get the number of items in a list. 5268 */ 5269 static long 5270 list_len(l) 5271 list_T *l; 5272 { 5273 if (l == NULL) 5274 return 0L; 5275 return l->lv_len; 5276 } 5277 5278 /* 5279 * Return TRUE when two lists have exactly the same values. 5280 */ 5281 static int 5282 list_equal(l1, l2, ic) 5283 list_T *l1; 5284 list_T *l2; 5285 int ic; /* ignore case for strings */ 5286 { 5287 listitem_T *item1, *item2; 5288 5289 if (list_len(l1) != list_len(l2)) 5290 return FALSE; 5291 5292 for (item1 = l1->lv_first, item2 = l2->lv_first; 5293 item1 != NULL && item2 != NULL; 5294 item1 = item1->li_next, item2 = item2->li_next) 5295 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) 5296 return FALSE; 5297 return item1 == NULL && item2 == NULL; 5298 } 5299 5300 /* 5301 * Return TRUE when two dictionaries have exactly the same key/values. 5302 */ 5303 static int 5304 dict_equal(d1, d2, ic) 5305 dict_T *d1; 5306 dict_T *d2; 5307 int ic; /* ignore case for strings */ 5308 { 5309 hashitem_T *hi; 5310 dictitem_T *item2; 5311 int todo; 5312 5313 if (dict_len(d1) != dict_len(d2)) 5314 return FALSE; 5315 5316 todo = d1->dv_hashtab.ht_used; 5317 for (hi = d1->dv_hashtab.ht_array; todo > 0; ++hi) 5318 { 5319 if (!HASHITEM_EMPTY(hi)) 5320 { 5321 item2 = dict_find(d2, hi->hi_key, -1); 5322 if (item2 == NULL) 5323 return FALSE; 5324 if (!tv_equal(&HI2DI(hi)->di_tv, &item2->di_tv, ic)) 5325 return FALSE; 5326 --todo; 5327 } 5328 } 5329 return TRUE; 5330 } 5331 5332 /* 5333 * Return TRUE if "tv1" and "tv2" have the same value. 5334 * Compares the items just like "==" would compare them, but strings and 5335 * numbers are different. 5336 */ 5337 static int 5338 tv_equal(tv1, tv2, ic) 5339 typval_T *tv1; 5340 typval_T *tv2; 5341 int ic; /* ignore case */ 5342 { 5343 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 5344 char_u *s1, *s2; 5345 5346 if (tv1->v_type != tv2->v_type) 5347 return FALSE; 5348 5349 switch (tv1->v_type) 5350 { 5351 case VAR_LIST: 5352 /* recursive! */ 5353 return list_equal(tv1->vval.v_list, tv2->vval.v_list, ic); 5354 5355 case VAR_DICT: 5356 /* recursive! */ 5357 return dict_equal(tv1->vval.v_dict, tv2->vval.v_dict, ic); 5358 5359 case VAR_FUNC: 5360 return (tv1->vval.v_string != NULL 5361 && tv2->vval.v_string != NULL 5362 && STRCMP(tv1->vval.v_string, tv2->vval.v_string) == 0); 5363 5364 case VAR_NUMBER: 5365 return tv1->vval.v_number == tv2->vval.v_number; 5366 5367 case VAR_STRING: 5368 s1 = get_tv_string_buf(tv1, buf1); 5369 s2 = get_tv_string_buf(tv2, buf2); 5370 return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0); 5371 } 5372 5373 EMSG2(_(e_intern2), "tv_equal()"); 5374 return TRUE; 5375 } 5376 5377 /* 5378 * Locate item with index "n" in list "l" and return it. 5379 * A negative index is counted from the end; -1 is the last item. 5380 * Returns NULL when "n" is out of range. 5381 */ 5382 static listitem_T * 5383 list_find(l, n) 5384 list_T *l; 5385 long n; 5386 { 5387 listitem_T *item; 5388 long idx; 5389 5390 if (l == NULL) 5391 return NULL; 5392 5393 /* Negative index is relative to the end. */ 5394 if (n < 0) 5395 n = l->lv_len + n; 5396 5397 /* Check for index out of range. */ 5398 if (n < 0 || n >= l->lv_len) 5399 return NULL; 5400 5401 /* When there is a cached index may start search from there. */ 5402 if (l->lv_idx_item != NULL) 5403 { 5404 if (n < l->lv_idx / 2) 5405 { 5406 /* closest to the start of the list */ 5407 item = l->lv_first; 5408 idx = 0; 5409 } 5410 else if (n > (l->lv_idx + l->lv_len) / 2) 5411 { 5412 /* closest to the end of the list */ 5413 item = l->lv_last; 5414 idx = l->lv_len - 1; 5415 } 5416 else 5417 { 5418 /* closest to the cached index */ 5419 item = l->lv_idx_item; 5420 idx = l->lv_idx; 5421 } 5422 } 5423 else 5424 { 5425 if (n < l->lv_len / 2) 5426 { 5427 /* closest to the start of the list */ 5428 item = l->lv_first; 5429 idx = 0; 5430 } 5431 else 5432 { 5433 /* closest to the end of the list */ 5434 item = l->lv_last; 5435 idx = l->lv_len - 1; 5436 } 5437 } 5438 5439 while (n > idx) 5440 { 5441 /* search forward */ 5442 item = item->li_next; 5443 ++idx; 5444 } 5445 while (n < idx) 5446 { 5447 /* search backward */ 5448 item = item->li_prev; 5449 --idx; 5450 } 5451 5452 /* cache the used index */ 5453 l->lv_idx = idx; 5454 l->lv_idx_item = item; 5455 5456 return item; 5457 } 5458 5459 /* 5460 * Locate "item" list "l" and return its index. 5461 * Returns -1 when "item" is not in the list. 5462 */ 5463 static long 5464 list_idx_of_item(l, item) 5465 list_T *l; 5466 listitem_T *item; 5467 { 5468 long idx = 0; 5469 listitem_T *li; 5470 5471 if (l == NULL) 5472 return -1; 5473 idx = 0; 5474 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) 5475 ++idx; 5476 if (li == NULL) 5477 return -1; 5478 return idx; 5479 } 5480 5481 /* 5482 * Append item "item" to the end of list "l". 5483 */ 5484 static void 5485 list_append(l, item) 5486 list_T *l; 5487 listitem_T *item; 5488 { 5489 if (l->lv_last == NULL) 5490 { 5491 /* empty list */ 5492 l->lv_first = item; 5493 l->lv_last = item; 5494 item->li_prev = NULL; 5495 } 5496 else 5497 { 5498 l->lv_last->li_next = item; 5499 item->li_prev = l->lv_last; 5500 l->lv_last = item; 5501 } 5502 ++l->lv_len; 5503 item->li_next = NULL; 5504 } 5505 5506 /* 5507 * Append typval_T "tv" to the end of list "l". 5508 * Return FAIL when out of memory. 5509 */ 5510 static int 5511 list_append_tv(l, tv) 5512 list_T *l; 5513 typval_T *tv; 5514 { 5515 listitem_T *li = listitem_alloc(); 5516 5517 if (li == NULL) 5518 return FAIL; 5519 copy_tv(tv, &li->li_tv); 5520 list_append(l, li); 5521 return OK; 5522 } 5523 5524 /* 5525 * Add a dictionary to a list. Used by getqflist(). 5526 * Return FAIL when out of memory. 5527 */ 5528 int 5529 list_append_dict(list, dict) 5530 list_T *list; 5531 dict_T *dict; 5532 { 5533 listitem_T *li = listitem_alloc(); 5534 5535 if (li == NULL) 5536 return FAIL; 5537 li->li_tv.v_type = VAR_DICT; 5538 li->li_tv.v_lock = 0; 5539 li->li_tv.vval.v_dict = dict; 5540 list_append(list, li); 5541 ++dict->dv_refcount; 5542 return OK; 5543 } 5544 5545 /* 5546 * Insert typval_T "tv" in list "l" before "item". 5547 * If "item" is NULL append at the end. 5548 * Return FAIL when out of memory. 5549 */ 5550 static int 5551 list_insert_tv(l, tv, item) 5552 list_T *l; 5553 typval_T *tv; 5554 listitem_T *item; 5555 { 5556 listitem_T *ni = listitem_alloc(); 5557 5558 if (ni == NULL) 5559 return FAIL; 5560 copy_tv(tv, &ni->li_tv); 5561 if (item == NULL) 5562 /* Append new item at end of list. */ 5563 list_append(l, ni); 5564 else 5565 { 5566 /* Insert new item before existing item. */ 5567 ni->li_prev = item->li_prev; 5568 ni->li_next = item; 5569 if (item->li_prev == NULL) 5570 { 5571 l->lv_first = ni; 5572 ++l->lv_idx; 5573 } 5574 else 5575 { 5576 item->li_prev->li_next = ni; 5577 l->lv_idx_item = NULL; 5578 } 5579 item->li_prev = ni; 5580 ++l->lv_len; 5581 } 5582 return OK; 5583 } 5584 5585 /* 5586 * Extend "l1" with "l2". 5587 * If "bef" is NULL append at the end, otherwise insert before this item. 5588 * Returns FAIL when out of memory. 5589 */ 5590 static int 5591 list_extend(l1, l2, bef) 5592 list_T *l1; 5593 list_T *l2; 5594 listitem_T *bef; 5595 { 5596 listitem_T *item; 5597 5598 for (item = l2->lv_first; item != NULL; item = item->li_next) 5599 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) 5600 return FAIL; 5601 return OK; 5602 } 5603 5604 /* 5605 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". 5606 * Return FAIL when out of memory. 5607 */ 5608 static int 5609 list_concat(l1, l2, tv) 5610 list_T *l1; 5611 list_T *l2; 5612 typval_T *tv; 5613 { 5614 list_T *l; 5615 5616 /* make a copy of the first list. */ 5617 l = list_copy(l1, FALSE, 0); 5618 if (l == NULL) 5619 return FAIL; 5620 tv->v_type = VAR_LIST; 5621 tv->vval.v_list = l; 5622 5623 /* append all items from the second list */ 5624 return list_extend(l, l2, NULL); 5625 } 5626 5627 /* 5628 * Make a copy of list "orig". Shallow if "deep" is FALSE. 5629 * The refcount of the new list is set to 1. 5630 * See item_copy() for "copyID". 5631 * Returns NULL when out of memory. 5632 */ 5633 static list_T * 5634 list_copy(orig, deep, copyID) 5635 list_T *orig; 5636 int deep; 5637 int copyID; 5638 { 5639 list_T *copy; 5640 listitem_T *item; 5641 listitem_T *ni; 5642 5643 if (orig == NULL) 5644 return NULL; 5645 5646 copy = list_alloc(); 5647 if (copy != NULL) 5648 { 5649 if (copyID != 0) 5650 { 5651 /* Do this before adding the items, because one of the items may 5652 * refer back to this list. */ 5653 orig->lv_copyID = copyID; 5654 orig->lv_copylist = copy; 5655 } 5656 for (item = orig->lv_first; item != NULL && !got_int; 5657 item = item->li_next) 5658 { 5659 ni = listitem_alloc(); 5660 if (ni == NULL) 5661 break; 5662 if (deep) 5663 { 5664 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) 5665 { 5666 vim_free(ni); 5667 break; 5668 } 5669 } 5670 else 5671 copy_tv(&item->li_tv, &ni->li_tv); 5672 list_append(copy, ni); 5673 } 5674 ++copy->lv_refcount; 5675 if (item != NULL) 5676 { 5677 list_unref(copy); 5678 copy = NULL; 5679 } 5680 } 5681 5682 return copy; 5683 } 5684 5685 /* 5686 * Remove items "item" to "item2" from list "l". 5687 * Does not free the listitem or the value! 5688 */ 5689 static void 5690 list_remove(l, item, item2) 5691 list_T *l; 5692 listitem_T *item; 5693 listitem_T *item2; 5694 { 5695 listitem_T *ip; 5696 5697 /* notify watchers */ 5698 for (ip = item; ip != NULL; ip = ip->li_next) 5699 { 5700 --l->lv_len; 5701 list_fix_watch(l, ip); 5702 if (ip == item2) 5703 break; 5704 } 5705 5706 if (item2->li_next == NULL) 5707 l->lv_last = item->li_prev; 5708 else 5709 item2->li_next->li_prev = item->li_prev; 5710 if (item->li_prev == NULL) 5711 l->lv_first = item2->li_next; 5712 else 5713 item->li_prev->li_next = item2->li_next; 5714 l->lv_idx_item = NULL; 5715 } 5716 5717 /* 5718 * Return an allocated string with the string representation of a list. 5719 * May return NULL. 5720 */ 5721 static char_u * 5722 list2string(tv) 5723 typval_T *tv; 5724 { 5725 garray_T ga; 5726 5727 if (tv->vval.v_list == NULL) 5728 return NULL; 5729 ga_init2(&ga, (int)sizeof(char), 80); 5730 ga_append(&ga, '['); 5731 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE) == FAIL) 5732 { 5733 vim_free(ga.ga_data); 5734 return NULL; 5735 } 5736 ga_append(&ga, ']'); 5737 ga_append(&ga, NUL); 5738 return (char_u *)ga.ga_data; 5739 } 5740 5741 /* 5742 * Join list "l" into a string in "*gap", using separator "sep". 5743 * When "echo" is TRUE use String as echoed, otherwise as inside a List. 5744 * Return FAIL or OK. 5745 */ 5746 static int 5747 list_join(gap, l, sep, echo) 5748 garray_T *gap; 5749 list_T *l; 5750 char_u *sep; 5751 int echo; 5752 { 5753 int first = TRUE; 5754 char_u *tofree; 5755 char_u numbuf[NUMBUFLEN]; 5756 listitem_T *item; 5757 char_u *s; 5758 5759 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) 5760 { 5761 if (first) 5762 first = FALSE; 5763 else 5764 ga_concat(gap, sep); 5765 5766 if (echo) 5767 s = echo_string(&item->li_tv, &tofree, numbuf); 5768 else 5769 s = tv2string(&item->li_tv, &tofree, numbuf); 5770 if (s != NULL) 5771 ga_concat(gap, s); 5772 vim_free(tofree); 5773 if (s == NULL) 5774 return FAIL; 5775 } 5776 return OK; 5777 } 5778 5779 /* 5780 * Garbage collection for lists and dictionaries. 5781 * 5782 * We use reference counts to be able to free most items right away when they 5783 * are no longer used. But for composite items it's possible that it becomes 5784 * unused while the reference count is > 0: When there is a recursive 5785 * reference. Example: 5786 * :let l = [1, 2, 3] 5787 * :let d = {9: l} 5788 * :let l[1] = d 5789 * 5790 * Since this is quite unusual we handle this with garbage collection: every 5791 * once in a while find out which lists and dicts are not referenced from any 5792 * variable. 5793 * 5794 * Here is a good reference text about garbage collection (refers to Python 5795 * but it applies to all reference-counting mechanisms): 5796 * http://python.ca/nas/python/gc/ 5797 */ 5798 5799 /* 5800 * Do garbage collection for lists and dicts. 5801 * Return TRUE if some memory was freed. 5802 */ 5803 int 5804 garbage_collect() 5805 { 5806 dict_T *dd; 5807 list_T *ll; 5808 int copyID = ++current_copyID; 5809 buf_T *buf; 5810 win_T *wp; 5811 int i; 5812 funccall_T *fc; 5813 int did_free = FALSE; 5814 5815 /* 5816 * 1. Go through all accessible variables and mark all lists and dicts 5817 * with copyID. 5818 */ 5819 /* script-local variables */ 5820 for (i = 1; i <= ga_scripts.ga_len; ++i) 5821 set_ref_in_ht(&SCRIPT_VARS(i), copyID); 5822 5823 /* buffer-local variables */ 5824 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5825 set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID); 5826 5827 /* window-local variables */ 5828 FOR_ALL_WINDOWS(wp) 5829 set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID); 5830 5831 /* global variables */ 5832 set_ref_in_ht(&globvarht, copyID); 5833 5834 /* function-local variables */ 5835 for (fc = current_funccal; fc != NULL; fc = fc->caller) 5836 { 5837 set_ref_in_ht(&fc->l_vars.dv_hashtab, copyID); 5838 set_ref_in_ht(&fc->l_avars.dv_hashtab, copyID); 5839 } 5840 5841 /* 5842 * 2. Go through the list of dicts and free items without the copyID. 5843 */ 5844 for (dd = first_dict; dd != NULL; ) 5845 if (dd->dv_copyID != copyID) 5846 { 5847 dict_free(dd); 5848 did_free = TRUE; 5849 5850 /* restart, next dict may also have been freed */ 5851 dd = first_dict; 5852 } 5853 else 5854 dd = dd->dv_used_next; 5855 5856 /* 5857 * 3. Go through the list of lists and free items without the copyID. 5858 */ 5859 for (ll = first_list; ll != NULL; ) 5860 if (ll->lv_copyID != copyID) 5861 { 5862 list_free(ll); 5863 did_free = TRUE; 5864 5865 /* restart, next dict may also have been freed */ 5866 ll = first_list; 5867 } 5868 else 5869 ll = ll->lv_used_next; 5870 5871 return did_free; 5872 } 5873 5874 /* 5875 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 5876 */ 5877 static void 5878 set_ref_in_ht(ht, copyID) 5879 hashtab_T *ht; 5880 int copyID; 5881 { 5882 int todo; 5883 hashitem_T *hi; 5884 5885 todo = ht->ht_used; 5886 for (hi = ht->ht_array; todo > 0; ++hi) 5887 if (!HASHITEM_EMPTY(hi)) 5888 { 5889 --todo; 5890 set_ref_in_item(&HI2DI(hi)->di_tv, copyID); 5891 } 5892 } 5893 5894 /* 5895 * Mark all lists and dicts referenced through list "l" with "copyID". 5896 */ 5897 static void 5898 set_ref_in_list(l, copyID) 5899 list_T *l; 5900 int copyID; 5901 { 5902 listitem_T *li; 5903 5904 for (li = l->lv_first; li != NULL; li = li->li_next) 5905 set_ref_in_item(&li->li_tv, copyID); 5906 } 5907 5908 /* 5909 * Mark all lists and dicts referenced through typval "tv" with "copyID". 5910 */ 5911 static void 5912 set_ref_in_item(tv, copyID) 5913 typval_T *tv; 5914 int copyID; 5915 { 5916 dict_T *dd; 5917 list_T *ll; 5918 5919 switch (tv->v_type) 5920 { 5921 case VAR_DICT: 5922 dd = tv->vval.v_dict; 5923 if (dd->dv_copyID != copyID) 5924 { 5925 /* Didn't see this dict yet. */ 5926 dd->dv_copyID = copyID; 5927 set_ref_in_ht(&dd->dv_hashtab, copyID); 5928 } 5929 break; 5930 5931 case VAR_LIST: 5932 ll = tv->vval.v_list; 5933 if (ll->lv_copyID != copyID) 5934 { 5935 /* Didn't see this list yet. */ 5936 ll->lv_copyID = copyID; 5937 set_ref_in_list(ll, copyID); 5938 } 5939 break; 5940 } 5941 return; 5942 } 5943 5944 /* 5945 * Allocate an empty header for a dictionary. 5946 */ 5947 dict_T * 5948 dict_alloc() 5949 { 5950 dict_T *d; 5951 5952 d = (dict_T *)alloc(sizeof(dict_T)); 5953 if (d != NULL) 5954 { 5955 /* Add the list to the hashtable for garbage collection. */ 5956 if (first_dict != NULL) 5957 first_dict->dv_used_prev = d; 5958 d->dv_used_next = first_dict; 5959 d->dv_used_prev = NULL; 5960 5961 hash_init(&d->dv_hashtab); 5962 d->dv_lock = 0; 5963 d->dv_refcount = 0; 5964 d->dv_copyID = 0; 5965 } 5966 return d; 5967 } 5968 5969 /* 5970 * Unreference a Dictionary: decrement the reference count and free it when it 5971 * becomes zero. 5972 */ 5973 static void 5974 dict_unref(d) 5975 dict_T *d; 5976 { 5977 if (d != NULL && d->dv_refcount != DEL_REFCOUNT && --d->dv_refcount <= 0) 5978 dict_free(d); 5979 } 5980 5981 /* 5982 * Free a Dictionary, including all items it contains. 5983 * Ignores the reference count. 5984 */ 5985 static void 5986 dict_free(d) 5987 dict_T *d; 5988 { 5989 int todo; 5990 hashitem_T *hi; 5991 dictitem_T *di; 5992 5993 /* Avoid that recursive reference to the dict frees us again. */ 5994 d->dv_refcount = DEL_REFCOUNT; 5995 5996 /* Remove the dict from the list of dicts for garbage collection. */ 5997 if (d->dv_used_prev == NULL) 5998 first_dict = d->dv_used_next; 5999 else 6000 d->dv_used_prev->dv_used_next = d->dv_used_next; 6001 if (d->dv_used_next != NULL) 6002 d->dv_used_next->dv_used_prev = d->dv_used_prev; 6003 6004 /* Lock the hashtab, we don't want it to resize while freeing items. */ 6005 hash_lock(&d->dv_hashtab); 6006 todo = d->dv_hashtab.ht_used; 6007 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 6008 { 6009 if (!HASHITEM_EMPTY(hi)) 6010 { 6011 /* Remove the item before deleting it, just in case there is 6012 * something recursive causing trouble. */ 6013 di = HI2DI(hi); 6014 hash_remove(&d->dv_hashtab, hi); 6015 dictitem_free(di); 6016 --todo; 6017 } 6018 } 6019 hash_clear(&d->dv_hashtab); 6020 vim_free(d); 6021 } 6022 6023 /* 6024 * Allocate a Dictionary item. 6025 * The "key" is copied to the new item. 6026 * Note that the value of the item "di_tv" still needs to be initialized! 6027 * Returns NULL when out of memory. 6028 */ 6029 static dictitem_T * 6030 dictitem_alloc(key) 6031 char_u *key; 6032 { 6033 dictitem_T *di; 6034 6035 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(key)); 6036 if (di != NULL) 6037 { 6038 STRCPY(di->di_key, key); 6039 di->di_flags = 0; 6040 } 6041 return di; 6042 } 6043 6044 /* 6045 * Make a copy of a Dictionary item. 6046 */ 6047 static dictitem_T * 6048 dictitem_copy(org) 6049 dictitem_T *org; 6050 { 6051 dictitem_T *di; 6052 6053 di = (dictitem_T *)alloc(sizeof(dictitem_T) + STRLEN(org->di_key)); 6054 if (di != NULL) 6055 { 6056 STRCPY(di->di_key, org->di_key); 6057 di->di_flags = 0; 6058 copy_tv(&org->di_tv, &di->di_tv); 6059 } 6060 return di; 6061 } 6062 6063 /* 6064 * Remove item "item" from Dictionary "dict" and free it. 6065 */ 6066 static void 6067 dictitem_remove(dict, item) 6068 dict_T *dict; 6069 dictitem_T *item; 6070 { 6071 hashitem_T *hi; 6072 6073 hi = hash_find(&dict->dv_hashtab, item->di_key); 6074 if (HASHITEM_EMPTY(hi)) 6075 EMSG2(_(e_intern2), "dictitem_remove()"); 6076 else 6077 hash_remove(&dict->dv_hashtab, hi); 6078 dictitem_free(item); 6079 } 6080 6081 /* 6082 * Free a dict item. Also clears the value. 6083 */ 6084 static void 6085 dictitem_free(item) 6086 dictitem_T *item; 6087 { 6088 clear_tv(&item->di_tv); 6089 vim_free(item); 6090 } 6091 6092 /* 6093 * Make a copy of dict "d". Shallow if "deep" is FALSE. 6094 * The refcount of the new dict is set to 1. 6095 * See item_copy() for "copyID". 6096 * Returns NULL when out of memory. 6097 */ 6098 static dict_T * 6099 dict_copy(orig, deep, copyID) 6100 dict_T *orig; 6101 int deep; 6102 int copyID; 6103 { 6104 dict_T *copy; 6105 dictitem_T *di; 6106 int todo; 6107 hashitem_T *hi; 6108 6109 if (orig == NULL) 6110 return NULL; 6111 6112 copy = dict_alloc(); 6113 if (copy != NULL) 6114 { 6115 if (copyID != 0) 6116 { 6117 orig->dv_copyID = copyID; 6118 orig->dv_copydict = copy; 6119 } 6120 todo = orig->dv_hashtab.ht_used; 6121 for (hi = orig->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6122 { 6123 if (!HASHITEM_EMPTY(hi)) 6124 { 6125 --todo; 6126 6127 di = dictitem_alloc(hi->hi_key); 6128 if (di == NULL) 6129 break; 6130 if (deep) 6131 { 6132 if (item_copy(&HI2DI(hi)->di_tv, &di->di_tv, deep, 6133 copyID) == FAIL) 6134 { 6135 vim_free(di); 6136 break; 6137 } 6138 } 6139 else 6140 copy_tv(&HI2DI(hi)->di_tv, &di->di_tv); 6141 if (dict_add(copy, di) == FAIL) 6142 { 6143 dictitem_free(di); 6144 break; 6145 } 6146 } 6147 } 6148 6149 ++copy->dv_refcount; 6150 if (todo > 0) 6151 { 6152 dict_unref(copy); 6153 copy = NULL; 6154 } 6155 } 6156 6157 return copy; 6158 } 6159 6160 /* 6161 * Add item "item" to Dictionary "d". 6162 * Returns FAIL when out of memory and when key already existed. 6163 */ 6164 static int 6165 dict_add(d, item) 6166 dict_T *d; 6167 dictitem_T *item; 6168 { 6169 return hash_add(&d->dv_hashtab, item->di_key); 6170 } 6171 6172 /* 6173 * Add a number or string entry to dictionary "d". 6174 * When "str" is NULL use number "nr", otherwise use "str". 6175 * Returns FAIL when out of memory and when key already exists. 6176 */ 6177 int 6178 dict_add_nr_str(d, key, nr, str) 6179 dict_T *d; 6180 char *key; 6181 long nr; 6182 char_u *str; 6183 { 6184 dictitem_T *item; 6185 6186 item = dictitem_alloc((char_u *)key); 6187 if (item == NULL) 6188 return FAIL; 6189 item->di_tv.v_lock = 0; 6190 if (str == NULL) 6191 { 6192 item->di_tv.v_type = VAR_NUMBER; 6193 item->di_tv.vval.v_number = nr; 6194 } 6195 else 6196 { 6197 item->di_tv.v_type = VAR_STRING; 6198 item->di_tv.vval.v_string = vim_strsave(str); 6199 } 6200 if (dict_add(d, item) == FAIL) 6201 { 6202 dictitem_free(item); 6203 return FAIL; 6204 } 6205 return OK; 6206 } 6207 6208 /* 6209 * Get the number of items in a Dictionary. 6210 */ 6211 static long 6212 dict_len(d) 6213 dict_T *d; 6214 { 6215 if (d == NULL) 6216 return 0L; 6217 return d->dv_hashtab.ht_used; 6218 } 6219 6220 /* 6221 * Find item "key[len]" in Dictionary "d". 6222 * If "len" is negative use strlen(key). 6223 * Returns NULL when not found. 6224 */ 6225 static dictitem_T * 6226 dict_find(d, key, len) 6227 dict_T *d; 6228 char_u *key; 6229 int len; 6230 { 6231 #define AKEYLEN 200 6232 char_u buf[AKEYLEN]; 6233 char_u *akey; 6234 char_u *tofree = NULL; 6235 hashitem_T *hi; 6236 6237 if (len < 0) 6238 akey = key; 6239 else if (len >= AKEYLEN) 6240 { 6241 tofree = akey = vim_strnsave(key, len); 6242 if (akey == NULL) 6243 return NULL; 6244 } 6245 else 6246 { 6247 /* Avoid a malloc/free by using buf[]. */ 6248 vim_strncpy(buf, key, len); 6249 akey = buf; 6250 } 6251 6252 hi = hash_find(&d->dv_hashtab, akey); 6253 vim_free(tofree); 6254 if (HASHITEM_EMPTY(hi)) 6255 return NULL; 6256 return HI2DI(hi); 6257 } 6258 6259 /* 6260 * Get a string item from a dictionary in allocated memory. 6261 * Returns NULL if the entry doesn't exist or out of memory. 6262 */ 6263 char_u * 6264 get_dict_string(d, key) 6265 dict_T *d; 6266 char_u *key; 6267 { 6268 dictitem_T *di; 6269 6270 di = dict_find(d, key, -1); 6271 if (di == NULL) 6272 return NULL; 6273 return vim_strsave(get_tv_string(&di->di_tv)); 6274 } 6275 6276 /* 6277 * Get a number item from a dictionary. 6278 * Returns 0 if the entry doesn't exist or out of memory. 6279 */ 6280 long 6281 get_dict_number(d, key) 6282 dict_T *d; 6283 char_u *key; 6284 { 6285 dictitem_T *di; 6286 6287 di = dict_find(d, key, -1); 6288 if (di == NULL) 6289 return 0; 6290 return get_tv_number(&di->di_tv); 6291 } 6292 6293 /* 6294 * Return an allocated string with the string representation of a Dictionary. 6295 * May return NULL. 6296 */ 6297 static char_u * 6298 dict2string(tv) 6299 typval_T *tv; 6300 { 6301 garray_T ga; 6302 int first = TRUE; 6303 char_u *tofree; 6304 char_u numbuf[NUMBUFLEN]; 6305 hashitem_T *hi; 6306 char_u *s; 6307 dict_T *d; 6308 int todo; 6309 6310 if ((d = tv->vval.v_dict) == NULL) 6311 return NULL; 6312 ga_init2(&ga, (int)sizeof(char), 80); 6313 ga_append(&ga, '{'); 6314 6315 todo = d->dv_hashtab.ht_used; 6316 for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int; ++hi) 6317 { 6318 if (!HASHITEM_EMPTY(hi)) 6319 { 6320 --todo; 6321 6322 if (first) 6323 first = FALSE; 6324 else 6325 ga_concat(&ga, (char_u *)", "); 6326 6327 tofree = string_quote(hi->hi_key, FALSE); 6328 if (tofree != NULL) 6329 { 6330 ga_concat(&ga, tofree); 6331 vim_free(tofree); 6332 } 6333 ga_concat(&ga, (char_u *)": "); 6334 s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf); 6335 if (s != NULL) 6336 ga_concat(&ga, s); 6337 vim_free(tofree); 6338 if (s == NULL) 6339 break; 6340 } 6341 } 6342 if (todo > 0) 6343 { 6344 vim_free(ga.ga_data); 6345 return NULL; 6346 } 6347 6348 ga_append(&ga, '}'); 6349 ga_append(&ga, NUL); 6350 return (char_u *)ga.ga_data; 6351 } 6352 6353 /* 6354 * Allocate a variable for a Dictionary and fill it from "*arg". 6355 * Return OK or FAIL. Returns NOTDONE for {expr}. 6356 */ 6357 static int 6358 get_dict_tv(arg, rettv, evaluate) 6359 char_u **arg; 6360 typval_T *rettv; 6361 int evaluate; 6362 { 6363 dict_T *d = NULL; 6364 typval_T tvkey; 6365 typval_T tv; 6366 char_u *key; 6367 dictitem_T *item; 6368 char_u *start = skipwhite(*arg + 1); 6369 char_u buf[NUMBUFLEN]; 6370 6371 /* 6372 * First check if it's not a curly-braces thing: {expr}. 6373 * Must do this without evaluating, otherwise a function may be called 6374 * twice. Unfortunately this means we need to call eval1() twice for the 6375 * first item. 6376 * But {} is an empty Dictionary. 6377 */ 6378 if (*start != '}') 6379 { 6380 if (eval1(&start, &tv, FALSE) == FAIL) /* recursive! */ 6381 return FAIL; 6382 if (*start == '}') 6383 return NOTDONE; 6384 } 6385 6386 if (evaluate) 6387 { 6388 d = dict_alloc(); 6389 if (d == NULL) 6390 return FAIL; 6391 } 6392 tvkey.v_type = VAR_UNKNOWN; 6393 tv.v_type = VAR_UNKNOWN; 6394 6395 *arg = skipwhite(*arg + 1); 6396 while (**arg != '}' && **arg != NUL) 6397 { 6398 if (eval1(arg, &tvkey, evaluate) == FAIL) /* recursive! */ 6399 goto failret; 6400 if (**arg != ':') 6401 { 6402 EMSG2(_("E720: Missing colon in Dictionary: %s"), *arg); 6403 clear_tv(&tvkey); 6404 goto failret; 6405 } 6406 key = get_tv_string_buf_chk(&tvkey, buf); 6407 if (key == NULL || *key == NUL) 6408 { 6409 /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */ 6410 if (key != NULL) 6411 EMSG(_(e_emptykey)); 6412 clear_tv(&tvkey); 6413 goto failret; 6414 } 6415 6416 *arg = skipwhite(*arg + 1); 6417 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ 6418 { 6419 clear_tv(&tvkey); 6420 goto failret; 6421 } 6422 if (evaluate) 6423 { 6424 item = dict_find(d, key, -1); 6425 if (item != NULL) 6426 { 6427 EMSG2(_("E721: Duplicate key in Dictionary: \"%s\""), key); 6428 clear_tv(&tvkey); 6429 clear_tv(&tv); 6430 goto failret; 6431 } 6432 item = dictitem_alloc(key); 6433 clear_tv(&tvkey); 6434 if (item != NULL) 6435 { 6436 item->di_tv = tv; 6437 item->di_tv.v_lock = 0; 6438 if (dict_add(d, item) == FAIL) 6439 dictitem_free(item); 6440 } 6441 } 6442 6443 if (**arg == '}') 6444 break; 6445 if (**arg != ',') 6446 { 6447 EMSG2(_("E722: Missing comma in Dictionary: %s"), *arg); 6448 goto failret; 6449 } 6450 *arg = skipwhite(*arg + 1); 6451 } 6452 6453 if (**arg != '}') 6454 { 6455 EMSG2(_("E723: Missing end of Dictionary '}': %s"), *arg); 6456 failret: 6457 if (evaluate) 6458 dict_free(d); 6459 return FAIL; 6460 } 6461 6462 *arg = skipwhite(*arg + 1); 6463 if (evaluate) 6464 { 6465 rettv->v_type = VAR_DICT; 6466 rettv->vval.v_dict = d; 6467 ++d->dv_refcount; 6468 } 6469 6470 return OK; 6471 } 6472 6473 /* 6474 * Return a string with the string representation of a variable. 6475 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6476 * "numbuf" is used for a number. 6477 * Does not put quotes around strings, as ":echo" displays values. 6478 * May return NULL; 6479 */ 6480 static char_u * 6481 echo_string(tv, tofree, numbuf) 6482 typval_T *tv; 6483 char_u **tofree; 6484 char_u *numbuf; 6485 { 6486 static int recurse = 0; 6487 char_u *r = NULL; 6488 6489 if (recurse >= DICT_MAXNEST) 6490 { 6491 EMSG(_("E724: variable nested too deep for displaying")); 6492 *tofree = NULL; 6493 return NULL; 6494 } 6495 ++recurse; 6496 6497 switch (tv->v_type) 6498 { 6499 case VAR_FUNC: 6500 *tofree = NULL; 6501 r = tv->vval.v_string; 6502 break; 6503 case VAR_LIST: 6504 *tofree = list2string(tv); 6505 r = *tofree; 6506 break; 6507 case VAR_DICT: 6508 *tofree = dict2string(tv); 6509 r = *tofree; 6510 break; 6511 case VAR_STRING: 6512 case VAR_NUMBER: 6513 *tofree = NULL; 6514 r = get_tv_string_buf(tv, numbuf); 6515 break; 6516 default: 6517 EMSG2(_(e_intern2), "echo_string()"); 6518 *tofree = NULL; 6519 } 6520 6521 --recurse; 6522 return r; 6523 } 6524 6525 /* 6526 * Return a string with the string representation of a variable. 6527 * If the memory is allocated "tofree" is set to it, otherwise NULL. 6528 * "numbuf" is used for a number. 6529 * Puts quotes around strings, so that they can be parsed back by eval(). 6530 * May return NULL; 6531 */ 6532 static char_u * 6533 tv2string(tv, tofree, numbuf) 6534 typval_T *tv; 6535 char_u **tofree; 6536 char_u *numbuf; 6537 { 6538 switch (tv->v_type) 6539 { 6540 case VAR_FUNC: 6541 *tofree = string_quote(tv->vval.v_string, TRUE); 6542 return *tofree; 6543 case VAR_STRING: 6544 *tofree = string_quote(tv->vval.v_string, FALSE); 6545 return *tofree; 6546 case VAR_NUMBER: 6547 case VAR_LIST: 6548 case VAR_DICT: 6549 break; 6550 default: 6551 EMSG2(_(e_intern2), "tv2string()"); 6552 } 6553 return echo_string(tv, tofree, numbuf); 6554 } 6555 6556 /* 6557 * Return string "str" in ' quotes, doubling ' characters. 6558 * If "str" is NULL an empty string is assumed. 6559 * If "function" is TRUE make it function('string'). 6560 */ 6561 static char_u * 6562 string_quote(str, function) 6563 char_u *str; 6564 int function; 6565 { 6566 unsigned len; 6567 char_u *p, *r, *s; 6568 6569 len = (function ? 13 : 3); 6570 if (str != NULL) 6571 { 6572 len += STRLEN(str); 6573 for (p = str; *p != NUL; mb_ptr_adv(p)) 6574 if (*p == '\'') 6575 ++len; 6576 } 6577 s = r = alloc(len); 6578 if (r != NULL) 6579 { 6580 if (function) 6581 { 6582 STRCPY(r, "function('"); 6583 r += 10; 6584 } 6585 else 6586 *r++ = '\''; 6587 if (str != NULL) 6588 for (p = str; *p != NUL; ) 6589 { 6590 if (*p == '\'') 6591 *r++ = '\''; 6592 MB_COPY_CHAR(p, r); 6593 } 6594 *r++ = '\''; 6595 if (function) 6596 *r++ = ')'; 6597 *r++ = NUL; 6598 } 6599 return s; 6600 } 6601 6602 /* 6603 * Get the value of an environment variable. 6604 * "arg" is pointing to the '$'. It is advanced to after the name. 6605 * If the environment variable was not set, silently assume it is empty. 6606 * Always return OK. 6607 */ 6608 static int 6609 get_env_tv(arg, rettv, evaluate) 6610 char_u **arg; 6611 typval_T *rettv; 6612 int evaluate; 6613 { 6614 char_u *string = NULL; 6615 int len; 6616 int cc; 6617 char_u *name; 6618 int mustfree = FALSE; 6619 6620 ++*arg; 6621 name = *arg; 6622 len = get_env_len(arg); 6623 if (evaluate) 6624 { 6625 if (len != 0) 6626 { 6627 cc = name[len]; 6628 name[len] = NUL; 6629 /* first try vim_getenv(), fast for normal environment vars */ 6630 string = vim_getenv(name, &mustfree); 6631 if (string != NULL && *string != NUL) 6632 { 6633 if (!mustfree) 6634 string = vim_strsave(string); 6635 } 6636 else 6637 { 6638 if (mustfree) 6639 vim_free(string); 6640 6641 /* next try expanding things like $VIM and ${HOME} */ 6642 string = expand_env_save(name - 1); 6643 if (string != NULL && *string == '$') 6644 { 6645 vim_free(string); 6646 string = NULL; 6647 } 6648 } 6649 name[len] = cc; 6650 } 6651 rettv->v_type = VAR_STRING; 6652 rettv->vval.v_string = string; 6653 } 6654 6655 return OK; 6656 } 6657 6658 /* 6659 * Array with names and number of arguments of all internal functions 6660 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 6661 */ 6662 static struct fst 6663 { 6664 char *f_name; /* function name */ 6665 char f_min_argc; /* minimal number of arguments */ 6666 char f_max_argc; /* maximal number of arguments */ 6667 void (*f_func) __ARGS((typval_T *args, typval_T *rvar)); 6668 /* implemenation of function */ 6669 } functions[] = 6670 { 6671 {"add", 2, 2, f_add}, 6672 {"append", 2, 2, f_append}, 6673 {"argc", 0, 0, f_argc}, 6674 {"argidx", 0, 0, f_argidx}, 6675 {"argv", 1, 1, f_argv}, 6676 {"browse", 4, 4, f_browse}, 6677 {"browsedir", 2, 2, f_browsedir}, 6678 {"bufexists", 1, 1, f_bufexists}, 6679 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 6680 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 6681 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 6682 {"buflisted", 1, 1, f_buflisted}, 6683 {"bufloaded", 1, 1, f_bufloaded}, 6684 {"bufname", 1, 1, f_bufname}, 6685 {"bufnr", 1, 1, f_bufnr}, 6686 {"bufwinnr", 1, 1, f_bufwinnr}, 6687 {"byte2line", 1, 1, f_byte2line}, 6688 {"byteidx", 2, 2, f_byteidx}, 6689 {"call", 2, 3, f_call}, 6690 {"char2nr", 1, 1, f_char2nr}, 6691 {"cindent", 1, 1, f_cindent}, 6692 {"col", 1, 1, f_col}, 6693 {"confirm", 1, 4, f_confirm}, 6694 {"copy", 1, 1, f_copy}, 6695 {"count", 2, 4, f_count}, 6696 {"cscope_connection",0,3, f_cscope_connection}, 6697 {"cursor", 2, 2, f_cursor}, 6698 {"deepcopy", 1, 2, f_deepcopy}, 6699 {"delete", 1, 1, f_delete}, 6700 {"did_filetype", 0, 0, f_did_filetype}, 6701 {"diff_filler", 1, 1, f_diff_filler}, 6702 {"diff_hlID", 2, 2, f_diff_hlID}, 6703 {"empty", 1, 1, f_empty}, 6704 {"escape", 2, 2, f_escape}, 6705 {"eval", 1, 1, f_eval}, 6706 {"eventhandler", 0, 0, f_eventhandler}, 6707 {"executable", 1, 1, f_executable}, 6708 {"exists", 1, 1, f_exists}, 6709 {"expand", 1, 2, f_expand}, 6710 {"extend", 2, 3, f_extend}, 6711 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 6712 {"filereadable", 1, 1, f_filereadable}, 6713 {"filewritable", 1, 1, f_filewritable}, 6714 {"filter", 2, 2, f_filter}, 6715 {"finddir", 1, 3, f_finddir}, 6716 {"findfile", 1, 3, f_findfile}, 6717 {"fnamemodify", 2, 2, f_fnamemodify}, 6718 {"foldclosed", 1, 1, f_foldclosed}, 6719 {"foldclosedend", 1, 1, f_foldclosedend}, 6720 {"foldlevel", 1, 1, f_foldlevel}, 6721 {"foldtext", 0, 0, f_foldtext}, 6722 {"foldtextresult", 1, 1, f_foldtextresult}, 6723 {"foreground", 0, 0, f_foreground}, 6724 {"function", 1, 1, f_function}, 6725 {"garbagecollect", 0, 0, f_garbagecollect}, 6726 {"get", 2, 3, f_get}, 6727 {"getbufline", 2, 3, f_getbufline}, 6728 {"getbufvar", 2, 2, f_getbufvar}, 6729 {"getchar", 0, 1, f_getchar}, 6730 {"getcharmod", 0, 0, f_getcharmod}, 6731 {"getcmdline", 0, 0, f_getcmdline}, 6732 {"getcmdpos", 0, 0, f_getcmdpos}, 6733 {"getcwd", 0, 0, f_getcwd}, 6734 {"getfontname", 0, 1, f_getfontname}, 6735 {"getfperm", 1, 1, f_getfperm}, 6736 {"getfsize", 1, 1, f_getfsize}, 6737 {"getftime", 1, 1, f_getftime}, 6738 {"getftype", 1, 1, f_getftype}, 6739 {"getline", 1, 2, f_getline}, 6740 {"getqflist", 0, 0, f_getqflist}, 6741 {"getreg", 0, 2, f_getreg}, 6742 {"getregtype", 0, 1, f_getregtype}, 6743 {"getwinposx", 0, 0, f_getwinposx}, 6744 {"getwinposy", 0, 0, f_getwinposy}, 6745 {"getwinvar", 2, 2, f_getwinvar}, 6746 {"glob", 1, 1, f_glob}, 6747 {"globpath", 2, 2, f_globpath}, 6748 {"has", 1, 1, f_has}, 6749 {"has_key", 2, 2, f_has_key}, 6750 {"hasmapto", 1, 2, f_hasmapto}, 6751 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 6752 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 6753 {"histadd", 2, 2, f_histadd}, 6754 {"histdel", 1, 2, f_histdel}, 6755 {"histget", 1, 2, f_histget}, 6756 {"histnr", 1, 1, f_histnr}, 6757 {"hlID", 1, 1, f_hlID}, 6758 {"hlexists", 1, 1, f_hlexists}, 6759 {"hostname", 0, 0, f_hostname}, 6760 {"iconv", 3, 3, f_iconv}, 6761 {"indent", 1, 1, f_indent}, 6762 {"index", 2, 4, f_index}, 6763 {"input", 1, 2, f_input}, 6764 {"inputdialog", 1, 3, f_inputdialog}, 6765 {"inputrestore", 0, 0, f_inputrestore}, 6766 {"inputsave", 0, 0, f_inputsave}, 6767 {"inputsecret", 1, 2, f_inputsecret}, 6768 {"insert", 2, 3, f_insert}, 6769 {"isdirectory", 1, 1, f_isdirectory}, 6770 {"islocked", 1, 1, f_islocked}, 6771 {"items", 1, 1, f_items}, 6772 {"join", 1, 2, f_join}, 6773 {"keys", 1, 1, f_keys}, 6774 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 6775 {"len", 1, 1, f_len}, 6776 {"libcall", 3, 3, f_libcall}, 6777 {"libcallnr", 3, 3, f_libcallnr}, 6778 {"line", 1, 1, f_line}, 6779 {"line2byte", 1, 1, f_line2byte}, 6780 {"lispindent", 1, 1, f_lispindent}, 6781 {"localtime", 0, 0, f_localtime}, 6782 {"map", 2, 2, f_map}, 6783 {"maparg", 1, 2, f_maparg}, 6784 {"mapcheck", 1, 2, f_mapcheck}, 6785 {"match", 2, 4, f_match}, 6786 {"matchend", 2, 4, f_matchend}, 6787 {"matchlist", 2, 4, f_matchlist}, 6788 {"matchstr", 2, 4, f_matchstr}, 6789 {"max", 1, 1, f_max}, 6790 {"min", 1, 1, f_min}, 6791 #ifdef vim_mkdir 6792 {"mkdir", 1, 3, f_mkdir}, 6793 #endif 6794 {"mode", 0, 0, f_mode}, 6795 {"nextnonblank", 1, 1, f_nextnonblank}, 6796 {"nr2char", 1, 1, f_nr2char}, 6797 {"prevnonblank", 1, 1, f_prevnonblank}, 6798 {"printf", 2, 19, f_printf}, 6799 {"range", 1, 3, f_range}, 6800 {"readfile", 1, 3, f_readfile}, 6801 {"remote_expr", 2, 3, f_remote_expr}, 6802 {"remote_foreground", 1, 1, f_remote_foreground}, 6803 {"remote_peek", 1, 2, f_remote_peek}, 6804 {"remote_read", 1, 1, f_remote_read}, 6805 {"remote_send", 2, 3, f_remote_send}, 6806 {"remove", 2, 3, f_remove}, 6807 {"rename", 2, 2, f_rename}, 6808 {"repeat", 2, 2, f_repeat}, 6809 {"resolve", 1, 1, f_resolve}, 6810 {"reverse", 1, 1, f_reverse}, 6811 {"search", 1, 2, f_search}, 6812 {"searchpair", 3, 5, f_searchpair}, 6813 {"server2client", 2, 2, f_server2client}, 6814 {"serverlist", 0, 0, f_serverlist}, 6815 {"setbufvar", 3, 3, f_setbufvar}, 6816 {"setcmdpos", 1, 1, f_setcmdpos}, 6817 {"setline", 2, 2, f_setline}, 6818 {"setqflist", 1, 2, f_setqflist}, 6819 {"setreg", 2, 3, f_setreg}, 6820 {"setwinvar", 3, 3, f_setwinvar}, 6821 {"simplify", 1, 1, f_simplify}, 6822 {"sort", 1, 2, f_sort}, 6823 {"soundfold", 1, 1, f_soundfold}, 6824 {"spellbadword", 0, 0, f_spellbadword}, 6825 {"spellsuggest", 1, 2, f_spellsuggest}, 6826 {"split", 1, 3, f_split}, 6827 #ifdef HAVE_STRFTIME 6828 {"strftime", 1, 2, f_strftime}, 6829 #endif 6830 {"stridx", 2, 3, f_stridx}, 6831 {"string", 1, 1, f_string}, 6832 {"strlen", 1, 1, f_strlen}, 6833 {"strpart", 2, 3, f_strpart}, 6834 {"strridx", 2, 3, f_strridx}, 6835 {"strtrans", 1, 1, f_strtrans}, 6836 {"submatch", 1, 1, f_submatch}, 6837 {"substitute", 4, 4, f_substitute}, 6838 {"synID", 3, 3, f_synID}, 6839 {"synIDattr", 2, 3, f_synIDattr}, 6840 {"synIDtrans", 1, 1, f_synIDtrans}, 6841 {"system", 1, 2, f_system}, 6842 {"taglist", 1, 1, f_taglist}, 6843 {"tempname", 0, 0, f_tempname}, 6844 {"tolower", 1, 1, f_tolower}, 6845 {"toupper", 1, 1, f_toupper}, 6846 {"tr", 3, 3, f_tr}, 6847 {"type", 1, 1, f_type}, 6848 {"values", 1, 1, f_values}, 6849 {"virtcol", 1, 1, f_virtcol}, 6850 {"visualmode", 0, 1, f_visualmode}, 6851 {"winbufnr", 1, 1, f_winbufnr}, 6852 {"wincol", 0, 0, f_wincol}, 6853 {"winheight", 1, 1, f_winheight}, 6854 {"winline", 0, 0, f_winline}, 6855 {"winnr", 0, 1, f_winnr}, 6856 {"winrestcmd", 0, 0, f_winrestcmd}, 6857 {"winwidth", 1, 1, f_winwidth}, 6858 {"writefile", 2, 3, f_writefile}, 6859 }; 6860 6861 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 6862 6863 /* 6864 * Function given to ExpandGeneric() to obtain the list of internal 6865 * or user defined function names. 6866 */ 6867 char_u * 6868 get_function_name(xp, idx) 6869 expand_T *xp; 6870 int idx; 6871 { 6872 static int intidx = -1; 6873 char_u *name; 6874 6875 if (idx == 0) 6876 intidx = -1; 6877 if (intidx < 0) 6878 { 6879 name = get_user_func_name(xp, idx); 6880 if (name != NULL) 6881 return name; 6882 } 6883 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 6884 { 6885 STRCPY(IObuff, functions[intidx].f_name); 6886 STRCAT(IObuff, "("); 6887 if (functions[intidx].f_max_argc == 0) 6888 STRCAT(IObuff, ")"); 6889 return IObuff; 6890 } 6891 6892 return NULL; 6893 } 6894 6895 /* 6896 * Function given to ExpandGeneric() to obtain the list of internal or 6897 * user defined variable or function names. 6898 */ 6899 /*ARGSUSED*/ 6900 char_u * 6901 get_expr_name(xp, idx) 6902 expand_T *xp; 6903 int idx; 6904 { 6905 static int intidx = -1; 6906 char_u *name; 6907 6908 if (idx == 0) 6909 intidx = -1; 6910 if (intidx < 0) 6911 { 6912 name = get_function_name(xp, idx); 6913 if (name != NULL) 6914 return name; 6915 } 6916 return get_user_var_name(xp, ++intidx); 6917 } 6918 6919 #endif /* FEAT_CMDL_COMPL */ 6920 6921 /* 6922 * Find internal function in table above. 6923 * Return index, or -1 if not found 6924 */ 6925 static int 6926 find_internal_func(name) 6927 char_u *name; /* name of the function */ 6928 { 6929 int first = 0; 6930 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 6931 int cmp; 6932 int x; 6933 6934 /* 6935 * Find the function name in the table. Binary search. 6936 */ 6937 while (first <= last) 6938 { 6939 x = first + ((unsigned)(last - first) >> 1); 6940 cmp = STRCMP(name, functions[x].f_name); 6941 if (cmp < 0) 6942 last = x - 1; 6943 else if (cmp > 0) 6944 first = x + 1; 6945 else 6946 return x; 6947 } 6948 return -1; 6949 } 6950 6951 /* 6952 * Check if "name" is a variable of type VAR_FUNC. If so, return the function 6953 * name it contains, otherwise return "name". 6954 */ 6955 static char_u * 6956 deref_func_name(name, lenp) 6957 char_u *name; 6958 int *lenp; 6959 { 6960 dictitem_T *v; 6961 int cc; 6962 6963 cc = name[*lenp]; 6964 name[*lenp] = NUL; 6965 v = find_var(name, NULL); 6966 name[*lenp] = cc; 6967 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 6968 { 6969 if (v->di_tv.vval.v_string == NULL) 6970 { 6971 *lenp = 0; 6972 return (char_u *)""; /* just in case */ 6973 } 6974 *lenp = STRLEN(v->di_tv.vval.v_string); 6975 return v->di_tv.vval.v_string; 6976 } 6977 6978 return name; 6979 } 6980 6981 /* 6982 * Allocate a variable for the result of a function. 6983 * Return OK or FAIL. 6984 */ 6985 static int 6986 get_func_tv(name, len, rettv, arg, firstline, lastline, doesrange, 6987 evaluate, selfdict) 6988 char_u *name; /* name of the function */ 6989 int len; /* length of "name" */ 6990 typval_T *rettv; 6991 char_u **arg; /* argument, pointing to the '(' */ 6992 linenr_T firstline; /* first line of range */ 6993 linenr_T lastline; /* last line of range */ 6994 int *doesrange; /* return: function handled range */ 6995 int evaluate; 6996 dict_T *selfdict; /* Dictionary for "self" */ 6997 { 6998 char_u *argp; 6999 int ret = OK; 7000 typval_T argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 7001 int argcount = 0; /* number of arguments found */ 7002 7003 /* 7004 * Get the arguments. 7005 */ 7006 argp = *arg; 7007 while (argcount < MAX_FUNC_ARGS) 7008 { 7009 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 7010 if (*argp == ')' || *argp == ',' || *argp == NUL) 7011 break; 7012 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 7013 { 7014 ret = FAIL; 7015 break; 7016 } 7017 ++argcount; 7018 if (*argp != ',') 7019 break; 7020 } 7021 if (*argp == ')') 7022 ++argp; 7023 else 7024 ret = FAIL; 7025 7026 if (ret == OK) 7027 ret = call_func(name, len, rettv, argcount, argvars, 7028 firstline, lastline, doesrange, evaluate, selfdict); 7029 else if (!aborting()) 7030 { 7031 if (argcount == MAX_FUNC_ARGS) 7032 emsg_funcname("E740: Too many arguments for function %s", name); 7033 else 7034 emsg_funcname("E116: Invalid arguments for function %s", name); 7035 } 7036 7037 while (--argcount >= 0) 7038 clear_tv(&argvars[argcount]); 7039 7040 *arg = skipwhite(argp); 7041 return ret; 7042 } 7043 7044 7045 /* 7046 * Call a function with its resolved parameters 7047 * Return OK or FAIL. 7048 */ 7049 static int 7050 call_func(name, len, rettv, argcount, argvars, firstline, lastline, 7051 doesrange, evaluate, selfdict) 7052 char_u *name; /* name of the function */ 7053 int len; /* length of "name" */ 7054 typval_T *rettv; /* return value goes here */ 7055 int argcount; /* number of "argvars" */ 7056 typval_T *argvars; /* vars for arguments */ 7057 linenr_T firstline; /* first line of range */ 7058 linenr_T lastline; /* last line of range */ 7059 int *doesrange; /* return: function handled range */ 7060 int evaluate; 7061 dict_T *selfdict; /* Dictionary for "self" */ 7062 { 7063 int ret = FAIL; 7064 #define ERROR_UNKNOWN 0 7065 #define ERROR_TOOMANY 1 7066 #define ERROR_TOOFEW 2 7067 #define ERROR_SCRIPT 3 7068 #define ERROR_DICT 4 7069 #define ERROR_NONE 5 7070 #define ERROR_OTHER 6 7071 int error = ERROR_NONE; 7072 int i; 7073 int llen; 7074 ufunc_T *fp; 7075 int cc; 7076 #define FLEN_FIXED 40 7077 char_u fname_buf[FLEN_FIXED + 1]; 7078 char_u *fname; 7079 7080 /* 7081 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 7082 * Change <SNR>123_name() to K_SNR 123_name(). 7083 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 7084 */ 7085 cc = name[len]; 7086 name[len] = NUL; 7087 llen = eval_fname_script(name); 7088 if (llen > 0) 7089 { 7090 fname_buf[0] = K_SPECIAL; 7091 fname_buf[1] = KS_EXTRA; 7092 fname_buf[2] = (int)KE_SNR; 7093 i = 3; 7094 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 7095 { 7096 if (current_SID <= 0) 7097 error = ERROR_SCRIPT; 7098 else 7099 { 7100 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 7101 i = (int)STRLEN(fname_buf); 7102 } 7103 } 7104 if (i + STRLEN(name + llen) < FLEN_FIXED) 7105 { 7106 STRCPY(fname_buf + i, name + llen); 7107 fname = fname_buf; 7108 } 7109 else 7110 { 7111 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 7112 if (fname == NULL) 7113 error = ERROR_OTHER; 7114 else 7115 { 7116 mch_memmove(fname, fname_buf, (size_t)i); 7117 STRCPY(fname + i, name + llen); 7118 } 7119 } 7120 } 7121 else 7122 fname = name; 7123 7124 *doesrange = FALSE; 7125 7126 7127 /* execute the function if no errors detected and executing */ 7128 if (evaluate && error == ERROR_NONE) 7129 { 7130 rettv->v_type = VAR_NUMBER; /* default is number rettv */ 7131 error = ERROR_UNKNOWN; 7132 7133 if (!builtin_function(fname)) 7134 { 7135 /* 7136 * User defined function. 7137 */ 7138 fp = find_func(fname); 7139 7140 #ifdef FEAT_AUTOCMD 7141 /* Trigger FuncUndefined event, may load the function. */ 7142 if (fp == NULL 7143 && apply_autocmds(EVENT_FUNCUNDEFINED, 7144 fname, fname, TRUE, NULL) 7145 && !aborting()) 7146 { 7147 /* executed an autocommand, search for the function again */ 7148 fp = find_func(fname); 7149 } 7150 #endif 7151 /* Try loading a package. */ 7152 if (fp == NULL && script_autoload(fname, TRUE) && !aborting()) 7153 { 7154 /* loaded a package, search for the function again */ 7155 fp = find_func(fname); 7156 } 7157 7158 if (fp != NULL) 7159 { 7160 if (fp->uf_flags & FC_RANGE) 7161 *doesrange = TRUE; 7162 if (argcount < fp->uf_args.ga_len) 7163 error = ERROR_TOOFEW; 7164 else if (!fp->uf_varargs && argcount > fp->uf_args.ga_len) 7165 error = ERROR_TOOMANY; 7166 else if ((fp->uf_flags & FC_DICT) && selfdict == NULL) 7167 error = ERROR_DICT; 7168 else 7169 { 7170 /* 7171 * Call the user function. 7172 * Save and restore search patterns, script variables and 7173 * redo buffer. 7174 */ 7175 save_search_patterns(); 7176 saveRedobuff(); 7177 ++fp->uf_calls; 7178 call_user_func(fp, argcount, argvars, rettv, 7179 firstline, lastline, 7180 (fp->uf_flags & FC_DICT) ? selfdict : NULL); 7181 if (--fp->uf_calls <= 0 && isdigit(*fp->uf_name) 7182 && fp->uf_refcount <= 0) 7183 /* Function was unreferenced while being used, free it 7184 * now. */ 7185 func_free(fp); 7186 restoreRedobuff(); 7187 restore_search_patterns(); 7188 error = ERROR_NONE; 7189 } 7190 } 7191 } 7192 else 7193 { 7194 /* 7195 * Find the function name in the table, call its implementation. 7196 */ 7197 i = find_internal_func(fname); 7198 if (i >= 0) 7199 { 7200 if (argcount < functions[i].f_min_argc) 7201 error = ERROR_TOOFEW; 7202 else if (argcount > functions[i].f_max_argc) 7203 error = ERROR_TOOMANY; 7204 else 7205 { 7206 argvars[argcount].v_type = VAR_UNKNOWN; 7207 functions[i].f_func(argvars, rettv); 7208 error = ERROR_NONE; 7209 } 7210 } 7211 } 7212 /* 7213 * The function call (or "FuncUndefined" autocommand sequence) might 7214 * have been aborted by an error, an interrupt, or an explicitly thrown 7215 * exception that has not been caught so far. This situation can be 7216 * tested for by calling aborting(). For an error in an internal 7217 * function or for the "E132" error in call_user_func(), however, the 7218 * throw point at which the "force_abort" flag (temporarily reset by 7219 * emsg()) is normally updated has not been reached yet. We need to 7220 * update that flag first to make aborting() reliable. 7221 */ 7222 update_force_abort(); 7223 } 7224 if (error == ERROR_NONE) 7225 ret = OK; 7226 7227 /* 7228 * Report an error unless the argument evaluation or function call has been 7229 * cancelled due to an aborting error, an interrupt, or an exception. 7230 */ 7231 if (!aborting()) 7232 { 7233 switch (error) 7234 { 7235 case ERROR_UNKNOWN: 7236 emsg_funcname("E117: Unknown function: %s", name); 7237 break; 7238 case ERROR_TOOMANY: 7239 emsg_funcname(e_toomanyarg, name); 7240 break; 7241 case ERROR_TOOFEW: 7242 emsg_funcname("E119: Not enough arguments for function: %s", 7243 name); 7244 break; 7245 case ERROR_SCRIPT: 7246 emsg_funcname("E120: Using <SID> not in a script context: %s", 7247 name); 7248 break; 7249 case ERROR_DICT: 7250 emsg_funcname("E725: Calling dict function without Dictionary: %s", 7251 name); 7252 break; 7253 } 7254 } 7255 7256 name[len] = cc; 7257 if (fname != name && fname != fname_buf) 7258 vim_free(fname); 7259 7260 return ret; 7261 } 7262 7263 /* 7264 * Give an error message with a function name. Handle <SNR> things. 7265 */ 7266 static void 7267 emsg_funcname(msg, name) 7268 char *msg; 7269 char_u *name; 7270 { 7271 char_u *p; 7272 7273 if (*name == K_SPECIAL) 7274 p = concat_str((char_u *)"<SNR>", name + 3); 7275 else 7276 p = name; 7277 EMSG2(_(msg), p); 7278 if (p != name) 7279 vim_free(p); 7280 } 7281 7282 /********************************************* 7283 * Implementation of the built-in functions 7284 */ 7285 7286 /* 7287 * "add(list, item)" function 7288 */ 7289 static void 7290 f_add(argvars, rettv) 7291 typval_T *argvars; 7292 typval_T *rettv; 7293 { 7294 list_T *l; 7295 7296 rettv->vval.v_number = 1; /* Default: Failed */ 7297 if (argvars[0].v_type == VAR_LIST) 7298 { 7299 if ((l = argvars[0].vval.v_list) != NULL 7300 && !tv_check_lock(l->lv_lock, (char_u *)"add()") 7301 && list_append_tv(l, &argvars[1]) == OK) 7302 copy_tv(&argvars[0], rettv); 7303 } 7304 else 7305 EMSG(_(e_listreq)); 7306 } 7307 7308 /* 7309 * "append(lnum, string/list)" function 7310 */ 7311 static void 7312 f_append(argvars, rettv) 7313 typval_T *argvars; 7314 typval_T *rettv; 7315 { 7316 long lnum; 7317 char_u *line; 7318 list_T *l = NULL; 7319 listitem_T *li = NULL; 7320 typval_T *tv; 7321 long added = 0; 7322 7323 lnum = get_tv_lnum(argvars); 7324 if (lnum >= 0 7325 && lnum <= curbuf->b_ml.ml_line_count 7326 && u_save(lnum, lnum + 1) == OK) 7327 { 7328 if (argvars[1].v_type == VAR_LIST) 7329 { 7330 l = argvars[1].vval.v_list; 7331 if (l == NULL) 7332 return; 7333 li = l->lv_first; 7334 } 7335 rettv->vval.v_number = 0; /* Default: Success */ 7336 for (;;) 7337 { 7338 if (l == NULL) 7339 tv = &argvars[1]; /* append a string */ 7340 else if (li == NULL) 7341 break; /* end of list */ 7342 else 7343 tv = &li->li_tv; /* append item from list */ 7344 line = get_tv_string_chk(tv); 7345 if (line == NULL) /* type error */ 7346 { 7347 rettv->vval.v_number = 1; /* Failed */ 7348 break; 7349 } 7350 ml_append(lnum + added, line, (colnr_T)0, FALSE); 7351 ++added; 7352 if (l == NULL) 7353 break; 7354 li = li->li_next; 7355 } 7356 7357 appended_lines_mark(lnum, added); 7358 if (curwin->w_cursor.lnum > lnum) 7359 curwin->w_cursor.lnum += added; 7360 } 7361 else 7362 rettv->vval.v_number = 1; /* Failed */ 7363 } 7364 7365 /* 7366 * "argc()" function 7367 */ 7368 /* ARGSUSED */ 7369 static void 7370 f_argc(argvars, rettv) 7371 typval_T *argvars; 7372 typval_T *rettv; 7373 { 7374 rettv->vval.v_number = ARGCOUNT; 7375 } 7376 7377 /* 7378 * "argidx()" function 7379 */ 7380 /* ARGSUSED */ 7381 static void 7382 f_argidx(argvars, rettv) 7383 typval_T *argvars; 7384 typval_T *rettv; 7385 { 7386 rettv->vval.v_number = curwin->w_arg_idx; 7387 } 7388 7389 /* 7390 * "argv(nr)" function 7391 */ 7392 static void 7393 f_argv(argvars, rettv) 7394 typval_T *argvars; 7395 typval_T *rettv; 7396 { 7397 int idx; 7398 7399 idx = get_tv_number_chk(&argvars[0], NULL); 7400 if (idx >= 0 && idx < ARGCOUNT) 7401 rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx])); 7402 else 7403 rettv->vval.v_string = NULL; 7404 rettv->v_type = VAR_STRING; 7405 } 7406 7407 /* 7408 * "browse(save, title, initdir, default)" function 7409 */ 7410 /* ARGSUSED */ 7411 static void 7412 f_browse(argvars, rettv) 7413 typval_T *argvars; 7414 typval_T *rettv; 7415 { 7416 #ifdef FEAT_BROWSE 7417 int save; 7418 char_u *title; 7419 char_u *initdir; 7420 char_u *defname; 7421 char_u buf[NUMBUFLEN]; 7422 char_u buf2[NUMBUFLEN]; 7423 int error = FALSE; 7424 7425 save = get_tv_number_chk(&argvars[0], &error); 7426 title = get_tv_string_chk(&argvars[1]); 7427 initdir = get_tv_string_buf_chk(&argvars[2], buf); 7428 defname = get_tv_string_buf_chk(&argvars[3], buf2); 7429 7430 if (error || title == NULL || initdir == NULL || defname == NULL) 7431 rettv->vval.v_string = NULL; 7432 else 7433 rettv->vval.v_string = 7434 do_browse(save ? BROWSE_SAVE : 0, 7435 title, defname, NULL, initdir, NULL, curbuf); 7436 #else 7437 rettv->vval.v_string = NULL; 7438 #endif 7439 rettv->v_type = VAR_STRING; 7440 } 7441 7442 /* 7443 * "browsedir(title, initdir)" function 7444 */ 7445 /* ARGSUSED */ 7446 static void 7447 f_browsedir(argvars, rettv) 7448 typval_T *argvars; 7449 typval_T *rettv; 7450 { 7451 #ifdef FEAT_BROWSE 7452 char_u *title; 7453 char_u *initdir; 7454 char_u buf[NUMBUFLEN]; 7455 7456 title = get_tv_string_chk(&argvars[0]); 7457 initdir = get_tv_string_buf_chk(&argvars[1], buf); 7458 7459 if (title == NULL || initdir == NULL) 7460 rettv->vval.v_string = NULL; 7461 else 7462 rettv->vval.v_string = do_browse(BROWSE_DIR, 7463 title, NULL, NULL, initdir, NULL, curbuf); 7464 #else 7465 rettv->vval.v_string = NULL; 7466 #endif 7467 rettv->v_type = VAR_STRING; 7468 } 7469 7470 static buf_T *find_buffer __ARGS((typval_T *avar)); 7471 7472 /* 7473 * Find a buffer by number or exact name. 7474 */ 7475 static buf_T * 7476 find_buffer(avar) 7477 typval_T *avar; 7478 { 7479 buf_T *buf = NULL; 7480 7481 if (avar->v_type == VAR_NUMBER) 7482 buf = buflist_findnr((int)avar->vval.v_number); 7483 else if (avar->v_type == VAR_STRING && avar->vval.v_string != NULL) 7484 { 7485 buf = buflist_findname_exp(avar->vval.v_string); 7486 if (buf == NULL) 7487 { 7488 /* No full path name match, try a match with a URL or a "nofile" 7489 * buffer, these don't use the full path. */ 7490 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 7491 if (buf->b_fname != NULL 7492 && (path_with_url(buf->b_fname) 7493 #ifdef FEAT_QUICKFIX 7494 || bt_nofile(buf) 7495 #endif 7496 ) 7497 && STRCMP(buf->b_fname, avar->vval.v_string) == 0) 7498 break; 7499 } 7500 } 7501 return buf; 7502 } 7503 7504 /* 7505 * "bufexists(expr)" function 7506 */ 7507 static void 7508 f_bufexists(argvars, rettv) 7509 typval_T *argvars; 7510 typval_T *rettv; 7511 { 7512 rettv->vval.v_number = (find_buffer(&argvars[0]) != NULL); 7513 } 7514 7515 /* 7516 * "buflisted(expr)" function 7517 */ 7518 static void 7519 f_buflisted(argvars, rettv) 7520 typval_T *argvars; 7521 typval_T *rettv; 7522 { 7523 buf_T *buf; 7524 7525 buf = find_buffer(&argvars[0]); 7526 rettv->vval.v_number = (buf != NULL && buf->b_p_bl); 7527 } 7528 7529 /* 7530 * "bufloaded(expr)" function 7531 */ 7532 static void 7533 f_bufloaded(argvars, rettv) 7534 typval_T *argvars; 7535 typval_T *rettv; 7536 { 7537 buf_T *buf; 7538 7539 buf = find_buffer(&argvars[0]); 7540 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 7541 } 7542 7543 static buf_T *get_buf_tv __ARGS((typval_T *tv)); 7544 7545 /* 7546 * Get buffer by number or pattern. 7547 */ 7548 static buf_T * 7549 get_buf_tv(tv) 7550 typval_T *tv; 7551 { 7552 char_u *name = tv->vval.v_string; 7553 int save_magic; 7554 char_u *save_cpo; 7555 buf_T *buf; 7556 7557 if (tv->v_type == VAR_NUMBER) 7558 return buflist_findnr((int)tv->vval.v_number); 7559 if (tv->v_type != VAR_STRING) 7560 return NULL; 7561 if (name == NULL || *name == NUL) 7562 return curbuf; 7563 if (name[0] == '$' && name[1] == NUL) 7564 return lastbuf; 7565 7566 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 7567 save_magic = p_magic; 7568 p_magic = TRUE; 7569 save_cpo = p_cpo; 7570 p_cpo = (char_u *)""; 7571 7572 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 7573 TRUE, FALSE)); 7574 7575 p_magic = save_magic; 7576 p_cpo = save_cpo; 7577 7578 /* If not found, try expanding the name, like done for bufexists(). */ 7579 if (buf == NULL) 7580 buf = find_buffer(tv); 7581 7582 return buf; 7583 } 7584 7585 /* 7586 * "bufname(expr)" function 7587 */ 7588 static void 7589 f_bufname(argvars, rettv) 7590 typval_T *argvars; 7591 typval_T *rettv; 7592 { 7593 buf_T *buf; 7594 7595 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7596 ++emsg_off; 7597 buf = get_buf_tv(&argvars[0]); 7598 rettv->v_type = VAR_STRING; 7599 if (buf != NULL && buf->b_fname != NULL) 7600 rettv->vval.v_string = vim_strsave(buf->b_fname); 7601 else 7602 rettv->vval.v_string = NULL; 7603 --emsg_off; 7604 } 7605 7606 /* 7607 * "bufnr(expr)" function 7608 */ 7609 static void 7610 f_bufnr(argvars, rettv) 7611 typval_T *argvars; 7612 typval_T *rettv; 7613 { 7614 buf_T *buf; 7615 7616 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7617 ++emsg_off; 7618 buf = get_buf_tv(&argvars[0]); 7619 if (buf != NULL) 7620 rettv->vval.v_number = buf->b_fnum; 7621 else 7622 rettv->vval.v_number = -1; 7623 --emsg_off; 7624 } 7625 7626 /* 7627 * "bufwinnr(nr)" function 7628 */ 7629 static void 7630 f_bufwinnr(argvars, rettv) 7631 typval_T *argvars; 7632 typval_T *rettv; 7633 { 7634 #ifdef FEAT_WINDOWS 7635 win_T *wp; 7636 int winnr = 0; 7637 #endif 7638 buf_T *buf; 7639 7640 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 7641 ++emsg_off; 7642 buf = get_buf_tv(&argvars[0]); 7643 #ifdef FEAT_WINDOWS 7644 for (wp = firstwin; wp; wp = wp->w_next) 7645 { 7646 ++winnr; 7647 if (wp->w_buffer == buf) 7648 break; 7649 } 7650 rettv->vval.v_number = (wp != NULL ? winnr : -1); 7651 #else 7652 rettv->vval.v_number = (curwin->w_buffer == buf ? 1 : -1); 7653 #endif 7654 --emsg_off; 7655 } 7656 7657 /* 7658 * "byte2line(byte)" function 7659 */ 7660 /*ARGSUSED*/ 7661 static void 7662 f_byte2line(argvars, rettv) 7663 typval_T *argvars; 7664 typval_T *rettv; 7665 { 7666 #ifndef FEAT_BYTEOFF 7667 rettv->vval.v_number = -1; 7668 #else 7669 long boff = 0; 7670 7671 boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ 7672 if (boff < 0) 7673 rettv->vval.v_number = -1; 7674 else 7675 rettv->vval.v_number = ml_find_line_or_offset(curbuf, 7676 (linenr_T)0, &boff); 7677 #endif 7678 } 7679 7680 /* 7681 * "byteidx()" function 7682 */ 7683 /*ARGSUSED*/ 7684 static void 7685 f_byteidx(argvars, rettv) 7686 typval_T *argvars; 7687 typval_T *rettv; 7688 { 7689 #ifdef FEAT_MBYTE 7690 char_u *t; 7691 #endif 7692 char_u *str; 7693 long idx; 7694 7695 str = get_tv_string_chk(&argvars[0]); 7696 idx = get_tv_number_chk(&argvars[1], NULL); 7697 rettv->vval.v_number = -1; 7698 if (str == NULL || idx < 0) 7699 return; 7700 7701 #ifdef FEAT_MBYTE 7702 t = str; 7703 for ( ; idx > 0; idx--) 7704 { 7705 if (*t == NUL) /* EOL reached */ 7706 return; 7707 t += mb_ptr2len_check(t); 7708 } 7709 rettv->vval.v_number = t - str; 7710 #else 7711 if (idx <= STRLEN(str)) 7712 rettv->vval.v_number = idx; 7713 #endif 7714 } 7715 7716 /* 7717 * "call(func, arglist)" function 7718 */ 7719 static void 7720 f_call(argvars, rettv) 7721 typval_T *argvars; 7722 typval_T *rettv; 7723 { 7724 char_u *func; 7725 typval_T argv[MAX_FUNC_ARGS]; 7726 int argc = 0; 7727 listitem_T *item; 7728 int dummy; 7729 dict_T *selfdict = NULL; 7730 7731 rettv->vval.v_number = 0; 7732 if (argvars[1].v_type != VAR_LIST) 7733 { 7734 EMSG(_(e_listreq)); 7735 return; 7736 } 7737 if (argvars[1].vval.v_list == NULL) 7738 return; 7739 7740 if (argvars[0].v_type == VAR_FUNC) 7741 func = argvars[0].vval.v_string; 7742 else 7743 func = get_tv_string(&argvars[0]); 7744 if (*func == NUL) 7745 return; /* type error or empty name */ 7746 7747 if (argvars[2].v_type != VAR_UNKNOWN) 7748 { 7749 if (argvars[2].v_type != VAR_DICT) 7750 { 7751 EMSG(_(e_dictreq)); 7752 return; 7753 } 7754 selfdict = argvars[2].vval.v_dict; 7755 } 7756 7757 for (item = argvars[1].vval.v_list->lv_first; item != NULL; 7758 item = item->li_next) 7759 { 7760 if (argc == MAX_FUNC_ARGS) 7761 { 7762 EMSG(_("E699: Too many arguments")); 7763 break; 7764 } 7765 /* Make a copy of each argument. This is needed to be able to set 7766 * v_lock to VAR_FIXED in the copy without changing the original list. 7767 */ 7768 copy_tv(&item->li_tv, &argv[argc++]); 7769 } 7770 7771 if (item == NULL) 7772 (void)call_func(func, STRLEN(func), rettv, argc, argv, 7773 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 7774 &dummy, TRUE, selfdict); 7775 7776 /* Free the arguments. */ 7777 while (argc > 0) 7778 clear_tv(&argv[--argc]); 7779 } 7780 7781 /* 7782 * "char2nr(string)" function 7783 */ 7784 static void 7785 f_char2nr(argvars, rettv) 7786 typval_T *argvars; 7787 typval_T *rettv; 7788 { 7789 #ifdef FEAT_MBYTE 7790 if (has_mbyte) 7791 rettv->vval.v_number = (*mb_ptr2char)(get_tv_string(&argvars[0])); 7792 else 7793 #endif 7794 rettv->vval.v_number = get_tv_string(&argvars[0])[0]; 7795 } 7796 7797 /* 7798 * "cindent(lnum)" function 7799 */ 7800 static void 7801 f_cindent(argvars, rettv) 7802 typval_T *argvars; 7803 typval_T *rettv; 7804 { 7805 #ifdef FEAT_CINDENT 7806 pos_T pos; 7807 linenr_T lnum; 7808 7809 pos = curwin->w_cursor; 7810 lnum = get_tv_lnum(argvars); 7811 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 7812 { 7813 curwin->w_cursor.lnum = lnum; 7814 rettv->vval.v_number = get_c_indent(); 7815 curwin->w_cursor = pos; 7816 } 7817 else 7818 #endif 7819 rettv->vval.v_number = -1; 7820 } 7821 7822 /* 7823 * "col(string)" function 7824 */ 7825 static void 7826 f_col(argvars, rettv) 7827 typval_T *argvars; 7828 typval_T *rettv; 7829 { 7830 colnr_T col = 0; 7831 pos_T *fp; 7832 7833 fp = var2fpos(&argvars[0], FALSE); 7834 if (fp != NULL) 7835 { 7836 if (fp->col == MAXCOL) 7837 { 7838 /* '> can be MAXCOL, get the length of the line then */ 7839 if (fp->lnum <= curbuf->b_ml.ml_line_count) 7840 col = STRLEN(ml_get(fp->lnum)) + 1; 7841 else 7842 col = MAXCOL; 7843 } 7844 else 7845 { 7846 col = fp->col + 1; 7847 #ifdef FEAT_VIRTUALEDIT 7848 /* col(".") when the cursor is on the NUL at the end of the line 7849 * because of "coladd" can be seen as an extra column. */ 7850 if (virtual_active() && fp == &curwin->w_cursor) 7851 { 7852 char_u *p = ml_get_cursor(); 7853 7854 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 7855 curwin->w_virtcol - curwin->w_cursor.coladd)) 7856 { 7857 # ifdef FEAT_MBYTE 7858 int l; 7859 7860 if (*p != NUL && p[(l = (*mb_ptr2len_check)(p))] == NUL) 7861 col += l; 7862 # else 7863 if (*p != NUL && p[1] == NUL) 7864 ++col; 7865 # endif 7866 } 7867 } 7868 #endif 7869 } 7870 } 7871 rettv->vval.v_number = col; 7872 } 7873 7874 /* 7875 * "confirm(message, buttons[, default [, type]])" function 7876 */ 7877 /*ARGSUSED*/ 7878 static void 7879 f_confirm(argvars, rettv) 7880 typval_T *argvars; 7881 typval_T *rettv; 7882 { 7883 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 7884 char_u *message; 7885 char_u *buttons = NULL; 7886 char_u buf[NUMBUFLEN]; 7887 char_u buf2[NUMBUFLEN]; 7888 int def = 1; 7889 int type = VIM_GENERIC; 7890 char_u *typestr; 7891 int error = FALSE; 7892 7893 message = get_tv_string_chk(&argvars[0]); 7894 if (message == NULL) 7895 error = TRUE; 7896 if (argvars[1].v_type != VAR_UNKNOWN) 7897 { 7898 buttons = get_tv_string_buf_chk(&argvars[1], buf); 7899 if (buttons == NULL) 7900 error = TRUE; 7901 if (argvars[2].v_type != VAR_UNKNOWN) 7902 { 7903 def = get_tv_number_chk(&argvars[2], &error); 7904 if (argvars[3].v_type != VAR_UNKNOWN) 7905 { 7906 typestr = get_tv_string_buf_chk(&argvars[3], buf2); 7907 if (typestr == NULL) 7908 error = TRUE; 7909 else 7910 { 7911 switch (TOUPPER_ASC(*typestr)) 7912 { 7913 case 'E': type = VIM_ERROR; break; 7914 case 'Q': type = VIM_QUESTION; break; 7915 case 'I': type = VIM_INFO; break; 7916 case 'W': type = VIM_WARNING; break; 7917 case 'G': type = VIM_GENERIC; break; 7918 } 7919 } 7920 } 7921 } 7922 } 7923 7924 if (buttons == NULL || *buttons == NUL) 7925 buttons = (char_u *)_("&Ok"); 7926 7927 if (error) 7928 rettv->vval.v_number = 0; 7929 else 7930 rettv->vval.v_number = do_dialog(type, NULL, message, buttons, 7931 def, NULL); 7932 #else 7933 rettv->vval.v_number = 0; 7934 #endif 7935 } 7936 7937 /* 7938 * "copy()" function 7939 */ 7940 static void 7941 f_copy(argvars, rettv) 7942 typval_T *argvars; 7943 typval_T *rettv; 7944 { 7945 item_copy(&argvars[0], rettv, FALSE, 0); 7946 } 7947 7948 /* 7949 * "count()" function 7950 */ 7951 static void 7952 f_count(argvars, rettv) 7953 typval_T *argvars; 7954 typval_T *rettv; 7955 { 7956 long n = 0; 7957 int ic = FALSE; 7958 7959 if (argvars[0].v_type == VAR_LIST) 7960 { 7961 listitem_T *li; 7962 list_T *l; 7963 long idx; 7964 7965 if ((l = argvars[0].vval.v_list) != NULL) 7966 { 7967 li = l->lv_first; 7968 if (argvars[2].v_type != VAR_UNKNOWN) 7969 { 7970 int error = FALSE; 7971 7972 ic = get_tv_number_chk(&argvars[2], &error); 7973 if (argvars[3].v_type != VAR_UNKNOWN) 7974 { 7975 idx = get_tv_number_chk(&argvars[3], &error); 7976 if (!error) 7977 { 7978 li = list_find(l, idx); 7979 if (li == NULL) 7980 EMSGN(_(e_listidx), idx); 7981 } 7982 } 7983 if (error) 7984 li = NULL; 7985 } 7986 7987 for ( ; li != NULL; li = li->li_next) 7988 if (tv_equal(&li->li_tv, &argvars[1], ic)) 7989 ++n; 7990 } 7991 } 7992 else if (argvars[0].v_type == VAR_DICT) 7993 { 7994 int todo; 7995 dict_T *d; 7996 hashitem_T *hi; 7997 7998 if ((d = argvars[0].vval.v_dict) != NULL) 7999 { 8000 int error = FALSE; 8001 8002 if (argvars[2].v_type != VAR_UNKNOWN) 8003 { 8004 ic = get_tv_number_chk(&argvars[2], &error); 8005 if (argvars[3].v_type != VAR_UNKNOWN) 8006 EMSG(_(e_invarg)); 8007 } 8008 8009 todo = error ? 0 : d->dv_hashtab.ht_used; 8010 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 8011 { 8012 if (!HASHITEM_EMPTY(hi)) 8013 { 8014 --todo; 8015 if (tv_equal(&HI2DI(hi)->di_tv, &argvars[1], ic)) 8016 ++n; 8017 } 8018 } 8019 } 8020 } 8021 else 8022 EMSG2(_(e_listdictarg), "count()"); 8023 rettv->vval.v_number = n; 8024 } 8025 8026 /* 8027 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 8028 * 8029 * Checks the existence of a cscope connection. 8030 */ 8031 /*ARGSUSED*/ 8032 static void 8033 f_cscope_connection(argvars, rettv) 8034 typval_T *argvars; 8035 typval_T *rettv; 8036 { 8037 #ifdef FEAT_CSCOPE 8038 int num = 0; 8039 char_u *dbpath = NULL; 8040 char_u *prepend = NULL; 8041 char_u buf[NUMBUFLEN]; 8042 8043 if (argvars[0].v_type != VAR_UNKNOWN 8044 && argvars[1].v_type != VAR_UNKNOWN) 8045 { 8046 num = (int)get_tv_number(&argvars[0]); 8047 dbpath = get_tv_string(&argvars[1]); 8048 if (argvars[2].v_type != VAR_UNKNOWN) 8049 prepend = get_tv_string_buf(&argvars[2], buf); 8050 } 8051 8052 rettv->vval.v_number = cs_connection(num, dbpath, prepend); 8053 #else 8054 rettv->vval.v_number = 0; 8055 #endif 8056 } 8057 8058 /* 8059 * "cursor(lnum, col)" function 8060 * 8061 * Moves the cursor to the specified line and column 8062 */ 8063 /*ARGSUSED*/ 8064 static void 8065 f_cursor(argvars, rettv) 8066 typval_T *argvars; 8067 typval_T *rettv; 8068 { 8069 long line, col; 8070 8071 line = get_tv_lnum(argvars); 8072 col = get_tv_number_chk(&argvars[1], NULL); 8073 if (line < 0 || col < 0) 8074 return; /* type error; errmsg already given */ 8075 if (line > 0) 8076 curwin->w_cursor.lnum = line; 8077 if (col > 0) 8078 curwin->w_cursor.col = col - 1; 8079 #ifdef FEAT_VIRTUALEDIT 8080 curwin->w_cursor.coladd = 0; 8081 #endif 8082 8083 /* Make sure the cursor is in a valid position. */ 8084 check_cursor(); 8085 #ifdef FEAT_MBYTE 8086 /* Correct cursor for multi-byte character. */ 8087 if (has_mbyte) 8088 mb_adjust_cursor(); 8089 #endif 8090 8091 curwin->w_set_curswant = TRUE; 8092 } 8093 8094 /* 8095 * "deepcopy()" function 8096 */ 8097 static void 8098 f_deepcopy(argvars, rettv) 8099 typval_T *argvars; 8100 typval_T *rettv; 8101 { 8102 int noref = 0; 8103 8104 if (argvars[1].v_type != VAR_UNKNOWN) 8105 noref = get_tv_number_chk(&argvars[1], NULL); 8106 if (noref < 0 || noref > 1) 8107 EMSG(_(e_invarg)); 8108 else 8109 item_copy(&argvars[0], rettv, TRUE, noref == 0 ? ++current_copyID : 0); 8110 } 8111 8112 /* 8113 * "delete()" function 8114 */ 8115 static void 8116 f_delete(argvars, rettv) 8117 typval_T *argvars; 8118 typval_T *rettv; 8119 { 8120 if (check_restricted() || check_secure()) 8121 rettv->vval.v_number = -1; 8122 else 8123 rettv->vval.v_number = mch_remove(get_tv_string(&argvars[0])); 8124 } 8125 8126 /* 8127 * "did_filetype()" function 8128 */ 8129 /*ARGSUSED*/ 8130 static void 8131 f_did_filetype(argvars, rettv) 8132 typval_T *argvars; 8133 typval_T *rettv; 8134 { 8135 #ifdef FEAT_AUTOCMD 8136 rettv->vval.v_number = did_filetype; 8137 #else 8138 rettv->vval.v_number = 0; 8139 #endif 8140 } 8141 8142 /* 8143 * "diff_filler()" function 8144 */ 8145 /*ARGSUSED*/ 8146 static void 8147 f_diff_filler(argvars, rettv) 8148 typval_T *argvars; 8149 typval_T *rettv; 8150 { 8151 #ifdef FEAT_DIFF 8152 rettv->vval.v_number = diff_check_fill(curwin, get_tv_lnum(argvars)); 8153 #endif 8154 } 8155 8156 /* 8157 * "diff_hlID()" function 8158 */ 8159 /*ARGSUSED*/ 8160 static void 8161 f_diff_hlID(argvars, rettv) 8162 typval_T *argvars; 8163 typval_T *rettv; 8164 { 8165 #ifdef FEAT_DIFF 8166 linenr_T lnum = get_tv_lnum(argvars); 8167 static linenr_T prev_lnum = 0; 8168 static int changedtick = 0; 8169 static int fnum = 0; 8170 static int change_start = 0; 8171 static int change_end = 0; 8172 static enum hlf_value hlID = 0; 8173 int filler_lines; 8174 int col; 8175 8176 if (lnum < 0) /* ignore type error in {lnum} arg */ 8177 lnum = 0; 8178 if (lnum != prev_lnum 8179 || changedtick != curbuf->b_changedtick 8180 || fnum != curbuf->b_fnum) 8181 { 8182 /* New line, buffer, change: need to get the values. */ 8183 filler_lines = diff_check(curwin, lnum); 8184 if (filler_lines < 0) 8185 { 8186 if (filler_lines == -1) 8187 { 8188 change_start = MAXCOL; 8189 change_end = -1; 8190 if (diff_find_change(curwin, lnum, &change_start, &change_end)) 8191 hlID = HLF_ADD; /* added line */ 8192 else 8193 hlID = HLF_CHD; /* changed line */ 8194 } 8195 else 8196 hlID = HLF_ADD; /* added line */ 8197 } 8198 else 8199 hlID = (enum hlf_value)0; 8200 prev_lnum = lnum; 8201 changedtick = curbuf->b_changedtick; 8202 fnum = curbuf->b_fnum; 8203 } 8204 8205 if (hlID == HLF_CHD || hlID == HLF_TXD) 8206 { 8207 col = get_tv_number(&argvars[1]) - 1; /* ignore type error in {col} */ 8208 if (col >= change_start && col <= change_end) 8209 hlID = HLF_TXD; /* changed text */ 8210 else 8211 hlID = HLF_CHD; /* changed line */ 8212 } 8213 rettv->vval.v_number = hlID == (enum hlf_value)0 ? 0 : (int)hlID; 8214 #endif 8215 } 8216 8217 /* 8218 * "empty({expr})" function 8219 */ 8220 static void 8221 f_empty(argvars, rettv) 8222 typval_T *argvars; 8223 typval_T *rettv; 8224 { 8225 int n; 8226 8227 switch (argvars[0].v_type) 8228 { 8229 case VAR_STRING: 8230 case VAR_FUNC: 8231 n = argvars[0].vval.v_string == NULL 8232 || *argvars[0].vval.v_string == NUL; 8233 break; 8234 case VAR_NUMBER: 8235 n = argvars[0].vval.v_number == 0; 8236 break; 8237 case VAR_LIST: 8238 n = argvars[0].vval.v_list == NULL 8239 || argvars[0].vval.v_list->lv_first == NULL; 8240 break; 8241 case VAR_DICT: 8242 n = argvars[0].vval.v_dict == NULL 8243 || argvars[0].vval.v_dict->dv_hashtab.ht_used == 0; 8244 break; 8245 default: 8246 EMSG2(_(e_intern2), "f_empty()"); 8247 n = 0; 8248 } 8249 8250 rettv->vval.v_number = n; 8251 } 8252 8253 /* 8254 * "escape({string}, {chars})" function 8255 */ 8256 static void 8257 f_escape(argvars, rettv) 8258 typval_T *argvars; 8259 typval_T *rettv; 8260 { 8261 char_u buf[NUMBUFLEN]; 8262 8263 rettv->vval.v_string = vim_strsave_escaped(get_tv_string(&argvars[0]), 8264 get_tv_string_buf(&argvars[1], buf)); 8265 rettv->v_type = VAR_STRING; 8266 } 8267 8268 /* 8269 * "eval()" function 8270 */ 8271 /*ARGSUSED*/ 8272 static void 8273 f_eval(argvars, rettv) 8274 typval_T *argvars; 8275 typval_T *rettv; 8276 { 8277 char_u *s; 8278 8279 s = get_tv_string_chk(&argvars[0]); 8280 if (s != NULL) 8281 s = skipwhite(s); 8282 8283 if (s == NULL || eval1(&s, rettv, TRUE) == FAIL) 8284 { 8285 rettv->v_type = VAR_NUMBER; 8286 rettv->vval.v_number = 0; 8287 } 8288 else if (*s != NUL) 8289 EMSG(_(e_trailing)); 8290 } 8291 8292 /* 8293 * "eventhandler()" function 8294 */ 8295 /*ARGSUSED*/ 8296 static void 8297 f_eventhandler(argvars, rettv) 8298 typval_T *argvars; 8299 typval_T *rettv; 8300 { 8301 rettv->vval.v_number = vgetc_busy; 8302 } 8303 8304 /* 8305 * "executable()" function 8306 */ 8307 static void 8308 f_executable(argvars, rettv) 8309 typval_T *argvars; 8310 typval_T *rettv; 8311 { 8312 rettv->vval.v_number = mch_can_exe(get_tv_string(&argvars[0])); 8313 } 8314 8315 /* 8316 * "exists()" function 8317 */ 8318 static void 8319 f_exists(argvars, rettv) 8320 typval_T *argvars; 8321 typval_T *rettv; 8322 { 8323 char_u *p; 8324 char_u *name; 8325 int n = FALSE; 8326 int len = 0; 8327 8328 p = get_tv_string(&argvars[0]); 8329 if (*p == '$') /* environment variable */ 8330 { 8331 /* first try "normal" environment variables (fast) */ 8332 if (mch_getenv(p + 1) != NULL) 8333 n = TRUE; 8334 else 8335 { 8336 /* try expanding things like $VIM and ${HOME} */ 8337 p = expand_env_save(p); 8338 if (p != NULL && *p != '$') 8339 n = TRUE; 8340 vim_free(p); 8341 } 8342 } 8343 else if (*p == '&' || *p == '+') /* option */ 8344 n = (get_option_tv(&p, NULL, TRUE) == OK); 8345 else if (*p == '*') /* internal or user defined function */ 8346 { 8347 n = function_exists(p + 1); 8348 } 8349 else if (*p == ':') 8350 { 8351 n = cmd_exists(p + 1); 8352 } 8353 else if (*p == '#') 8354 { 8355 #ifdef FEAT_AUTOCMD 8356 name = p + 1; 8357 p = vim_strchr(name, '#'); 8358 if (p != NULL) 8359 n = au_exists(name, p, p + 1); 8360 else 8361 n = au_exists(name, name + STRLEN(name), NULL); 8362 #endif 8363 } 8364 else /* internal variable */ 8365 { 8366 char_u *tofree; 8367 typval_T tv; 8368 8369 /* get_name_len() takes care of expanding curly braces */ 8370 name = p; 8371 len = get_name_len(&p, &tofree, TRUE, FALSE); 8372 if (len > 0) 8373 { 8374 if (tofree != NULL) 8375 name = tofree; 8376 n = (get_var_tv(name, len, &tv, FALSE) == OK); 8377 if (n) 8378 { 8379 /* handle d.key, l[idx], f(expr) */ 8380 n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); 8381 if (n) 8382 clear_tv(&tv); 8383 } 8384 } 8385 8386 vim_free(tofree); 8387 } 8388 8389 rettv->vval.v_number = n; 8390 } 8391 8392 /* 8393 * "expand()" function 8394 */ 8395 static void 8396 f_expand(argvars, rettv) 8397 typval_T *argvars; 8398 typval_T *rettv; 8399 { 8400 char_u *s; 8401 int len; 8402 char_u *errormsg; 8403 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 8404 expand_T xpc; 8405 int error = FALSE; 8406 8407 rettv->v_type = VAR_STRING; 8408 s = get_tv_string(&argvars[0]); 8409 if (*s == '%' || *s == '#' || *s == '<') 8410 { 8411 ++emsg_off; 8412 rettv->vval.v_string = eval_vars(s, &len, NULL, &errormsg, s); 8413 --emsg_off; 8414 } 8415 else 8416 { 8417 /* When the optional second argument is non-zero, don't remove matches 8418 * for 'suffixes' and 'wildignore' */ 8419 if (argvars[1].v_type != VAR_UNKNOWN 8420 && get_tv_number_chk(&argvars[1], &error)) 8421 flags |= WILD_KEEP_ALL; 8422 if (!error) 8423 { 8424 ExpandInit(&xpc); 8425 xpc.xp_context = EXPAND_FILES; 8426 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 8427 ExpandCleanup(&xpc); 8428 } 8429 else 8430 rettv->vval.v_string = NULL; 8431 } 8432 } 8433 8434 /* 8435 * "extend(list, list [, idx])" function 8436 * "extend(dict, dict [, action])" function 8437 */ 8438 static void 8439 f_extend(argvars, rettv) 8440 typval_T *argvars; 8441 typval_T *rettv; 8442 { 8443 rettv->vval.v_number = 0; 8444 if (argvars[0].v_type == VAR_LIST && argvars[1].v_type == VAR_LIST) 8445 { 8446 list_T *l1, *l2; 8447 listitem_T *item; 8448 long before; 8449 int error = FALSE; 8450 8451 l1 = argvars[0].vval.v_list; 8452 l2 = argvars[1].vval.v_list; 8453 if (l1 != NULL && !tv_check_lock(l1->lv_lock, (char_u *)"extend()") 8454 && l2 != NULL) 8455 { 8456 if (argvars[2].v_type != VAR_UNKNOWN) 8457 { 8458 before = get_tv_number_chk(&argvars[2], &error); 8459 if (error) 8460 return; /* type error; errmsg already given */ 8461 8462 if (before == l1->lv_len) 8463 item = NULL; 8464 else 8465 { 8466 item = list_find(l1, before); 8467 if (item == NULL) 8468 { 8469 EMSGN(_(e_listidx), before); 8470 return; 8471 } 8472 } 8473 } 8474 else 8475 item = NULL; 8476 list_extend(l1, l2, item); 8477 8478 copy_tv(&argvars[0], rettv); 8479 } 8480 } 8481 else if (argvars[0].v_type == VAR_DICT && argvars[1].v_type == VAR_DICT) 8482 { 8483 dict_T *d1, *d2; 8484 dictitem_T *di1; 8485 char_u *action; 8486 int i; 8487 hashitem_T *hi2; 8488 int todo; 8489 8490 d1 = argvars[0].vval.v_dict; 8491 d2 = argvars[1].vval.v_dict; 8492 if (d1 != NULL && !tv_check_lock(d1->dv_lock, (char_u *)"extend()") 8493 && d2 != NULL) 8494 { 8495 /* Check the third argument. */ 8496 if (argvars[2].v_type != VAR_UNKNOWN) 8497 { 8498 static char *(av[]) = {"keep", "force", "error"}; 8499 8500 action = get_tv_string_chk(&argvars[2]); 8501 if (action == NULL) 8502 return; /* type error; errmsg already given */ 8503 for (i = 0; i < 3; ++i) 8504 if (STRCMP(action, av[i]) == 0) 8505 break; 8506 if (i == 3) 8507 { 8508 EMSGN(_(e_invarg2), action); 8509 return; 8510 } 8511 } 8512 else 8513 action = (char_u *)"force"; 8514 8515 /* Go over all entries in the second dict and add them to the 8516 * first dict. */ 8517 todo = d2->dv_hashtab.ht_used; 8518 for (hi2 = d2->dv_hashtab.ht_array; todo > 0; ++hi2) 8519 { 8520 if (!HASHITEM_EMPTY(hi2)) 8521 { 8522 --todo; 8523 di1 = dict_find(d1, hi2->hi_key, -1); 8524 if (di1 == NULL) 8525 { 8526 di1 = dictitem_copy(HI2DI(hi2)); 8527 if (di1 != NULL && dict_add(d1, di1) == FAIL) 8528 dictitem_free(di1); 8529 } 8530 else if (*action == 'e') 8531 { 8532 EMSG2(_("E737: Key already exists: %s"), hi2->hi_key); 8533 break; 8534 } 8535 else if (*action == 'f') 8536 { 8537 clear_tv(&di1->di_tv); 8538 copy_tv(&HI2DI(hi2)->di_tv, &di1->di_tv); 8539 } 8540 } 8541 } 8542 8543 copy_tv(&argvars[0], rettv); 8544 } 8545 } 8546 else 8547 EMSG2(_(e_listdictarg), "extend()"); 8548 } 8549 8550 /* 8551 * "filereadable()" function 8552 */ 8553 static void 8554 f_filereadable(argvars, rettv) 8555 typval_T *argvars; 8556 typval_T *rettv; 8557 { 8558 FILE *fd; 8559 char_u *p; 8560 int n; 8561 8562 p = get_tv_string(&argvars[0]); 8563 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 8564 { 8565 n = TRUE; 8566 fclose(fd); 8567 } 8568 else 8569 n = FALSE; 8570 8571 rettv->vval.v_number = n; 8572 } 8573 8574 /* 8575 * Return 0 for not writable, 1 for writable file, 2 for a dir which we have 8576 * rights to write into. 8577 */ 8578 static void 8579 f_filewritable(argvars, rettv) 8580 typval_T *argvars; 8581 typval_T *rettv; 8582 { 8583 rettv->vval.v_number = filewritable(get_tv_string(&argvars[0])); 8584 } 8585 8586 static void findfilendir __ARGS((typval_T *argvars, typval_T *rettv, int dir)); 8587 8588 static void 8589 findfilendir(argvars, rettv, dir) 8590 typval_T *argvars; 8591 typval_T *rettv; 8592 int dir; 8593 { 8594 #ifdef FEAT_SEARCHPATH 8595 char_u *fname; 8596 char_u *fresult = NULL; 8597 char_u *path = *curbuf->b_p_path == NUL ? p_path : curbuf->b_p_path; 8598 char_u *p; 8599 char_u pathbuf[NUMBUFLEN]; 8600 int count = 1; 8601 int first = TRUE; 8602 8603 fname = get_tv_string(&argvars[0]); 8604 8605 if (argvars[1].v_type != VAR_UNKNOWN) 8606 { 8607 p = get_tv_string_buf_chk(&argvars[1], pathbuf); 8608 if (p == NULL) 8609 count = -1; /* error */ 8610 else 8611 { 8612 if (*p != NUL) 8613 path = p; 8614 8615 if (argvars[2].v_type != VAR_UNKNOWN) 8616 count = get_tv_number_chk(&argvars[2], NULL); /* -1: error */ 8617 } 8618 } 8619 8620 if (*fname != NUL && count >= 0) 8621 { 8622 do 8623 { 8624 vim_free(fresult); 8625 fresult = find_file_in_path_option(first ? fname : NULL, 8626 first ? (int)STRLEN(fname) : 0, 8627 0, first, path, dir, NULL); 8628 first = FALSE; 8629 } while (--count > 0 && fresult != NULL); 8630 } 8631 8632 rettv->vval.v_string = fresult; 8633 #else 8634 rettv->vval.v_string = NULL; 8635 #endif 8636 rettv->v_type = VAR_STRING; 8637 } 8638 8639 static void filter_map __ARGS((typval_T *argvars, typval_T *rettv, int map)); 8640 static int filter_map_one __ARGS((typval_T *tv, char_u *expr, int map, int *remp)); 8641 8642 /* 8643 * Implementation of map() and filter(). 8644 */ 8645 static void 8646 filter_map(argvars, rettv, map) 8647 typval_T *argvars; 8648 typval_T *rettv; 8649 int map; 8650 { 8651 char_u buf[NUMBUFLEN]; 8652 char_u *expr; 8653 listitem_T *li, *nli; 8654 list_T *l = NULL; 8655 dictitem_T *di; 8656 hashtab_T *ht; 8657 hashitem_T *hi; 8658 dict_T *d = NULL; 8659 typval_T save_val; 8660 typval_T save_key; 8661 int rem; 8662 int todo; 8663 char_u *msg = map ? (char_u *)"map()" : (char_u *)"filter()"; 8664 8665 8666 rettv->vval.v_number = 0; 8667 if (argvars[0].v_type == VAR_LIST) 8668 { 8669 if ((l = argvars[0].vval.v_list) == NULL 8670 || (map && tv_check_lock(l->lv_lock, msg))) 8671 return; 8672 } 8673 else if (argvars[0].v_type == VAR_DICT) 8674 { 8675 if ((d = argvars[0].vval.v_dict) == NULL 8676 || (map && tv_check_lock(d->dv_lock, msg))) 8677 return; 8678 } 8679 else 8680 { 8681 EMSG2(_(e_listdictarg), msg); 8682 return; 8683 } 8684 8685 expr = get_tv_string_buf_chk(&argvars[1], buf); 8686 /* On type errors, the preceding call has already displayed an error 8687 * message. Avoid a misleading error message for an empty string that 8688 * was not passed as argument. */ 8689 if (expr != NULL) 8690 { 8691 prepare_vimvar(VV_VAL, &save_val); 8692 expr = skipwhite(expr); 8693 8694 if (argvars[0].v_type == VAR_DICT) 8695 { 8696 prepare_vimvar(VV_KEY, &save_key); 8697 vimvars[VV_KEY].vv_type = VAR_STRING; 8698 8699 ht = &d->dv_hashtab; 8700 hash_lock(ht); 8701 todo = ht->ht_used; 8702 for (hi = ht->ht_array; todo > 0; ++hi) 8703 { 8704 if (!HASHITEM_EMPTY(hi)) 8705 { 8706 --todo; 8707 di = HI2DI(hi); 8708 if (tv_check_lock(di->di_tv.v_lock, msg)) 8709 break; 8710 vimvars[VV_KEY].vv_str = vim_strsave(di->di_key); 8711 if (filter_map_one(&di->di_tv, expr, map, &rem) == FAIL) 8712 break; 8713 if (!map && rem) 8714 dictitem_remove(d, di); 8715 clear_tv(&vimvars[VV_KEY].vv_tv); 8716 } 8717 } 8718 hash_unlock(ht); 8719 8720 restore_vimvar(VV_KEY, &save_key); 8721 } 8722 else 8723 { 8724 for (li = l->lv_first; li != NULL; li = nli) 8725 { 8726 if (tv_check_lock(li->li_tv.v_lock, msg)) 8727 break; 8728 nli = li->li_next; 8729 if (filter_map_one(&li->li_tv, expr, map, &rem) == FAIL) 8730 break; 8731 if (!map && rem) 8732 listitem_remove(l, li); 8733 } 8734 } 8735 8736 restore_vimvar(VV_VAL, &save_val); 8737 } 8738 8739 copy_tv(&argvars[0], rettv); 8740 } 8741 8742 static int 8743 filter_map_one(tv, expr, map, remp) 8744 typval_T *tv; 8745 char_u *expr; 8746 int map; 8747 int *remp; 8748 { 8749 typval_T rettv; 8750 char_u *s; 8751 8752 copy_tv(tv, &vimvars[VV_VAL].vv_tv); 8753 s = expr; 8754 if (eval1(&s, &rettv, TRUE) == FAIL) 8755 return FAIL; 8756 if (*s != NUL) /* check for trailing chars after expr */ 8757 { 8758 EMSG2(_(e_invexpr2), s); 8759 return FAIL; 8760 } 8761 if (map) 8762 { 8763 /* map(): replace the list item value */ 8764 clear_tv(tv); 8765 *tv = rettv; 8766 } 8767 else 8768 { 8769 int error = FALSE; 8770 8771 /* filter(): when expr is zero remove the item */ 8772 *remp = (get_tv_number_chk(&rettv, &error) == 0); 8773 clear_tv(&rettv); 8774 /* On type error, nothing has been removed; return FAIL to stop the 8775 * loop. The error message was given by get_tv_number_chk(). */ 8776 if (error) 8777 return FAIL; 8778 } 8779 clear_tv(&vimvars[VV_VAL].vv_tv); 8780 return OK; 8781 } 8782 8783 /* 8784 * "filter()" function 8785 */ 8786 static void 8787 f_filter(argvars, rettv) 8788 typval_T *argvars; 8789 typval_T *rettv; 8790 { 8791 filter_map(argvars, rettv, FALSE); 8792 } 8793 8794 /* 8795 * "finddir({fname}[, {path}[, {count}]])" function 8796 */ 8797 static void 8798 f_finddir(argvars, rettv) 8799 typval_T *argvars; 8800 typval_T *rettv; 8801 { 8802 findfilendir(argvars, rettv, TRUE); 8803 } 8804 8805 /* 8806 * "findfile({fname}[, {path}[, {count}]])" function 8807 */ 8808 static void 8809 f_findfile(argvars, rettv) 8810 typval_T *argvars; 8811 typval_T *rettv; 8812 { 8813 findfilendir(argvars, rettv, FALSE); 8814 } 8815 8816 /* 8817 * "fnamemodify({fname}, {mods})" function 8818 */ 8819 static void 8820 f_fnamemodify(argvars, rettv) 8821 typval_T *argvars; 8822 typval_T *rettv; 8823 { 8824 char_u *fname; 8825 char_u *mods; 8826 int usedlen = 0; 8827 int len; 8828 char_u *fbuf = NULL; 8829 char_u buf[NUMBUFLEN]; 8830 8831 fname = get_tv_string_chk(&argvars[0]); 8832 mods = get_tv_string_buf_chk(&argvars[1], buf); 8833 if (fname == NULL || mods == NULL) 8834 fname = NULL; 8835 else 8836 { 8837 len = (int)STRLEN(fname); 8838 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 8839 } 8840 8841 rettv->v_type = VAR_STRING; 8842 if (fname == NULL) 8843 rettv->vval.v_string = NULL; 8844 else 8845 rettv->vval.v_string = vim_strnsave(fname, len); 8846 vim_free(fbuf); 8847 } 8848 8849 static void foldclosed_both __ARGS((typval_T *argvars, typval_T *rettv, int end)); 8850 8851 /* 8852 * "foldclosed()" function 8853 */ 8854 static void 8855 foldclosed_both(argvars, rettv, end) 8856 typval_T *argvars; 8857 typval_T *rettv; 8858 int end; 8859 { 8860 #ifdef FEAT_FOLDING 8861 linenr_T lnum; 8862 linenr_T first, last; 8863 8864 lnum = get_tv_lnum(argvars); 8865 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8866 { 8867 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 8868 { 8869 if (end) 8870 rettv->vval.v_number = (varnumber_T)last; 8871 else 8872 rettv->vval.v_number = (varnumber_T)first; 8873 return; 8874 } 8875 } 8876 #endif 8877 rettv->vval.v_number = -1; 8878 } 8879 8880 /* 8881 * "foldclosed()" function 8882 */ 8883 static void 8884 f_foldclosed(argvars, rettv) 8885 typval_T *argvars; 8886 typval_T *rettv; 8887 { 8888 foldclosed_both(argvars, rettv, FALSE); 8889 } 8890 8891 /* 8892 * "foldclosedend()" function 8893 */ 8894 static void 8895 f_foldclosedend(argvars, rettv) 8896 typval_T *argvars; 8897 typval_T *rettv; 8898 { 8899 foldclosed_both(argvars, rettv, TRUE); 8900 } 8901 8902 /* 8903 * "foldlevel()" function 8904 */ 8905 static void 8906 f_foldlevel(argvars, rettv) 8907 typval_T *argvars; 8908 typval_T *rettv; 8909 { 8910 #ifdef FEAT_FOLDING 8911 linenr_T lnum; 8912 8913 lnum = get_tv_lnum(argvars); 8914 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 8915 rettv->vval.v_number = foldLevel(lnum); 8916 else 8917 #endif 8918 rettv->vval.v_number = 0; 8919 } 8920 8921 /* 8922 * "foldtext()" function 8923 */ 8924 /*ARGSUSED*/ 8925 static void 8926 f_foldtext(argvars, rettv) 8927 typval_T *argvars; 8928 typval_T *rettv; 8929 { 8930 #ifdef FEAT_FOLDING 8931 linenr_T lnum; 8932 char_u *s; 8933 char_u *r; 8934 int len; 8935 char *txt; 8936 #endif 8937 8938 rettv->v_type = VAR_STRING; 8939 rettv->vval.v_string = NULL; 8940 #ifdef FEAT_FOLDING 8941 if ((linenr_T)vimvars[VV_FOLDSTART].vv_nr > 0 8942 && (linenr_T)vimvars[VV_FOLDEND].vv_nr 8943 <= curbuf->b_ml.ml_line_count 8944 && vimvars[VV_FOLDDASHES].vv_str != NULL) 8945 { 8946 /* Find first non-empty line in the fold. */ 8947 lnum = (linenr_T)vimvars[VV_FOLDSTART].vv_nr; 8948 while (lnum < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 8949 { 8950 if (!linewhite(lnum)) 8951 break; 8952 ++lnum; 8953 } 8954 8955 /* Find interesting text in this line. */ 8956 s = skipwhite(ml_get(lnum)); 8957 /* skip C comment-start */ 8958 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 8959 { 8960 s = skipwhite(s + 2); 8961 if (*skipwhite(s) == NUL 8962 && lnum + 1 < (linenr_T)vimvars[VV_FOLDEND].vv_nr) 8963 { 8964 s = skipwhite(ml_get(lnum + 1)); 8965 if (*s == '*') 8966 s = skipwhite(s + 1); 8967 } 8968 } 8969 txt = _("+-%s%3ld lines: "); 8970 r = alloc((unsigned)(STRLEN(txt) 8971 + STRLEN(vimvars[VV_FOLDDASHES].vv_str) /* for %s */ 8972 + 20 /* for %3ld */ 8973 + STRLEN(s))); /* concatenated */ 8974 if (r != NULL) 8975 { 8976 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].vv_str, 8977 (long)((linenr_T)vimvars[VV_FOLDEND].vv_nr 8978 - (linenr_T)vimvars[VV_FOLDSTART].vv_nr + 1)); 8979 len = (int)STRLEN(r); 8980 STRCAT(r, s); 8981 /* remove 'foldmarker' and 'commentstring' */ 8982 foldtext_cleanup(r + len); 8983 rettv->vval.v_string = r; 8984 } 8985 } 8986 #endif 8987 } 8988 8989 /* 8990 * "foldtextresult(lnum)" function 8991 */ 8992 /*ARGSUSED*/ 8993 static void 8994 f_foldtextresult(argvars, rettv) 8995 typval_T *argvars; 8996 typval_T *rettv; 8997 { 8998 #ifdef FEAT_FOLDING 8999 linenr_T lnum; 9000 char_u *text; 9001 char_u buf[51]; 9002 foldinfo_T foldinfo; 9003 int fold_count; 9004 #endif 9005 9006 rettv->v_type = VAR_STRING; 9007 rettv->vval.v_string = NULL; 9008 #ifdef FEAT_FOLDING 9009 lnum = get_tv_lnum(argvars); 9010 /* treat illegal types and illegal string values for {lnum} the same */ 9011 if (lnum < 0) 9012 lnum = 0; 9013 fold_count = foldedCount(curwin, lnum, &foldinfo); 9014 if (fold_count > 0) 9015 { 9016 text = get_foldtext(curwin, lnum, lnum + fold_count - 1, 9017 &foldinfo, buf); 9018 if (text == buf) 9019 text = vim_strsave(text); 9020 rettv->vval.v_string = text; 9021 } 9022 #endif 9023 } 9024 9025 /* 9026 * "foreground()" function 9027 */ 9028 /*ARGSUSED*/ 9029 static void 9030 f_foreground(argvars, rettv) 9031 typval_T *argvars; 9032 typval_T *rettv; 9033 { 9034 rettv->vval.v_number = 0; 9035 #ifdef FEAT_GUI 9036 if (gui.in_use) 9037 gui_mch_set_foreground(); 9038 #else 9039 # ifdef WIN32 9040 win32_set_foreground(); 9041 # endif 9042 #endif 9043 } 9044 9045 /* 9046 * "function()" function 9047 */ 9048 /*ARGSUSED*/ 9049 static void 9050 f_function(argvars, rettv) 9051 typval_T *argvars; 9052 typval_T *rettv; 9053 { 9054 char_u *s; 9055 9056 rettv->vval.v_number = 0; 9057 s = get_tv_string(&argvars[0]); 9058 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) 9059 EMSG2(_(e_invarg2), s); 9060 else if (!function_exists(s)) 9061 EMSG2(_("E700: Unknown function: %s"), s); 9062 else 9063 { 9064 rettv->vval.v_string = vim_strsave(s); 9065 rettv->v_type = VAR_FUNC; 9066 } 9067 } 9068 9069 /* 9070 * "garbagecollect()" function 9071 */ 9072 /*ARGSUSED*/ 9073 static void 9074 f_garbagecollect(argvars, rettv) 9075 typval_T *argvars; 9076 typval_T *rettv; 9077 { 9078 garbage_collect(); 9079 } 9080 9081 /* 9082 * "get()" function 9083 */ 9084 static void 9085 f_get(argvars, rettv) 9086 typval_T *argvars; 9087 typval_T *rettv; 9088 { 9089 listitem_T *li; 9090 list_T *l; 9091 dictitem_T *di; 9092 dict_T *d; 9093 typval_T *tv = NULL; 9094 9095 if (argvars[0].v_type == VAR_LIST) 9096 { 9097 if ((l = argvars[0].vval.v_list) != NULL) 9098 { 9099 int error = FALSE; 9100 9101 li = list_find(l, get_tv_number_chk(&argvars[1], &error)); 9102 if (!error && li != NULL) 9103 tv = &li->li_tv; 9104 } 9105 } 9106 else if (argvars[0].v_type == VAR_DICT) 9107 { 9108 if ((d = argvars[0].vval.v_dict) != NULL) 9109 { 9110 di = dict_find(d, get_tv_string(&argvars[1]), -1); 9111 if (di != NULL) 9112 tv = &di->di_tv; 9113 } 9114 } 9115 else 9116 EMSG2(_(e_listdictarg), "get()"); 9117 9118 if (tv == NULL) 9119 { 9120 if (argvars[2].v_type == VAR_UNKNOWN) 9121 rettv->vval.v_number = 0; 9122 else 9123 copy_tv(&argvars[2], rettv); 9124 } 9125 else 9126 copy_tv(tv, rettv); 9127 } 9128 9129 static void get_buffer_lines __ARGS((buf_T *buf, linenr_T start, linenr_T end, int retlist, typval_T *rettv)); 9130 9131 /* 9132 * Get line or list of lines from buffer "buf" into "rettv". 9133 * Return a range (from start to end) of lines in rettv from the specified 9134 * buffer. 9135 * If 'retlist' is TRUE, then the lines are returned as a Vim List. 9136 */ 9137 static void 9138 get_buffer_lines(buf, start, end, retlist, rettv) 9139 buf_T *buf; 9140 linenr_T start; 9141 linenr_T end; 9142 int retlist; 9143 typval_T *rettv; 9144 { 9145 char_u *p; 9146 list_T *l = NULL; 9147 listitem_T *li; 9148 9149 if (retlist) 9150 { 9151 l = list_alloc(); 9152 if (l == NULL) 9153 return; 9154 9155 rettv->vval.v_list = l; 9156 rettv->v_type = VAR_LIST; 9157 ++l->lv_refcount; 9158 } 9159 else 9160 rettv->vval.v_number = 0; 9161 9162 if (buf == NULL || buf->b_ml.ml_mfp == NULL || start < 0) 9163 return; 9164 9165 if (!retlist) 9166 { 9167 if (start >= 1 && start <= buf->b_ml.ml_line_count) 9168 p = ml_get_buf(buf, start, FALSE); 9169 else 9170 p = (char_u *)""; 9171 9172 rettv->v_type = VAR_STRING; 9173 rettv->vval.v_string = vim_strsave(p); 9174 } 9175 else 9176 { 9177 if (end < start) 9178 return; 9179 9180 if (start < 1) 9181 start = 1; 9182 if (end > buf->b_ml.ml_line_count) 9183 end = buf->b_ml.ml_line_count; 9184 while (start <= end) 9185 { 9186 li = listitem_alloc(); 9187 if (li == NULL) 9188 break; 9189 list_append(l, li); 9190 li->li_tv.v_type = VAR_STRING; 9191 li->li_tv.v_lock = 0; 9192 li->li_tv.vval.v_string = 9193 vim_strsave(ml_get_buf(buf, start++, FALSE)); 9194 } 9195 } 9196 } 9197 9198 /* 9199 * "getbufline()" function 9200 */ 9201 static void 9202 f_getbufline(argvars, rettv) 9203 typval_T *argvars; 9204 typval_T *rettv; 9205 { 9206 linenr_T lnum; 9207 linenr_T end; 9208 buf_T *buf; 9209 9210 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9211 ++emsg_off; 9212 buf = get_buf_tv(&argvars[0]); 9213 --emsg_off; 9214 9215 lnum = get_tv_lnum_buf(&argvars[1], buf); 9216 if (argvars[2].v_type == VAR_UNKNOWN) 9217 end = lnum; 9218 else 9219 end = get_tv_lnum_buf(&argvars[2], buf); 9220 9221 get_buffer_lines(buf, lnum, end, TRUE, rettv); 9222 } 9223 9224 /* 9225 * "getbufvar()" function 9226 */ 9227 static void 9228 f_getbufvar(argvars, rettv) 9229 typval_T *argvars; 9230 typval_T *rettv; 9231 { 9232 buf_T *buf; 9233 buf_T *save_curbuf; 9234 char_u *varname; 9235 dictitem_T *v; 9236 9237 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 9238 varname = get_tv_string_chk(&argvars[1]); 9239 ++emsg_off; 9240 buf = get_buf_tv(&argvars[0]); 9241 9242 rettv->v_type = VAR_STRING; 9243 rettv->vval.v_string = NULL; 9244 9245 if (buf != NULL && varname != NULL) 9246 { 9247 if (*varname == '&') /* buffer-local-option */ 9248 { 9249 /* set curbuf to be our buf, temporarily */ 9250 save_curbuf = curbuf; 9251 curbuf = buf; 9252 9253 get_option_tv(&varname, rettv, TRUE); 9254 9255 /* restore previous notion of curbuf */ 9256 curbuf = save_curbuf; 9257 } 9258 else 9259 { 9260 if (*varname == NUL) 9261 /* let getbufvar({nr}, "") return the "b:" dictionary. The 9262 * scope prefix before the NUL byte is required by 9263 * find_var_in_ht(). */ 9264 varname = (char_u *)"b:" + 2; 9265 /* look up the variable */ 9266 v = find_var_in_ht(&buf->b_vars.dv_hashtab, varname, FALSE); 9267 if (v != NULL) 9268 copy_tv(&v->di_tv, rettv); 9269 } 9270 } 9271 9272 --emsg_off; 9273 } 9274 9275 /* 9276 * "getchar()" function 9277 */ 9278 static void 9279 f_getchar(argvars, rettv) 9280 typval_T *argvars; 9281 typval_T *rettv; 9282 { 9283 varnumber_T n; 9284 int error = FALSE; 9285 9286 ++no_mapping; 9287 ++allow_keys; 9288 if (argvars[0].v_type == VAR_UNKNOWN) 9289 /* getchar(): blocking wait. */ 9290 n = safe_vgetc(); 9291 else if (get_tv_number_chk(&argvars[0], &error) == 1) 9292 /* getchar(1): only check if char avail */ 9293 n = vpeekc(); 9294 else if (error || vpeekc() == NUL) 9295 /* illegal argument or getchar(0) and no char avail: return zero */ 9296 n = 0; 9297 else 9298 /* getchar(0) and char avail: return char */ 9299 n = safe_vgetc(); 9300 --no_mapping; 9301 --allow_keys; 9302 9303 rettv->vval.v_number = n; 9304 if (IS_SPECIAL(n) || mod_mask != 0) 9305 { 9306 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 9307 int i = 0; 9308 9309 /* Turn a special key into three bytes, plus modifier. */ 9310 if (mod_mask != 0) 9311 { 9312 temp[i++] = K_SPECIAL; 9313 temp[i++] = KS_MODIFIER; 9314 temp[i++] = mod_mask; 9315 } 9316 if (IS_SPECIAL(n)) 9317 { 9318 temp[i++] = K_SPECIAL; 9319 temp[i++] = K_SECOND(n); 9320 temp[i++] = K_THIRD(n); 9321 } 9322 #ifdef FEAT_MBYTE 9323 else if (has_mbyte) 9324 i += (*mb_char2bytes)(n, temp + i); 9325 #endif 9326 else 9327 temp[i++] = n; 9328 temp[i++] = NUL; 9329 rettv->v_type = VAR_STRING; 9330 rettv->vval.v_string = vim_strsave(temp); 9331 } 9332 } 9333 9334 /* 9335 * "getcharmod()" function 9336 */ 9337 /*ARGSUSED*/ 9338 static void 9339 f_getcharmod(argvars, rettv) 9340 typval_T *argvars; 9341 typval_T *rettv; 9342 { 9343 rettv->vval.v_number = mod_mask; 9344 } 9345 9346 /* 9347 * "getcmdline()" function 9348 */ 9349 /*ARGSUSED*/ 9350 static void 9351 f_getcmdline(argvars, rettv) 9352 typval_T *argvars; 9353 typval_T *rettv; 9354 { 9355 rettv->v_type = VAR_STRING; 9356 rettv->vval.v_string = get_cmdline_str(); 9357 } 9358 9359 /* 9360 * "getcmdpos()" function 9361 */ 9362 /*ARGSUSED*/ 9363 static void 9364 f_getcmdpos(argvars, rettv) 9365 typval_T *argvars; 9366 typval_T *rettv; 9367 { 9368 rettv->vval.v_number = get_cmdline_pos() + 1; 9369 } 9370 9371 /* 9372 * "getcwd()" function 9373 */ 9374 /*ARGSUSED*/ 9375 static void 9376 f_getcwd(argvars, rettv) 9377 typval_T *argvars; 9378 typval_T *rettv; 9379 { 9380 char_u cwd[MAXPATHL]; 9381 9382 rettv->v_type = VAR_STRING; 9383 if (mch_dirname(cwd, MAXPATHL) == FAIL) 9384 rettv->vval.v_string = NULL; 9385 else 9386 { 9387 rettv->vval.v_string = vim_strsave(cwd); 9388 #ifdef BACKSLASH_IN_FILENAME 9389 if (rettv->vval.v_string != NULL) 9390 slash_adjust(rettv->vval.v_string); 9391 #endif 9392 } 9393 } 9394 9395 /* 9396 * "getfontname()" function 9397 */ 9398 /*ARGSUSED*/ 9399 static void 9400 f_getfontname(argvars, rettv) 9401 typval_T *argvars; 9402 typval_T *rettv; 9403 { 9404 rettv->v_type = VAR_STRING; 9405 rettv->vval.v_string = NULL; 9406 #ifdef FEAT_GUI 9407 if (gui.in_use) 9408 { 9409 GuiFont font; 9410 char_u *name = NULL; 9411 9412 if (argvars[0].v_type == VAR_UNKNOWN) 9413 { 9414 /* Get the "Normal" font. Either the name saved by 9415 * hl_set_font_name() or from the font ID. */ 9416 font = gui.norm_font; 9417 name = hl_get_font_name(); 9418 } 9419 else 9420 { 9421 name = get_tv_string(&argvars[0]); 9422 if (STRCMP(name, "*") == 0) /* don't use font dialog */ 9423 return; 9424 font = gui_mch_get_font(name, FALSE); 9425 if (font == NOFONT) 9426 return; /* Invalid font name, return empty string. */ 9427 } 9428 rettv->vval.v_string = gui_mch_get_fontname(font, name); 9429 if (argvars[0].v_type != VAR_UNKNOWN) 9430 gui_mch_free_font(font); 9431 } 9432 #endif 9433 } 9434 9435 /* 9436 * "getfperm({fname})" function 9437 */ 9438 static void 9439 f_getfperm(argvars, rettv) 9440 typval_T *argvars; 9441 typval_T *rettv; 9442 { 9443 char_u *fname; 9444 struct stat st; 9445 char_u *perm = NULL; 9446 char_u flags[] = "rwx"; 9447 int i; 9448 9449 fname = get_tv_string(&argvars[0]); 9450 9451 rettv->v_type = VAR_STRING; 9452 if (mch_stat((char *)fname, &st) >= 0) 9453 { 9454 perm = vim_strsave((char_u *)"---------"); 9455 if (perm != NULL) 9456 { 9457 for (i = 0; i < 9; i++) 9458 { 9459 if (st.st_mode & (1 << (8 - i))) 9460 perm[i] = flags[i % 3]; 9461 } 9462 } 9463 } 9464 rettv->vval.v_string = perm; 9465 } 9466 9467 /* 9468 * "getfsize({fname})" function 9469 */ 9470 static void 9471 f_getfsize(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 rettv->v_type = VAR_NUMBER; 9481 9482 if (mch_stat((char *)fname, &st) >= 0) 9483 { 9484 if (mch_isdir(fname)) 9485 rettv->vval.v_number = 0; 9486 else 9487 rettv->vval.v_number = (varnumber_T)st.st_size; 9488 } 9489 else 9490 rettv->vval.v_number = -1; 9491 } 9492 9493 /* 9494 * "getftime({fname})" function 9495 */ 9496 static void 9497 f_getftime(argvars, rettv) 9498 typval_T *argvars; 9499 typval_T *rettv; 9500 { 9501 char_u *fname; 9502 struct stat st; 9503 9504 fname = get_tv_string(&argvars[0]); 9505 9506 if (mch_stat((char *)fname, &st) >= 0) 9507 rettv->vval.v_number = (varnumber_T)st.st_mtime; 9508 else 9509 rettv->vval.v_number = -1; 9510 } 9511 9512 /* 9513 * "getftype({fname})" function 9514 */ 9515 static void 9516 f_getftype(argvars, rettv) 9517 typval_T *argvars; 9518 typval_T *rettv; 9519 { 9520 char_u *fname; 9521 struct stat st; 9522 char_u *type = NULL; 9523 char *t; 9524 9525 fname = get_tv_string(&argvars[0]); 9526 9527 rettv->v_type = VAR_STRING; 9528 if (mch_lstat((char *)fname, &st) >= 0) 9529 { 9530 #ifdef S_ISREG 9531 if (S_ISREG(st.st_mode)) 9532 t = "file"; 9533 else if (S_ISDIR(st.st_mode)) 9534 t = "dir"; 9535 # ifdef S_ISLNK 9536 else if (S_ISLNK(st.st_mode)) 9537 t = "link"; 9538 # endif 9539 # ifdef S_ISBLK 9540 else if (S_ISBLK(st.st_mode)) 9541 t = "bdev"; 9542 # endif 9543 # ifdef S_ISCHR 9544 else if (S_ISCHR(st.st_mode)) 9545 t = "cdev"; 9546 # endif 9547 # ifdef S_ISFIFO 9548 else if (S_ISFIFO(st.st_mode)) 9549 t = "fifo"; 9550 # endif 9551 # ifdef S_ISSOCK 9552 else if (S_ISSOCK(st.st_mode)) 9553 t = "fifo"; 9554 # endif 9555 else 9556 t = "other"; 9557 #else 9558 # ifdef S_IFMT 9559 switch (st.st_mode & S_IFMT) 9560 { 9561 case S_IFREG: t = "file"; break; 9562 case S_IFDIR: t = "dir"; break; 9563 # ifdef S_IFLNK 9564 case S_IFLNK: t = "link"; break; 9565 # endif 9566 # ifdef S_IFBLK 9567 case S_IFBLK: t = "bdev"; break; 9568 # endif 9569 # ifdef S_IFCHR 9570 case S_IFCHR: t = "cdev"; break; 9571 # endif 9572 # ifdef S_IFIFO 9573 case S_IFIFO: t = "fifo"; break; 9574 # endif 9575 # ifdef S_IFSOCK 9576 case S_IFSOCK: t = "socket"; break; 9577 # endif 9578 default: t = "other"; 9579 } 9580 # else 9581 if (mch_isdir(fname)) 9582 t = "dir"; 9583 else 9584 t = "file"; 9585 # endif 9586 #endif 9587 type = vim_strsave((char_u *)t); 9588 } 9589 rettv->vval.v_string = type; 9590 } 9591 9592 /* 9593 * "getline(lnum, [end])" function 9594 */ 9595 static void 9596 f_getline(argvars, rettv) 9597 typval_T *argvars; 9598 typval_T *rettv; 9599 { 9600 linenr_T lnum; 9601 linenr_T end; 9602 int retlist; 9603 9604 lnum = get_tv_lnum(argvars); 9605 if (argvars[1].v_type == VAR_UNKNOWN) 9606 { 9607 end = 0; 9608 retlist = FALSE; 9609 } 9610 else 9611 { 9612 end = get_tv_lnum(&argvars[1]); 9613 retlist = TRUE; 9614 } 9615 9616 get_buffer_lines(curbuf, lnum, end, retlist, rettv); 9617 } 9618 9619 /* 9620 * "getqflist()" function 9621 */ 9622 /*ARGSUSED*/ 9623 static void 9624 f_getqflist(argvars, rettv) 9625 typval_T *argvars; 9626 typval_T *rettv; 9627 { 9628 #ifdef FEAT_QUICKFIX 9629 list_T *l; 9630 #endif 9631 9632 rettv->vval.v_number = FALSE; 9633 #ifdef FEAT_QUICKFIX 9634 l = list_alloc(); 9635 if (l != NULL) 9636 { 9637 if (get_errorlist(l) != FAIL) 9638 { 9639 rettv->vval.v_list = l; 9640 rettv->v_type = VAR_LIST; 9641 ++l->lv_refcount; 9642 } 9643 else 9644 list_free(l); 9645 } 9646 #endif 9647 } 9648 9649 /* 9650 * "getreg()" function 9651 */ 9652 static void 9653 f_getreg(argvars, rettv) 9654 typval_T *argvars; 9655 typval_T *rettv; 9656 { 9657 char_u *strregname; 9658 int regname; 9659 int arg2 = FALSE; 9660 int error = FALSE; 9661 9662 if (argvars[0].v_type != VAR_UNKNOWN) 9663 { 9664 strregname = get_tv_string_chk(&argvars[0]); 9665 error = strregname == NULL; 9666 if (argvars[1].v_type != VAR_UNKNOWN) 9667 arg2 = get_tv_number_chk(&argvars[1], &error); 9668 } 9669 else 9670 strregname = vimvars[VV_REG].vv_str; 9671 regname = (strregname == NULL ? '"' : *strregname); 9672 if (regname == 0) 9673 regname = '"'; 9674 9675 rettv->v_type = VAR_STRING; 9676 rettv->vval.v_string = error ? NULL : 9677 get_reg_contents(regname, TRUE, arg2); 9678 } 9679 9680 /* 9681 * "getregtype()" function 9682 */ 9683 static void 9684 f_getregtype(argvars, rettv) 9685 typval_T *argvars; 9686 typval_T *rettv; 9687 { 9688 char_u *strregname; 9689 int regname; 9690 char_u buf[NUMBUFLEN + 2]; 9691 long reglen = 0; 9692 9693 if (argvars[0].v_type != VAR_UNKNOWN) 9694 { 9695 strregname = get_tv_string_chk(&argvars[0]); 9696 if (strregname == NULL) /* type error; errmsg already given */ 9697 { 9698 rettv->v_type = VAR_STRING; 9699 rettv->vval.v_string = NULL; 9700 return; 9701 } 9702 } 9703 else 9704 /* Default to v:register */ 9705 strregname = vimvars[VV_REG].vv_str; 9706 9707 regname = (strregname == NULL ? '"' : *strregname); 9708 if (regname == 0) 9709 regname = '"'; 9710 9711 buf[0] = NUL; 9712 buf[1] = NUL; 9713 switch (get_reg_type(regname, ®len)) 9714 { 9715 case MLINE: buf[0] = 'V'; break; 9716 case MCHAR: buf[0] = 'v'; break; 9717 #ifdef FEAT_VISUAL 9718 case MBLOCK: 9719 buf[0] = Ctrl_V; 9720 sprintf((char *)buf + 1, "%ld", reglen + 1); 9721 break; 9722 #endif 9723 } 9724 rettv->v_type = VAR_STRING; 9725 rettv->vval.v_string = vim_strsave(buf); 9726 } 9727 9728 /* 9729 * "getwinposx()" function 9730 */ 9731 /*ARGSUSED*/ 9732 static void 9733 f_getwinposx(argvars, rettv) 9734 typval_T *argvars; 9735 typval_T *rettv; 9736 { 9737 rettv->vval.v_number = -1; 9738 #ifdef FEAT_GUI 9739 if (gui.in_use) 9740 { 9741 int x, y; 9742 9743 if (gui_mch_get_winpos(&x, &y) == OK) 9744 rettv->vval.v_number = x; 9745 } 9746 #endif 9747 } 9748 9749 /* 9750 * "getwinposy()" function 9751 */ 9752 /*ARGSUSED*/ 9753 static void 9754 f_getwinposy(argvars, rettv) 9755 typval_T *argvars; 9756 typval_T *rettv; 9757 { 9758 rettv->vval.v_number = -1; 9759 #ifdef FEAT_GUI 9760 if (gui.in_use) 9761 { 9762 int x, y; 9763 9764 if (gui_mch_get_winpos(&x, &y) == OK) 9765 rettv->vval.v_number = y; 9766 } 9767 #endif 9768 } 9769 9770 static win_T *find_win_by_nr __ARGS((typval_T *vp)); 9771 9772 static win_T * 9773 find_win_by_nr(vp) 9774 typval_T *vp; 9775 { 9776 #ifdef FEAT_WINDOWS 9777 win_T *wp; 9778 #endif 9779 int nr; 9780 9781 nr = get_tv_number_chk(vp, NULL); 9782 9783 #ifdef FEAT_WINDOWS 9784 if (nr < 0) 9785 return NULL; 9786 if (nr == 0) 9787 return curwin; 9788 9789 for (wp = firstwin; wp != NULL; wp = wp->w_next) 9790 if (--nr <= 0) 9791 break; 9792 return wp; 9793 #else 9794 if (nr == 0 || nr == 1) 9795 return curwin; 9796 return NULL; 9797 #endif 9798 } 9799 9800 /* 9801 * "getwinvar()" function 9802 */ 9803 static void 9804 f_getwinvar(argvars, rettv) 9805 typval_T *argvars; 9806 typval_T *rettv; 9807 { 9808 win_T *win, *oldcurwin; 9809 char_u *varname; 9810 dictitem_T *v; 9811 9812 win = find_win_by_nr(&argvars[0]); 9813 varname = get_tv_string_chk(&argvars[1]); 9814 ++emsg_off; 9815 9816 rettv->v_type = VAR_STRING; 9817 rettv->vval.v_string = NULL; 9818 9819 if (win != NULL && varname != NULL) 9820 { 9821 if (*varname == '&') /* window-local-option */ 9822 { 9823 /* Set curwin to be our win, temporarily. Also set curbuf, so 9824 * that we can get buffer-local options. */ 9825 oldcurwin = curwin; 9826 curwin = win; 9827 curbuf = win->w_buffer; 9828 9829 get_option_tv(&varname, rettv, 1); 9830 9831 /* restore previous notion of curwin */ 9832 curwin = oldcurwin; 9833 curbuf = curwin->w_buffer; 9834 } 9835 else 9836 { 9837 if (*varname == NUL) 9838 /* let getwinvar({nr}, "") return the "w:" dictionary. The 9839 * scope prefix before the NUL byte is required by 9840 * find_var_in_ht(). */ 9841 varname = (char_u *)"w:" + 2; 9842 /* look up the variable */ 9843 v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE); 9844 if (v != NULL) 9845 copy_tv(&v->di_tv, rettv); 9846 } 9847 } 9848 9849 --emsg_off; 9850 } 9851 9852 /* 9853 * "glob()" function 9854 */ 9855 static void 9856 f_glob(argvars, rettv) 9857 typval_T *argvars; 9858 typval_T *rettv; 9859 { 9860 expand_T xpc; 9861 9862 ExpandInit(&xpc); 9863 xpc.xp_context = EXPAND_FILES; 9864 rettv->v_type = VAR_STRING; 9865 rettv->vval.v_string = ExpandOne(&xpc, get_tv_string(&argvars[0]), 9866 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 9867 ExpandCleanup(&xpc); 9868 } 9869 9870 /* 9871 * "globpath()" function 9872 */ 9873 static void 9874 f_globpath(argvars, rettv) 9875 typval_T *argvars; 9876 typval_T *rettv; 9877 { 9878 char_u buf1[NUMBUFLEN]; 9879 char_u *file = get_tv_string_buf_chk(&argvars[1], buf1); 9880 9881 rettv->v_type = VAR_STRING; 9882 if (file == NULL) 9883 rettv->vval.v_string = NULL; 9884 else 9885 rettv->vval.v_string = globpath(get_tv_string(&argvars[0]), file); 9886 } 9887 9888 /* 9889 * "has()" function 9890 */ 9891 static void 9892 f_has(argvars, rettv) 9893 typval_T *argvars; 9894 typval_T *rettv; 9895 { 9896 int i; 9897 char_u *name; 9898 int n = FALSE; 9899 static char *(has_list[]) = 9900 { 9901 #ifdef AMIGA 9902 "amiga", 9903 # ifdef FEAT_ARP 9904 "arp", 9905 # endif 9906 #endif 9907 #ifdef __BEOS__ 9908 "beos", 9909 #endif 9910 #ifdef MSDOS 9911 # ifdef DJGPP 9912 "dos32", 9913 # else 9914 "dos16", 9915 # endif 9916 #endif 9917 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */ 9918 "mac", 9919 #endif 9920 #if defined(MACOS_X_UNIX) 9921 "macunix", 9922 #endif 9923 #ifdef OS2 9924 "os2", 9925 #endif 9926 #ifdef __QNX__ 9927 "qnx", 9928 #endif 9929 #ifdef RISCOS 9930 "riscos", 9931 #endif 9932 #ifdef UNIX 9933 "unix", 9934 #endif 9935 #ifdef VMS 9936 "vms", 9937 #endif 9938 #ifdef WIN16 9939 "win16", 9940 #endif 9941 #ifdef WIN32 9942 "win32", 9943 #endif 9944 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 9945 "win32unix", 9946 #endif 9947 #ifdef WIN64 9948 "win64", 9949 #endif 9950 #ifdef EBCDIC 9951 "ebcdic", 9952 #endif 9953 #ifndef CASE_INSENSITIVE_FILENAME 9954 "fname_case", 9955 #endif 9956 #ifdef FEAT_ARABIC 9957 "arabic", 9958 #endif 9959 #ifdef FEAT_AUTOCMD 9960 "autocmd", 9961 #endif 9962 #ifdef FEAT_BEVAL 9963 "balloon_eval", 9964 # ifndef FEAT_GUI_W32 /* other GUIs always have multiline balloons */ 9965 "balloon_multiline", 9966 # endif 9967 #endif 9968 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 9969 "builtin_terms", 9970 # ifdef ALL_BUILTIN_TCAPS 9971 "all_builtin_terms", 9972 # endif 9973 #endif 9974 #ifdef FEAT_BYTEOFF 9975 "byte_offset", 9976 #endif 9977 #ifdef FEAT_CINDENT 9978 "cindent", 9979 #endif 9980 #ifdef FEAT_CLIENTSERVER 9981 "clientserver", 9982 #endif 9983 #ifdef FEAT_CLIPBOARD 9984 "clipboard", 9985 #endif 9986 #ifdef FEAT_CMDL_COMPL 9987 "cmdline_compl", 9988 #endif 9989 #ifdef FEAT_CMDHIST 9990 "cmdline_hist", 9991 #endif 9992 #ifdef FEAT_COMMENTS 9993 "comments", 9994 #endif 9995 #ifdef FEAT_CRYPT 9996 "cryptv", 9997 #endif 9998 #ifdef FEAT_CSCOPE 9999 "cscope", 10000 #endif 10001 #ifdef DEBUG 10002 "debug", 10003 #endif 10004 #ifdef FEAT_CON_DIALOG 10005 "dialog_con", 10006 #endif 10007 #ifdef FEAT_GUI_DIALOG 10008 "dialog_gui", 10009 #endif 10010 #ifdef FEAT_DIFF 10011 "diff", 10012 #endif 10013 #ifdef FEAT_DIGRAPHS 10014 "digraphs", 10015 #endif 10016 #ifdef FEAT_DND 10017 "dnd", 10018 #endif 10019 #ifdef FEAT_EMACS_TAGS 10020 "emacs_tags", 10021 #endif 10022 "eval", /* always present, of course! */ 10023 #ifdef FEAT_EX_EXTRA 10024 "ex_extra", 10025 #endif 10026 #ifdef FEAT_SEARCH_EXTRA 10027 "extra_search", 10028 #endif 10029 #ifdef FEAT_FKMAP 10030 "farsi", 10031 #endif 10032 #ifdef FEAT_SEARCHPATH 10033 "file_in_path", 10034 #endif 10035 #if defined(UNIX) && !defined(USE_SYSTEM) 10036 "filterpipe", 10037 #endif 10038 #ifdef FEAT_FIND_ID 10039 "find_in_path", 10040 #endif 10041 #ifdef FEAT_FOLDING 10042 "folding", 10043 #endif 10044 #ifdef FEAT_FOOTER 10045 "footer", 10046 #endif 10047 #if !defined(USE_SYSTEM) && defined(UNIX) 10048 "fork", 10049 #endif 10050 #ifdef FEAT_GETTEXT 10051 "gettext", 10052 #endif 10053 #ifdef FEAT_GUI 10054 "gui", 10055 #endif 10056 #ifdef FEAT_GUI_ATHENA 10057 # ifdef FEAT_GUI_NEXTAW 10058 "gui_neXtaw", 10059 # else 10060 "gui_athena", 10061 # endif 10062 #endif 10063 #ifdef FEAT_GUI_KDE 10064 "gui_kde", 10065 #endif 10066 #ifdef FEAT_GUI_GTK 10067 "gui_gtk", 10068 # ifdef HAVE_GTK2 10069 "gui_gtk2", 10070 # endif 10071 #endif 10072 #ifdef FEAT_GUI_MAC 10073 "gui_mac", 10074 #endif 10075 #ifdef FEAT_GUI_MOTIF 10076 "gui_motif", 10077 #endif 10078 #ifdef FEAT_GUI_PHOTON 10079 "gui_photon", 10080 #endif 10081 #ifdef FEAT_GUI_W16 10082 "gui_win16", 10083 #endif 10084 #ifdef FEAT_GUI_W32 10085 "gui_win32", 10086 #endif 10087 #ifdef FEAT_HANGULIN 10088 "hangul_input", 10089 #endif 10090 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 10091 "iconv", 10092 #endif 10093 #ifdef FEAT_INS_EXPAND 10094 "insert_expand", 10095 #endif 10096 #ifdef FEAT_JUMPLIST 10097 "jumplist", 10098 #endif 10099 #ifdef FEAT_KEYMAP 10100 "keymap", 10101 #endif 10102 #ifdef FEAT_LANGMAP 10103 "langmap", 10104 #endif 10105 #ifdef FEAT_LIBCALL 10106 "libcall", 10107 #endif 10108 #ifdef FEAT_LINEBREAK 10109 "linebreak", 10110 #endif 10111 #ifdef FEAT_LISP 10112 "lispindent", 10113 #endif 10114 #ifdef FEAT_LISTCMDS 10115 "listcmds", 10116 #endif 10117 #ifdef FEAT_LOCALMAP 10118 "localmap", 10119 #endif 10120 #ifdef FEAT_MENU 10121 "menu", 10122 #endif 10123 #ifdef FEAT_SESSION 10124 "mksession", 10125 #endif 10126 #ifdef FEAT_MODIFY_FNAME 10127 "modify_fname", 10128 #endif 10129 #ifdef FEAT_MOUSE 10130 "mouse", 10131 #endif 10132 #ifdef FEAT_MOUSESHAPE 10133 "mouseshape", 10134 #endif 10135 #if defined(UNIX) || defined(VMS) 10136 # ifdef FEAT_MOUSE_DEC 10137 "mouse_dec", 10138 # endif 10139 # ifdef FEAT_MOUSE_GPM 10140 "mouse_gpm", 10141 # endif 10142 # ifdef FEAT_MOUSE_JSB 10143 "mouse_jsbterm", 10144 # endif 10145 # ifdef FEAT_MOUSE_NET 10146 "mouse_netterm", 10147 # endif 10148 # ifdef FEAT_MOUSE_PTERM 10149 "mouse_pterm", 10150 # endif 10151 # ifdef FEAT_MOUSE_XTERM 10152 "mouse_xterm", 10153 # endif 10154 #endif 10155 #ifdef FEAT_MBYTE 10156 "multi_byte", 10157 #endif 10158 #ifdef FEAT_MBYTE_IME 10159 "multi_byte_ime", 10160 #endif 10161 #ifdef FEAT_MULTI_LANG 10162 "multi_lang", 10163 #endif 10164 #ifdef FEAT_MZSCHEME 10165 #ifndef DYNAMIC_MZSCHEME 10166 "mzscheme", 10167 #endif 10168 #endif 10169 #ifdef FEAT_OLE 10170 "ole", 10171 #endif 10172 #ifdef FEAT_OSFILETYPE 10173 "osfiletype", 10174 #endif 10175 #ifdef FEAT_PATH_EXTRA 10176 "path_extra", 10177 #endif 10178 #ifdef FEAT_PERL 10179 #ifndef DYNAMIC_PERL 10180 "perl", 10181 #endif 10182 #endif 10183 #ifdef FEAT_PYTHON 10184 #ifndef DYNAMIC_PYTHON 10185 "python", 10186 #endif 10187 #endif 10188 #ifdef FEAT_POSTSCRIPT 10189 "postscript", 10190 #endif 10191 #ifdef FEAT_PRINTER 10192 "printer", 10193 #endif 10194 #ifdef FEAT_PROFILE 10195 "profile", 10196 #endif 10197 #ifdef FEAT_QUICKFIX 10198 "quickfix", 10199 #endif 10200 #ifdef FEAT_RIGHTLEFT 10201 "rightleft", 10202 #endif 10203 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 10204 "ruby", 10205 #endif 10206 #ifdef FEAT_SCROLLBIND 10207 "scrollbind", 10208 #endif 10209 #ifdef FEAT_CMDL_INFO 10210 "showcmd", 10211 "cmdline_info", 10212 #endif 10213 #ifdef FEAT_SIGNS 10214 "signs", 10215 #endif 10216 #ifdef FEAT_SMARTINDENT 10217 "smartindent", 10218 #endif 10219 #ifdef FEAT_SNIFF 10220 "sniff", 10221 #endif 10222 #ifdef FEAT_STL_OPT 10223 "statusline", 10224 #endif 10225 #ifdef FEAT_SUN_WORKSHOP 10226 "sun_workshop", 10227 #endif 10228 #ifdef FEAT_NETBEANS_INTG 10229 "netbeans_intg", 10230 #endif 10231 #ifdef FEAT_SYN_HL 10232 "spell", 10233 #endif 10234 #ifdef FEAT_SYN_HL 10235 "syntax", 10236 #endif 10237 #if defined(USE_SYSTEM) || !defined(UNIX) 10238 "system", 10239 #endif 10240 #ifdef FEAT_TAG_BINS 10241 "tag_binary", 10242 #endif 10243 #ifdef FEAT_TAG_OLDSTATIC 10244 "tag_old_static", 10245 #endif 10246 #ifdef FEAT_TAG_ANYWHITE 10247 "tag_any_white", 10248 #endif 10249 #ifdef FEAT_TCL 10250 # ifndef DYNAMIC_TCL 10251 "tcl", 10252 # endif 10253 #endif 10254 #ifdef TERMINFO 10255 "terminfo", 10256 #endif 10257 #ifdef FEAT_TERMRESPONSE 10258 "termresponse", 10259 #endif 10260 #ifdef FEAT_TEXTOBJ 10261 "textobjects", 10262 #endif 10263 #ifdef HAVE_TGETENT 10264 "tgetent", 10265 #endif 10266 #ifdef FEAT_TITLE 10267 "title", 10268 #endif 10269 #ifdef FEAT_TOOLBAR 10270 "toolbar", 10271 #endif 10272 #ifdef FEAT_USR_CMDS 10273 "user-commands", /* was accidentally included in 5.4 */ 10274 "user_commands", 10275 #endif 10276 #ifdef FEAT_VIMINFO 10277 "viminfo", 10278 #endif 10279 #ifdef FEAT_VERTSPLIT 10280 "vertsplit", 10281 #endif 10282 #ifdef FEAT_VIRTUALEDIT 10283 "virtualedit", 10284 #endif 10285 #ifdef FEAT_VISUAL 10286 "visual", 10287 #endif 10288 #ifdef FEAT_VISUALEXTRA 10289 "visualextra", 10290 #endif 10291 #ifdef FEAT_VREPLACE 10292 "vreplace", 10293 #endif 10294 #ifdef FEAT_WILDIGN 10295 "wildignore", 10296 #endif 10297 #ifdef FEAT_WILDMENU 10298 "wildmenu", 10299 #endif 10300 #ifdef FEAT_WINDOWS 10301 "windows", 10302 #endif 10303 #ifdef FEAT_WAK 10304 "winaltkeys", 10305 #endif 10306 #ifdef FEAT_WRITEBACKUP 10307 "writebackup", 10308 #endif 10309 #ifdef FEAT_XIM 10310 "xim", 10311 #endif 10312 #ifdef FEAT_XFONTSET 10313 "xfontset", 10314 #endif 10315 #ifdef USE_XSMP 10316 "xsmp", 10317 #endif 10318 #ifdef USE_XSMP_INTERACT 10319 "xsmp_interact", 10320 #endif 10321 #ifdef FEAT_XCLIPBOARD 10322 "xterm_clipboard", 10323 #endif 10324 #ifdef FEAT_XTERM_SAVE 10325 "xterm_save", 10326 #endif 10327 #if defined(UNIX) && defined(FEAT_X11) 10328 "X11", 10329 #endif 10330 NULL 10331 }; 10332 10333 name = get_tv_string(&argvars[0]); 10334 for (i = 0; has_list[i] != NULL; ++i) 10335 if (STRICMP(name, has_list[i]) == 0) 10336 { 10337 n = TRUE; 10338 break; 10339 } 10340 10341 if (n == FALSE) 10342 { 10343 if (STRNICMP(name, "patch", 5) == 0) 10344 n = has_patch(atoi((char *)name + 5)); 10345 else if (STRICMP(name, "vim_starting") == 0) 10346 n = (starting != 0); 10347 #if defined(FEAT_BEVAL) && defined(FEAT_GUI_W32) 10348 else if (STRICMP(name, "balloon_multiline") == 0) 10349 n = multiline_balloon_available(); 10350 #endif 10351 #ifdef DYNAMIC_TCL 10352 else if (STRICMP(name, "tcl") == 0) 10353 n = tcl_enabled(FALSE); 10354 #endif 10355 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 10356 else if (STRICMP(name, "iconv") == 0) 10357 n = iconv_enabled(FALSE); 10358 #endif 10359 #ifdef DYNAMIC_MZSCHEME 10360 else if (STRICMP(name, "mzscheme") == 0) 10361 n = mzscheme_enabled(FALSE); 10362 #endif 10363 #ifdef DYNAMIC_RUBY 10364 else if (STRICMP(name, "ruby") == 0) 10365 n = ruby_enabled(FALSE); 10366 #endif 10367 #ifdef DYNAMIC_PYTHON 10368 else if (STRICMP(name, "python") == 0) 10369 n = python_enabled(FALSE); 10370 #endif 10371 #ifdef DYNAMIC_PERL 10372 else if (STRICMP(name, "perl") == 0) 10373 n = perl_enabled(FALSE); 10374 #endif 10375 #ifdef FEAT_GUI 10376 else if (STRICMP(name, "gui_running") == 0) 10377 n = (gui.in_use || gui.starting); 10378 # ifdef FEAT_GUI_W32 10379 else if (STRICMP(name, "gui_win32s") == 0) 10380 n = gui_is_win32s(); 10381 # endif 10382 # ifdef FEAT_BROWSE 10383 else if (STRICMP(name, "browse") == 0) 10384 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 10385 # endif 10386 #endif 10387 #ifdef FEAT_SYN_HL 10388 else if (STRICMP(name, "syntax_items") == 0) 10389 n = syntax_present(curbuf); 10390 #endif 10391 #if defined(WIN3264) 10392 else if (STRICMP(name, "win95") == 0) 10393 n = mch_windows95(); 10394 #endif 10395 #ifdef FEAT_NETBEANS_INTG 10396 else if (STRICMP(name, "netbeans_enabled") == 0) 10397 n = usingNetbeans; 10398 #endif 10399 } 10400 10401 rettv->vval.v_number = n; 10402 } 10403 10404 /* 10405 * "has_key()" function 10406 */ 10407 static void 10408 f_has_key(argvars, rettv) 10409 typval_T *argvars; 10410 typval_T *rettv; 10411 { 10412 rettv->vval.v_number = 0; 10413 if (argvars[0].v_type != VAR_DICT) 10414 { 10415 EMSG(_(e_dictreq)); 10416 return; 10417 } 10418 if (argvars[0].vval.v_dict == NULL) 10419 return; 10420 10421 rettv->vval.v_number = dict_find(argvars[0].vval.v_dict, 10422 get_tv_string(&argvars[1]), -1) != NULL; 10423 } 10424 10425 /* 10426 * "hasmapto()" function 10427 */ 10428 static void 10429 f_hasmapto(argvars, rettv) 10430 typval_T *argvars; 10431 typval_T *rettv; 10432 { 10433 char_u *name; 10434 char_u *mode; 10435 char_u buf[NUMBUFLEN]; 10436 10437 name = get_tv_string(&argvars[0]); 10438 if (argvars[1].v_type == VAR_UNKNOWN) 10439 mode = (char_u *)"nvo"; 10440 else 10441 mode = get_tv_string_buf(&argvars[1], buf); 10442 10443 if (map_to_exists(name, mode)) 10444 rettv->vval.v_number = TRUE; 10445 else 10446 rettv->vval.v_number = FALSE; 10447 } 10448 10449 /* 10450 * "histadd()" function 10451 */ 10452 /*ARGSUSED*/ 10453 static void 10454 f_histadd(argvars, rettv) 10455 typval_T *argvars; 10456 typval_T *rettv; 10457 { 10458 #ifdef FEAT_CMDHIST 10459 int histype; 10460 char_u *str; 10461 char_u buf[NUMBUFLEN]; 10462 #endif 10463 10464 rettv->vval.v_number = FALSE; 10465 if (check_restricted() || check_secure()) 10466 return; 10467 #ifdef FEAT_CMDHIST 10468 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10469 histype = str != NULL ? get_histtype(str) : -1; 10470 if (histype >= 0) 10471 { 10472 str = get_tv_string_buf(&argvars[1], buf); 10473 if (*str != NUL) 10474 { 10475 add_to_history(histype, str, FALSE, NUL); 10476 rettv->vval.v_number = TRUE; 10477 return; 10478 } 10479 } 10480 #endif 10481 } 10482 10483 /* 10484 * "histdel()" function 10485 */ 10486 /*ARGSUSED*/ 10487 static void 10488 f_histdel(argvars, rettv) 10489 typval_T *argvars; 10490 typval_T *rettv; 10491 { 10492 #ifdef FEAT_CMDHIST 10493 int n; 10494 char_u buf[NUMBUFLEN]; 10495 char_u *str; 10496 10497 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10498 if (str == NULL) 10499 n = 0; 10500 else if (argvars[1].v_type == VAR_UNKNOWN) 10501 /* only one argument: clear entire history */ 10502 n = clr_history(get_histtype(str)); 10503 else if (argvars[1].v_type == VAR_NUMBER) 10504 /* index given: remove that entry */ 10505 n = del_history_idx(get_histtype(str), 10506 (int)get_tv_number(&argvars[1])); 10507 else 10508 /* string given: remove all matching entries */ 10509 n = del_history_entry(get_histtype(str), 10510 get_tv_string_buf(&argvars[1], buf)); 10511 rettv->vval.v_number = n; 10512 #else 10513 rettv->vval.v_number = 0; 10514 #endif 10515 } 10516 10517 /* 10518 * "histget()" function 10519 */ 10520 /*ARGSUSED*/ 10521 static void 10522 f_histget(argvars, rettv) 10523 typval_T *argvars; 10524 typval_T *rettv; 10525 { 10526 #ifdef FEAT_CMDHIST 10527 int type; 10528 int idx; 10529 char_u *str; 10530 10531 str = get_tv_string_chk(&argvars[0]); /* NULL on type error */ 10532 if (str == NULL) 10533 rettv->vval.v_string = NULL; 10534 else 10535 { 10536 type = get_histtype(str); 10537 if (argvars[1].v_type == VAR_UNKNOWN) 10538 idx = get_history_idx(type); 10539 else 10540 idx = (int)get_tv_number_chk(&argvars[1], NULL); 10541 /* -1 on type error */ 10542 rettv->vval.v_string = vim_strsave(get_history_entry(type, idx)); 10543 } 10544 #else 10545 rettv->vval.v_string = NULL; 10546 #endif 10547 rettv->v_type = VAR_STRING; 10548 } 10549 10550 /* 10551 * "histnr()" function 10552 */ 10553 /*ARGSUSED*/ 10554 static void 10555 f_histnr(argvars, rettv) 10556 typval_T *argvars; 10557 typval_T *rettv; 10558 { 10559 int i; 10560 10561 #ifdef FEAT_CMDHIST 10562 char_u *history = get_tv_string_chk(&argvars[0]); 10563 10564 i = history == NULL ? HIST_CMD - 1 : get_histtype(history); 10565 if (i >= HIST_CMD && i < HIST_COUNT) 10566 i = get_history_idx(i); 10567 else 10568 #endif 10569 i = -1; 10570 rettv->vval.v_number = i; 10571 } 10572 10573 /* 10574 * "highlightID(name)" function 10575 */ 10576 static void 10577 f_hlID(argvars, rettv) 10578 typval_T *argvars; 10579 typval_T *rettv; 10580 { 10581 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0])); 10582 } 10583 10584 /* 10585 * "highlight_exists()" function 10586 */ 10587 static void 10588 f_hlexists(argvars, rettv) 10589 typval_T *argvars; 10590 typval_T *rettv; 10591 { 10592 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 10593 } 10594 10595 /* 10596 * "hostname()" function 10597 */ 10598 /*ARGSUSED*/ 10599 static void 10600 f_hostname(argvars, rettv) 10601 typval_T *argvars; 10602 typval_T *rettv; 10603 { 10604 char_u hostname[256]; 10605 10606 mch_get_host_name(hostname, 256); 10607 rettv->v_type = VAR_STRING; 10608 rettv->vval.v_string = vim_strsave(hostname); 10609 } 10610 10611 /* 10612 * iconv() function 10613 */ 10614 /*ARGSUSED*/ 10615 static void 10616 f_iconv(argvars, rettv) 10617 typval_T *argvars; 10618 typval_T *rettv; 10619 { 10620 #ifdef FEAT_MBYTE 10621 char_u buf1[NUMBUFLEN]; 10622 char_u buf2[NUMBUFLEN]; 10623 char_u *from, *to, *str; 10624 vimconv_T vimconv; 10625 #endif 10626 10627 rettv->v_type = VAR_STRING; 10628 rettv->vval.v_string = NULL; 10629 10630 #ifdef FEAT_MBYTE 10631 str = get_tv_string(&argvars[0]); 10632 from = enc_canonize(enc_skip(get_tv_string_buf(&argvars[1], buf1))); 10633 to = enc_canonize(enc_skip(get_tv_string_buf(&argvars[2], buf2))); 10634 vimconv.vc_type = CONV_NONE; 10635 convert_setup(&vimconv, from, to); 10636 10637 /* If the encodings are equal, no conversion needed. */ 10638 if (vimconv.vc_type == CONV_NONE) 10639 rettv->vval.v_string = vim_strsave(str); 10640 else 10641 rettv->vval.v_string = string_convert(&vimconv, str, NULL); 10642 10643 convert_setup(&vimconv, NULL, NULL); 10644 vim_free(from); 10645 vim_free(to); 10646 #endif 10647 } 10648 10649 /* 10650 * "indent()" function 10651 */ 10652 static void 10653 f_indent(argvars, rettv) 10654 typval_T *argvars; 10655 typval_T *rettv; 10656 { 10657 linenr_T lnum; 10658 10659 lnum = get_tv_lnum(argvars); 10660 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 10661 rettv->vval.v_number = get_indent_lnum(lnum); 10662 else 10663 rettv->vval.v_number = -1; 10664 } 10665 10666 /* 10667 * "index()" function 10668 */ 10669 static void 10670 f_index(argvars, rettv) 10671 typval_T *argvars; 10672 typval_T *rettv; 10673 { 10674 list_T *l; 10675 listitem_T *item; 10676 long idx = 0; 10677 int ic = FALSE; 10678 10679 rettv->vval.v_number = -1; 10680 if (argvars[0].v_type != VAR_LIST) 10681 { 10682 EMSG(_(e_listreq)); 10683 return; 10684 } 10685 l = argvars[0].vval.v_list; 10686 if (l != NULL) 10687 { 10688 item = l->lv_first; 10689 if (argvars[2].v_type != VAR_UNKNOWN) 10690 { 10691 int error = FALSE; 10692 10693 /* Start at specified item. Use the cached index that list_find() 10694 * sets, so that a negative number also works. */ 10695 item = list_find(l, get_tv_number_chk(&argvars[2], &error)); 10696 idx = l->lv_idx; 10697 if (argvars[3].v_type != VAR_UNKNOWN) 10698 ic = get_tv_number_chk(&argvars[3], &error); 10699 if (error) 10700 item = NULL; 10701 } 10702 10703 for ( ; item != NULL; item = item->li_next, ++idx) 10704 if (tv_equal(&item->li_tv, &argvars[1], ic)) 10705 { 10706 rettv->vval.v_number = idx; 10707 break; 10708 } 10709 } 10710 } 10711 10712 static int inputsecret_flag = 0; 10713 10714 /* 10715 * "input()" function 10716 * Also handles inputsecret() when inputsecret is set. 10717 */ 10718 static void 10719 f_input(argvars, rettv) 10720 typval_T *argvars; 10721 typval_T *rettv; 10722 { 10723 char_u *prompt = get_tv_string_chk(&argvars[0]); 10724 char_u *p = NULL; 10725 int c; 10726 char_u buf[NUMBUFLEN]; 10727 int cmd_silent_save = cmd_silent; 10728 char_u *defstr = (char_u *)""; 10729 10730 rettv->v_type = VAR_STRING; 10731 10732 #ifdef NO_CONSOLE_INPUT 10733 /* While starting up, there is no place to enter text. */ 10734 if (no_console_input()) 10735 { 10736 rettv->vval.v_string = NULL; 10737 return; 10738 } 10739 #endif 10740 10741 cmd_silent = FALSE; /* Want to see the prompt. */ 10742 if (prompt != NULL) 10743 { 10744 /* Only the part of the message after the last NL is considered as 10745 * prompt for the command line */ 10746 p = vim_strrchr(prompt, '\n'); 10747 if (p == NULL) 10748 p = prompt; 10749 else 10750 { 10751 ++p; 10752 c = *p; 10753 *p = NUL; 10754 msg_start(); 10755 msg_clr_eos(); 10756 msg_puts_attr(prompt, echo_attr); 10757 msg_didout = FALSE; 10758 msg_starthere(); 10759 *p = c; 10760 } 10761 cmdline_row = msg_row; 10762 10763 if (argvars[1].v_type != VAR_UNKNOWN) 10764 { 10765 defstr = get_tv_string_buf_chk(&argvars[1], buf); 10766 if (defstr != NULL) 10767 stuffReadbuffSpec(defstr); 10768 } 10769 10770 if (defstr != NULL) 10771 rettv->vval.v_string = 10772 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr); 10773 10774 /* since the user typed this, no need to wait for return */ 10775 need_wait_return = FALSE; 10776 msg_didout = FALSE; 10777 } 10778 cmd_silent = cmd_silent_save; 10779 } 10780 10781 /* 10782 * "inputdialog()" function 10783 */ 10784 static void 10785 f_inputdialog(argvars, rettv) 10786 typval_T *argvars; 10787 typval_T *rettv; 10788 { 10789 #if defined(FEAT_GUI_TEXTDIALOG) 10790 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 10791 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 10792 { 10793 char_u *message; 10794 char_u buf[NUMBUFLEN]; 10795 char_u *defstr = (char_u *)""; 10796 10797 message = get_tv_string_chk(&argvars[0]); 10798 if (argvars[1].v_type != VAR_UNKNOWN 10799 && (defstr = get_tv_string_buf_chk(&argvars[1], buf)) != NULL) 10800 vim_strncpy(IObuff, defstr, IOSIZE - 1); 10801 else 10802 IObuff[0] = NUL; 10803 if (message != NULL && defstr != NULL 10804 && do_dialog(VIM_QUESTION, NULL, message, 10805 (char_u *)_("&OK\n&Cancel"), 1, IObuff) == 1) 10806 rettv->vval.v_string = vim_strsave(IObuff); 10807 else 10808 { 10809 if (message != NULL && defstr != NULL 10810 && argvars[1].v_type != VAR_UNKNOWN 10811 && argvars[2].v_type != VAR_UNKNOWN) 10812 rettv->vval.v_string = vim_strsave( 10813 get_tv_string_buf(&argvars[2], buf)); 10814 else 10815 rettv->vval.v_string = NULL; 10816 } 10817 rettv->v_type = VAR_STRING; 10818 } 10819 else 10820 #endif 10821 f_input(argvars, rettv); 10822 } 10823 10824 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 10825 10826 /* 10827 * "inputrestore()" function 10828 */ 10829 /*ARGSUSED*/ 10830 static void 10831 f_inputrestore(argvars, rettv) 10832 typval_T *argvars; 10833 typval_T *rettv; 10834 { 10835 if (ga_userinput.ga_len > 0) 10836 { 10837 --ga_userinput.ga_len; 10838 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 10839 + ga_userinput.ga_len); 10840 rettv->vval.v_number = 0; /* OK */ 10841 } 10842 else if (p_verbose > 1) 10843 { 10844 verb_msg((char_u *)_("called inputrestore() more often than inputsave()")); 10845 rettv->vval.v_number = 1; /* Failed */ 10846 } 10847 } 10848 10849 /* 10850 * "inputsave()" function 10851 */ 10852 /*ARGSUSED*/ 10853 static void 10854 f_inputsave(argvars, rettv) 10855 typval_T *argvars; 10856 typval_T *rettv; 10857 { 10858 /* Add an entry to the stack of typehead storage. */ 10859 if (ga_grow(&ga_userinput, 1) == OK) 10860 { 10861 save_typeahead((tasave_T *)(ga_userinput.ga_data) 10862 + ga_userinput.ga_len); 10863 ++ga_userinput.ga_len; 10864 rettv->vval.v_number = 0; /* OK */ 10865 } 10866 else 10867 rettv->vval.v_number = 1; /* Failed */ 10868 } 10869 10870 /* 10871 * "inputsecret()" function 10872 */ 10873 static void 10874 f_inputsecret(argvars, rettv) 10875 typval_T *argvars; 10876 typval_T *rettv; 10877 { 10878 ++cmdline_star; 10879 ++inputsecret_flag; 10880 f_input(argvars, rettv); 10881 --cmdline_star; 10882 --inputsecret_flag; 10883 } 10884 10885 /* 10886 * "insert()" function 10887 */ 10888 static void 10889 f_insert(argvars, rettv) 10890 typval_T *argvars; 10891 typval_T *rettv; 10892 { 10893 long before = 0; 10894 listitem_T *item; 10895 list_T *l; 10896 int error = FALSE; 10897 10898 rettv->vval.v_number = 0; 10899 if (argvars[0].v_type != VAR_LIST) 10900 EMSG2(_(e_listarg), "insert()"); 10901 else if ((l = argvars[0].vval.v_list) != NULL 10902 && !tv_check_lock(l->lv_lock, (char_u *)"insert()")) 10903 { 10904 if (argvars[2].v_type != VAR_UNKNOWN) 10905 before = get_tv_number_chk(&argvars[2], &error); 10906 if (error) 10907 return; /* type error; errmsg already given */ 10908 10909 if (before == l->lv_len) 10910 item = NULL; 10911 else 10912 { 10913 item = list_find(l, before); 10914 if (item == NULL) 10915 { 10916 EMSGN(_(e_listidx), before); 10917 l = NULL; 10918 } 10919 } 10920 if (l != NULL) 10921 { 10922 list_insert_tv(l, &argvars[1], item); 10923 copy_tv(&argvars[0], rettv); 10924 } 10925 } 10926 } 10927 10928 /* 10929 * "isdirectory()" function 10930 */ 10931 static void 10932 f_isdirectory(argvars, rettv) 10933 typval_T *argvars; 10934 typval_T *rettv; 10935 { 10936 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); 10937 } 10938 10939 /* 10940 * "islocked()" function 10941 */ 10942 static void 10943 f_islocked(argvars, rettv) 10944 typval_T *argvars; 10945 typval_T *rettv; 10946 { 10947 lval_T lv; 10948 char_u *end; 10949 dictitem_T *di; 10950 10951 rettv->vval.v_number = -1; 10952 end = get_lval(get_tv_string(&argvars[0]), NULL, &lv, FALSE, FALSE, FALSE, 10953 FNE_CHECK_START); 10954 if (end != NULL && lv.ll_name != NULL) 10955 { 10956 if (*end != NUL) 10957 EMSG(_(e_trailing)); 10958 else 10959 { 10960 if (lv.ll_tv == NULL) 10961 { 10962 if (check_changedtick(lv.ll_name)) 10963 rettv->vval.v_number = 1; /* always locked */ 10964 else 10965 { 10966 di = find_var(lv.ll_name, NULL); 10967 if (di != NULL) 10968 { 10969 /* Consider a variable locked when: 10970 * 1. the variable itself is locked 10971 * 2. the value of the variable is locked. 10972 * 3. the List or Dict value is locked. 10973 */ 10974 rettv->vval.v_number = ((di->di_flags & DI_FLAGS_LOCK) 10975 || tv_islocked(&di->di_tv)); 10976 } 10977 } 10978 } 10979 else if (lv.ll_range) 10980 EMSG(_("E745: Range not allowed")); 10981 else if (lv.ll_newkey != NULL) 10982 EMSG2(_(e_dictkey), lv.ll_newkey); 10983 else if (lv.ll_list != NULL) 10984 /* List item. */ 10985 rettv->vval.v_number = tv_islocked(&lv.ll_li->li_tv); 10986 else 10987 /* Dictionary item. */ 10988 rettv->vval.v_number = tv_islocked(&lv.ll_di->di_tv); 10989 } 10990 } 10991 10992 clear_lval(&lv); 10993 } 10994 10995 static void dict_list __ARGS((typval_T *argvars, typval_T *rettv, int what)); 10996 10997 /* 10998 * Turn a dict into a list: 10999 * "what" == 0: list of keys 11000 * "what" == 1: list of values 11001 * "what" == 2: list of items 11002 */ 11003 static void 11004 dict_list(argvars, rettv, what) 11005 typval_T *argvars; 11006 typval_T *rettv; 11007 int what; 11008 { 11009 list_T *l; 11010 list_T *l2; 11011 dictitem_T *di; 11012 hashitem_T *hi; 11013 listitem_T *li; 11014 listitem_T *li2; 11015 dict_T *d; 11016 int todo; 11017 11018 rettv->vval.v_number = 0; 11019 if (argvars[0].v_type != VAR_DICT) 11020 { 11021 EMSG(_(e_dictreq)); 11022 return; 11023 } 11024 if ((d = argvars[0].vval.v_dict) == NULL) 11025 return; 11026 11027 l = list_alloc(); 11028 if (l == NULL) 11029 return; 11030 rettv->v_type = VAR_LIST; 11031 rettv->vval.v_list = l; 11032 ++l->lv_refcount; 11033 11034 todo = d->dv_hashtab.ht_used; 11035 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11036 { 11037 if (!HASHITEM_EMPTY(hi)) 11038 { 11039 --todo; 11040 di = HI2DI(hi); 11041 11042 li = listitem_alloc(); 11043 if (li == NULL) 11044 break; 11045 list_append(l, li); 11046 11047 if (what == 0) 11048 { 11049 /* keys() */ 11050 li->li_tv.v_type = VAR_STRING; 11051 li->li_tv.v_lock = 0; 11052 li->li_tv.vval.v_string = vim_strsave(di->di_key); 11053 } 11054 else if (what == 1) 11055 { 11056 /* values() */ 11057 copy_tv(&di->di_tv, &li->li_tv); 11058 } 11059 else 11060 { 11061 /* items() */ 11062 l2 = list_alloc(); 11063 li->li_tv.v_type = VAR_LIST; 11064 li->li_tv.v_lock = 0; 11065 li->li_tv.vval.v_list = l2; 11066 if (l2 == NULL) 11067 break; 11068 ++l2->lv_refcount; 11069 11070 li2 = listitem_alloc(); 11071 if (li2 == NULL) 11072 break; 11073 list_append(l2, li2); 11074 li2->li_tv.v_type = VAR_STRING; 11075 li2->li_tv.v_lock = 0; 11076 li2->li_tv.vval.v_string = vim_strsave(di->di_key); 11077 11078 li2 = listitem_alloc(); 11079 if (li2 == NULL) 11080 break; 11081 list_append(l2, li2); 11082 copy_tv(&di->di_tv, &li2->li_tv); 11083 } 11084 } 11085 } 11086 } 11087 11088 /* 11089 * "items(dict)" function 11090 */ 11091 static void 11092 f_items(argvars, rettv) 11093 typval_T *argvars; 11094 typval_T *rettv; 11095 { 11096 dict_list(argvars, rettv, 2); 11097 } 11098 11099 /* 11100 * "join()" function 11101 */ 11102 static void 11103 f_join(argvars, rettv) 11104 typval_T *argvars; 11105 typval_T *rettv; 11106 { 11107 garray_T ga; 11108 char_u *sep; 11109 11110 rettv->vval.v_number = 0; 11111 if (argvars[0].v_type != VAR_LIST) 11112 { 11113 EMSG(_(e_listreq)); 11114 return; 11115 } 11116 if (argvars[0].vval.v_list == NULL) 11117 return; 11118 if (argvars[1].v_type == VAR_UNKNOWN) 11119 sep = (char_u *)" "; 11120 else 11121 sep = get_tv_string_chk(&argvars[1]); 11122 11123 rettv->v_type = VAR_STRING; 11124 11125 if (sep != NULL) 11126 { 11127 ga_init2(&ga, (int)sizeof(char), 80); 11128 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); 11129 ga_append(&ga, NUL); 11130 rettv->vval.v_string = (char_u *)ga.ga_data; 11131 } 11132 else 11133 rettv->vval.v_string = NULL; 11134 } 11135 11136 /* 11137 * "keys()" function 11138 */ 11139 static void 11140 f_keys(argvars, rettv) 11141 typval_T *argvars; 11142 typval_T *rettv; 11143 { 11144 dict_list(argvars, rettv, 0); 11145 } 11146 11147 /* 11148 * "last_buffer_nr()" function. 11149 */ 11150 /*ARGSUSED*/ 11151 static void 11152 f_last_buffer_nr(argvars, rettv) 11153 typval_T *argvars; 11154 typval_T *rettv; 11155 { 11156 int n = 0; 11157 buf_T *buf; 11158 11159 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 11160 if (n < buf->b_fnum) 11161 n = buf->b_fnum; 11162 11163 rettv->vval.v_number = n; 11164 } 11165 11166 /* 11167 * "len()" function 11168 */ 11169 static void 11170 f_len(argvars, rettv) 11171 typval_T *argvars; 11172 typval_T *rettv; 11173 { 11174 switch (argvars[0].v_type) 11175 { 11176 case VAR_STRING: 11177 case VAR_NUMBER: 11178 rettv->vval.v_number = (varnumber_T)STRLEN( 11179 get_tv_string(&argvars[0])); 11180 break; 11181 case VAR_LIST: 11182 rettv->vval.v_number = list_len(argvars[0].vval.v_list); 11183 break; 11184 case VAR_DICT: 11185 rettv->vval.v_number = dict_len(argvars[0].vval.v_dict); 11186 break; 11187 default: 11188 EMSG(_("E701: Invalid type for len()")); 11189 break; 11190 } 11191 } 11192 11193 static void libcall_common __ARGS((typval_T *argvars, typval_T *rettv, int type)); 11194 11195 static void 11196 libcall_common(argvars, rettv, type) 11197 typval_T *argvars; 11198 typval_T *rettv; 11199 int type; 11200 { 11201 #ifdef FEAT_LIBCALL 11202 char_u *string_in; 11203 char_u **string_result; 11204 int nr_result; 11205 #endif 11206 11207 rettv->v_type = type; 11208 if (type == VAR_NUMBER) 11209 rettv->vval.v_number = 0; 11210 else 11211 rettv->vval.v_string = NULL; 11212 11213 if (check_restricted() || check_secure()) 11214 return; 11215 11216 #ifdef FEAT_LIBCALL 11217 /* The first two args must be strings, otherwise its meaningless */ 11218 if (argvars[0].v_type == VAR_STRING && argvars[1].v_type == VAR_STRING) 11219 { 11220 string_in = NULL; 11221 if (argvars[2].v_type == VAR_STRING) 11222 string_in = argvars[2].vval.v_string; 11223 if (type == VAR_NUMBER) 11224 string_result = NULL; 11225 else 11226 string_result = &rettv->vval.v_string; 11227 if (mch_libcall(argvars[0].vval.v_string, 11228 argvars[1].vval.v_string, 11229 string_in, 11230 argvars[2].vval.v_number, 11231 string_result, 11232 &nr_result) == OK 11233 && type == VAR_NUMBER) 11234 rettv->vval.v_number = nr_result; 11235 } 11236 #endif 11237 } 11238 11239 /* 11240 * "libcall()" function 11241 */ 11242 static void 11243 f_libcall(argvars, rettv) 11244 typval_T *argvars; 11245 typval_T *rettv; 11246 { 11247 libcall_common(argvars, rettv, VAR_STRING); 11248 } 11249 11250 /* 11251 * "libcallnr()" function 11252 */ 11253 static void 11254 f_libcallnr(argvars, rettv) 11255 typval_T *argvars; 11256 typval_T *rettv; 11257 { 11258 libcall_common(argvars, rettv, VAR_NUMBER); 11259 } 11260 11261 /* 11262 * "line(string)" function 11263 */ 11264 static void 11265 f_line(argvars, rettv) 11266 typval_T *argvars; 11267 typval_T *rettv; 11268 { 11269 linenr_T lnum = 0; 11270 pos_T *fp; 11271 11272 fp = var2fpos(&argvars[0], TRUE); 11273 if (fp != NULL) 11274 lnum = fp->lnum; 11275 rettv->vval.v_number = lnum; 11276 } 11277 11278 /* 11279 * "line2byte(lnum)" function 11280 */ 11281 /*ARGSUSED*/ 11282 static void 11283 f_line2byte(argvars, rettv) 11284 typval_T *argvars; 11285 typval_T *rettv; 11286 { 11287 #ifndef FEAT_BYTEOFF 11288 rettv->vval.v_number = -1; 11289 #else 11290 linenr_T lnum; 11291 11292 lnum = get_tv_lnum(argvars); 11293 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 11294 rettv->vval.v_number = -1; 11295 else 11296 rettv->vval.v_number = ml_find_line_or_offset(curbuf, lnum, NULL); 11297 if (rettv->vval.v_number >= 0) 11298 ++rettv->vval.v_number; 11299 #endif 11300 } 11301 11302 /* 11303 * "lispindent(lnum)" function 11304 */ 11305 static void 11306 f_lispindent(argvars, rettv) 11307 typval_T *argvars; 11308 typval_T *rettv; 11309 { 11310 #ifdef FEAT_LISP 11311 pos_T pos; 11312 linenr_T lnum; 11313 11314 pos = curwin->w_cursor; 11315 lnum = get_tv_lnum(argvars); 11316 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 11317 { 11318 curwin->w_cursor.lnum = lnum; 11319 rettv->vval.v_number = get_lisp_indent(); 11320 curwin->w_cursor = pos; 11321 } 11322 else 11323 #endif 11324 rettv->vval.v_number = -1; 11325 } 11326 11327 /* 11328 * "localtime()" function 11329 */ 11330 /*ARGSUSED*/ 11331 static void 11332 f_localtime(argvars, rettv) 11333 typval_T *argvars; 11334 typval_T *rettv; 11335 { 11336 rettv->vval.v_number = (varnumber_T)time(NULL); 11337 } 11338 11339 static void get_maparg __ARGS((typval_T *argvars, typval_T *rettv, int exact)); 11340 11341 static void 11342 get_maparg(argvars, rettv, exact) 11343 typval_T *argvars; 11344 typval_T *rettv; 11345 int exact; 11346 { 11347 char_u *keys; 11348 char_u *which; 11349 char_u buf[NUMBUFLEN]; 11350 char_u *keys_buf = NULL; 11351 char_u *rhs; 11352 int mode; 11353 garray_T ga; 11354 11355 /* return empty string for failure */ 11356 rettv->v_type = VAR_STRING; 11357 rettv->vval.v_string = NULL; 11358 11359 keys = get_tv_string(&argvars[0]); 11360 if (*keys == NUL) 11361 return; 11362 11363 if (argvars[1].v_type != VAR_UNKNOWN) 11364 which = get_tv_string_buf_chk(&argvars[1], buf); 11365 else 11366 which = (char_u *)""; 11367 if (which == NULL) 11368 return; 11369 11370 mode = get_map_mode(&which, 0); 11371 11372 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 11373 rhs = check_map(keys, mode, exact, FALSE); 11374 vim_free(keys_buf); 11375 if (rhs != NULL) 11376 { 11377 ga_init(&ga); 11378 ga.ga_itemsize = 1; 11379 ga.ga_growsize = 40; 11380 11381 while (*rhs != NUL) 11382 ga_concat(&ga, str2special(&rhs, FALSE)); 11383 11384 ga_append(&ga, NUL); 11385 rettv->vval.v_string = (char_u *)ga.ga_data; 11386 } 11387 } 11388 11389 /* 11390 * "map()" function 11391 */ 11392 static void 11393 f_map(argvars, rettv) 11394 typval_T *argvars; 11395 typval_T *rettv; 11396 { 11397 filter_map(argvars, rettv, TRUE); 11398 } 11399 11400 /* 11401 * "maparg()" function 11402 */ 11403 static void 11404 f_maparg(argvars, rettv) 11405 typval_T *argvars; 11406 typval_T *rettv; 11407 { 11408 get_maparg(argvars, rettv, TRUE); 11409 } 11410 11411 /* 11412 * "mapcheck()" function 11413 */ 11414 static void 11415 f_mapcheck(argvars, rettv) 11416 typval_T *argvars; 11417 typval_T *rettv; 11418 { 11419 get_maparg(argvars, rettv, FALSE); 11420 } 11421 11422 static void find_some_match __ARGS((typval_T *argvars, typval_T *rettv, int start)); 11423 11424 static void 11425 find_some_match(argvars, rettv, type) 11426 typval_T *argvars; 11427 typval_T *rettv; 11428 int type; 11429 { 11430 char_u *str = NULL; 11431 char_u *expr = NULL; 11432 char_u *pat; 11433 regmatch_T regmatch; 11434 char_u patbuf[NUMBUFLEN]; 11435 char_u strbuf[NUMBUFLEN]; 11436 char_u *save_cpo; 11437 long start = 0; 11438 long nth = 1; 11439 int match = 0; 11440 list_T *l = NULL; 11441 listitem_T *li = NULL; 11442 long idx = 0; 11443 char_u *tofree = NULL; 11444 11445 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 11446 save_cpo = p_cpo; 11447 p_cpo = (char_u *)""; 11448 11449 rettv->vval.v_number = -1; 11450 if (type == 3) 11451 { 11452 /* return empty list when there are no matches */ 11453 if ((rettv->vval.v_list = list_alloc()) == NULL) 11454 goto theend; 11455 rettv->v_type = VAR_LIST; 11456 ++rettv->vval.v_list->lv_refcount; 11457 } 11458 else if (type == 2) 11459 { 11460 rettv->v_type = VAR_STRING; 11461 rettv->vval.v_string = NULL; 11462 } 11463 11464 if (argvars[0].v_type == VAR_LIST) 11465 { 11466 if ((l = argvars[0].vval.v_list) == NULL) 11467 goto theend; 11468 li = l->lv_first; 11469 } 11470 else 11471 expr = str = get_tv_string(&argvars[0]); 11472 11473 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 11474 if (pat == NULL) 11475 goto theend; 11476 11477 if (argvars[2].v_type != VAR_UNKNOWN) 11478 { 11479 int error = FALSE; 11480 11481 start = get_tv_number_chk(&argvars[2], &error); 11482 if (error) 11483 goto theend; 11484 if (l != NULL) 11485 { 11486 li = list_find(l, start); 11487 if (li == NULL) 11488 goto theend; 11489 idx = l->lv_idx; /* use the cached index */ 11490 } 11491 else 11492 { 11493 if (start < 0) 11494 start = 0; 11495 if (start > (long)STRLEN(str)) 11496 goto theend; 11497 str += start; 11498 } 11499 11500 if (argvars[3].v_type != VAR_UNKNOWN) 11501 nth = get_tv_number_chk(&argvars[3], &error); 11502 if (error) 11503 goto theend; 11504 } 11505 11506 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 11507 if (regmatch.regprog != NULL) 11508 { 11509 regmatch.rm_ic = p_ic; 11510 11511 for (;;) 11512 { 11513 if (l != NULL) 11514 { 11515 if (li == NULL) 11516 { 11517 match = FALSE; 11518 break; 11519 } 11520 vim_free(tofree); 11521 str = echo_string(&li->li_tv, &tofree, strbuf); 11522 if (str == NULL) 11523 break; 11524 } 11525 11526 match = vim_regexec_nl(®match, str, (colnr_T)0); 11527 11528 if (match && --nth <= 0) 11529 break; 11530 if (l == NULL && !match) 11531 break; 11532 11533 /* Advance to just after the match. */ 11534 if (l != NULL) 11535 { 11536 li = li->li_next; 11537 ++idx; 11538 } 11539 else 11540 { 11541 #ifdef FEAT_MBYTE 11542 str = regmatch.startp[0] + mb_ptr2len_check(regmatch.startp[0]); 11543 #else 11544 str = regmatch.startp[0] + 1; 11545 #endif 11546 } 11547 } 11548 11549 if (match) 11550 { 11551 if (type == 3) 11552 { 11553 int i; 11554 11555 /* return list with matched string and submatches */ 11556 for (i = 0; i < NSUBEXP; ++i) 11557 { 11558 if (regmatch.endp[i] == NULL) 11559 break; 11560 li = listitem_alloc(); 11561 if (li == NULL) 11562 break; 11563 li->li_tv.v_type = VAR_STRING; 11564 li->li_tv.v_lock = 0; 11565 li->li_tv.vval.v_string = vim_strnsave(regmatch.startp[i], 11566 (int)(regmatch.endp[i] - regmatch.startp[i])); 11567 list_append(rettv->vval.v_list, li); 11568 } 11569 } 11570 else if (type == 2) 11571 { 11572 /* return matched string */ 11573 if (l != NULL) 11574 copy_tv(&li->li_tv, rettv); 11575 else 11576 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], 11577 (int)(regmatch.endp[0] - regmatch.startp[0])); 11578 } 11579 else if (l != NULL) 11580 rettv->vval.v_number = idx; 11581 else 11582 { 11583 if (type != 0) 11584 rettv->vval.v_number = 11585 (varnumber_T)(regmatch.startp[0] - str); 11586 else 11587 rettv->vval.v_number = 11588 (varnumber_T)(regmatch.endp[0] - str); 11589 rettv->vval.v_number += str - expr; 11590 } 11591 } 11592 vim_free(regmatch.regprog); 11593 } 11594 11595 theend: 11596 vim_free(tofree); 11597 p_cpo = save_cpo; 11598 } 11599 11600 /* 11601 * "match()" function 11602 */ 11603 static void 11604 f_match(argvars, rettv) 11605 typval_T *argvars; 11606 typval_T *rettv; 11607 { 11608 find_some_match(argvars, rettv, 1); 11609 } 11610 11611 /* 11612 * "matchend()" function 11613 */ 11614 static void 11615 f_matchend(argvars, rettv) 11616 typval_T *argvars; 11617 typval_T *rettv; 11618 { 11619 find_some_match(argvars, rettv, 0); 11620 } 11621 11622 /* 11623 * "matchlist()" function 11624 */ 11625 static void 11626 f_matchlist(argvars, rettv) 11627 typval_T *argvars; 11628 typval_T *rettv; 11629 { 11630 find_some_match(argvars, rettv, 3); 11631 } 11632 11633 /* 11634 * "matchstr()" function 11635 */ 11636 static void 11637 f_matchstr(argvars, rettv) 11638 typval_T *argvars; 11639 typval_T *rettv; 11640 { 11641 find_some_match(argvars, rettv, 2); 11642 } 11643 11644 static void max_min __ARGS((typval_T *argvars, typval_T *rettv, int domax)); 11645 11646 static void 11647 max_min(argvars, rettv, domax) 11648 typval_T *argvars; 11649 typval_T *rettv; 11650 int domax; 11651 { 11652 long n = 0; 11653 long i; 11654 int error = FALSE; 11655 11656 if (argvars[0].v_type == VAR_LIST) 11657 { 11658 list_T *l; 11659 listitem_T *li; 11660 11661 l = argvars[0].vval.v_list; 11662 if (l != NULL) 11663 { 11664 li = l->lv_first; 11665 if (li != NULL) 11666 { 11667 n = get_tv_number_chk(&li->li_tv, &error); 11668 for (;;) 11669 { 11670 li = li->li_next; 11671 if (li == NULL) 11672 break; 11673 i = get_tv_number_chk(&li->li_tv, &error); 11674 if (domax ? i > n : i < n) 11675 n = i; 11676 } 11677 } 11678 } 11679 } 11680 else if (argvars[0].v_type == VAR_DICT) 11681 { 11682 dict_T *d; 11683 int first = TRUE; 11684 hashitem_T *hi; 11685 int todo; 11686 11687 d = argvars[0].vval.v_dict; 11688 if (d != NULL) 11689 { 11690 todo = d->dv_hashtab.ht_used; 11691 for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) 11692 { 11693 if (!HASHITEM_EMPTY(hi)) 11694 { 11695 --todo; 11696 i = get_tv_number_chk(&HI2DI(hi)->di_tv, &error); 11697 if (first) 11698 { 11699 n = i; 11700 first = FALSE; 11701 } 11702 else if (domax ? i > n : i < n) 11703 n = i; 11704 } 11705 } 11706 } 11707 } 11708 else 11709 EMSG(_(e_listdictarg)); 11710 rettv->vval.v_number = error ? 0 : n; 11711 } 11712 11713 /* 11714 * "max()" function 11715 */ 11716 static void 11717 f_max(argvars, rettv) 11718 typval_T *argvars; 11719 typval_T *rettv; 11720 { 11721 max_min(argvars, rettv, TRUE); 11722 } 11723 11724 /* 11725 * "min()" function 11726 */ 11727 static void 11728 f_min(argvars, rettv) 11729 typval_T *argvars; 11730 typval_T *rettv; 11731 { 11732 max_min(argvars, rettv, FALSE); 11733 } 11734 11735 static int mkdir_recurse __ARGS((char_u *dir, int prot)); 11736 11737 /* 11738 * Create the directory in which "dir" is located, and higher levels when 11739 * needed. 11740 */ 11741 static int 11742 mkdir_recurse(dir, prot) 11743 char_u *dir; 11744 int prot; 11745 { 11746 char_u *p; 11747 char_u *updir; 11748 int r = FAIL; 11749 11750 /* Get end of directory name in "dir". 11751 * We're done when it's "/" or "c:/". */ 11752 p = gettail_sep(dir); 11753 if (p <= get_past_head(dir)) 11754 return OK; 11755 11756 /* If the directory exists we're done. Otherwise: create it.*/ 11757 updir = vim_strnsave(dir, (int)(p - dir)); 11758 if (updir == NULL) 11759 return FAIL; 11760 if (mch_isdir(updir)) 11761 r = OK; 11762 else if (mkdir_recurse(updir, prot) == OK) 11763 r = vim_mkdir_emsg(updir, prot); 11764 vim_free(updir); 11765 return r; 11766 } 11767 11768 #ifdef vim_mkdir 11769 /* 11770 * "mkdir()" function 11771 */ 11772 static void 11773 f_mkdir(argvars, rettv) 11774 typval_T *argvars; 11775 typval_T *rettv; 11776 { 11777 char_u *dir; 11778 char_u buf[NUMBUFLEN]; 11779 int prot = 0755; 11780 11781 rettv->vval.v_number = FAIL; 11782 if (check_restricted() || check_secure()) 11783 return; 11784 11785 dir = get_tv_string_buf(&argvars[0], buf); 11786 if (argvars[1].v_type != VAR_UNKNOWN) 11787 { 11788 if (argvars[2].v_type != VAR_UNKNOWN) 11789 prot = get_tv_number_chk(&argvars[2], NULL); 11790 if (prot != -1 && STRCMP(get_tv_string(&argvars[1]), "p") == 0) 11791 mkdir_recurse(dir, prot); 11792 } 11793 rettv->vval.v_number = prot != -1 ? vim_mkdir_emsg(dir, prot) : 0; 11794 } 11795 #endif 11796 11797 /* 11798 * "mode()" function 11799 */ 11800 /*ARGSUSED*/ 11801 static void 11802 f_mode(argvars, rettv) 11803 typval_T *argvars; 11804 typval_T *rettv; 11805 { 11806 char_u buf[2]; 11807 11808 #ifdef FEAT_VISUAL 11809 if (VIsual_active) 11810 { 11811 if (VIsual_select) 11812 buf[0] = VIsual_mode + 's' - 'v'; 11813 else 11814 buf[0] = VIsual_mode; 11815 } 11816 else 11817 #endif 11818 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 11819 buf[0] = 'r'; 11820 else if (State & INSERT) 11821 { 11822 if (State & REPLACE_FLAG) 11823 buf[0] = 'R'; 11824 else 11825 buf[0] = 'i'; 11826 } 11827 else if (State & CMDLINE) 11828 buf[0] = 'c'; 11829 else 11830 buf[0] = 'n'; 11831 11832 buf[1] = NUL; 11833 rettv->vval.v_string = vim_strsave(buf); 11834 rettv->v_type = VAR_STRING; 11835 } 11836 11837 /* 11838 * "nextnonblank()" function 11839 */ 11840 static void 11841 f_nextnonblank(argvars, rettv) 11842 typval_T *argvars; 11843 typval_T *rettv; 11844 { 11845 linenr_T lnum; 11846 11847 for (lnum = get_tv_lnum(argvars); ; ++lnum) 11848 { 11849 if (lnum < 0 || lnum > curbuf->b_ml.ml_line_count) 11850 { 11851 lnum = 0; 11852 break; 11853 } 11854 if (*skipwhite(ml_get(lnum)) != NUL) 11855 break; 11856 } 11857 rettv->vval.v_number = lnum; 11858 } 11859 11860 /* 11861 * "nr2char()" function 11862 */ 11863 static void 11864 f_nr2char(argvars, rettv) 11865 typval_T *argvars; 11866 typval_T *rettv; 11867 { 11868 char_u buf[NUMBUFLEN]; 11869 11870 #ifdef FEAT_MBYTE 11871 if (has_mbyte) 11872 buf[(*mb_char2bytes)((int)get_tv_number(&argvars[0]), buf)] = NUL; 11873 else 11874 #endif 11875 { 11876 buf[0] = (char_u)get_tv_number(&argvars[0]); 11877 buf[1] = NUL; 11878 } 11879 rettv->v_type = VAR_STRING; 11880 rettv->vval.v_string = vim_strsave(buf); 11881 } 11882 11883 /* 11884 * "prevnonblank()" function 11885 */ 11886 static void 11887 f_prevnonblank(argvars, rettv) 11888 typval_T *argvars; 11889 typval_T *rettv; 11890 { 11891 linenr_T lnum; 11892 11893 lnum = get_tv_lnum(argvars); 11894 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 11895 lnum = 0; 11896 else 11897 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 11898 --lnum; 11899 rettv->vval.v_number = lnum; 11900 } 11901 11902 /* 11903 * "printf()" function 11904 */ 11905 static void 11906 f_printf(argvars, rettv) 11907 typval_T *argvars; 11908 typval_T *rettv; 11909 { 11910 rettv->v_type = VAR_STRING; 11911 rettv->vval.v_string = NULL; 11912 #ifdef HAVE_STDARG_H 11913 { 11914 char_u buf[NUMBUFLEN]; 11915 int len; 11916 char_u *s; 11917 int saved_did_emsg = did_emsg; 11918 char *fmt; 11919 11920 /* Get the required length, allocate the buffer and do it for real. */ 11921 did_emsg = FALSE; 11922 fmt = (char *)get_tv_string_buf(&argvars[0], buf); 11923 len = vim_vsnprintf(NULL, 0, fmt, NULL, argvars + 1); 11924 if (!did_emsg) 11925 { 11926 s = alloc(len + 1); 11927 if (s != NULL) 11928 { 11929 rettv->vval.v_string = s; 11930 (void)vim_vsnprintf((char *)s, len + 1, fmt, NULL, argvars + 1); 11931 } 11932 } 11933 did_emsg |= saved_did_emsg; 11934 } 11935 #endif 11936 } 11937 11938 /* 11939 * "range()" function 11940 */ 11941 static void 11942 f_range(argvars, rettv) 11943 typval_T *argvars; 11944 typval_T *rettv; 11945 { 11946 long start; 11947 long end; 11948 long stride = 1; 11949 long i; 11950 list_T *l; 11951 listitem_T *li; 11952 int error = FALSE; 11953 11954 start = get_tv_number_chk(&argvars[0], &error); 11955 if (argvars[1].v_type == VAR_UNKNOWN) 11956 { 11957 end = start - 1; 11958 start = 0; 11959 } 11960 else 11961 { 11962 end = get_tv_number_chk(&argvars[1], &error); 11963 if (argvars[2].v_type != VAR_UNKNOWN) 11964 stride = get_tv_number_chk(&argvars[2], &error); 11965 } 11966 11967 rettv->vval.v_number = 0; 11968 if (error) 11969 return; /* type error; errmsg already given */ 11970 if (stride == 0) 11971 EMSG(_("E726: Stride is zero")); 11972 else if (stride > 0 ? end + 1 < start : end - 1 > start) 11973 EMSG(_("E727: Start past end")); 11974 else 11975 { 11976 l = list_alloc(); 11977 if (l != NULL) 11978 { 11979 rettv->v_type = VAR_LIST; 11980 rettv->vval.v_list = l; 11981 ++l->lv_refcount; 11982 11983 for (i = start; stride > 0 ? i <= end : i >= end; i += stride) 11984 { 11985 li = listitem_alloc(); 11986 if (li == NULL) 11987 break; 11988 li->li_tv.v_type = VAR_NUMBER; 11989 li->li_tv.v_lock = 0; 11990 li->li_tv.vval.v_number = i; 11991 list_append(l, li); 11992 } 11993 } 11994 } 11995 } 11996 11997 /* 11998 * "readfile()" function 11999 */ 12000 static void 12001 f_readfile(argvars, rettv) 12002 typval_T *argvars; 12003 typval_T *rettv; 12004 { 12005 int binary = FALSE; 12006 char_u *fname; 12007 FILE *fd; 12008 list_T *l; 12009 listitem_T *li; 12010 #define FREAD_SIZE 200 /* optimized for text lines */ 12011 char_u buf[FREAD_SIZE]; 12012 int readlen; /* size of last fread() */ 12013 int buflen; /* nr of valid chars in buf[] */ 12014 int filtd; /* how much in buf[] was NUL -> '\n' filtered */ 12015 int tolist; /* first byte in buf[] still to be put in list */ 12016 int chop; /* how many CR to chop off */ 12017 char_u *prev = NULL; /* previously read bytes, if any */ 12018 int prevlen = 0; /* length of "prev" if not NULL */ 12019 char_u *s; 12020 int len; 12021 long maxline = MAXLNUM; 12022 long cnt = 0; 12023 12024 if (argvars[1].v_type != VAR_UNKNOWN) 12025 { 12026 if (STRCMP(get_tv_string(&argvars[1]), "b") == 0) 12027 binary = TRUE; 12028 if (argvars[2].v_type != VAR_UNKNOWN) 12029 maxline = get_tv_number(&argvars[2]); 12030 } 12031 12032 l = list_alloc(); 12033 if (l == NULL) 12034 return; 12035 rettv->v_type = VAR_LIST; 12036 rettv->vval.v_list = l; 12037 l->lv_refcount = 1; 12038 12039 /* Always open the file in binary mode, library functions have a mind of 12040 * their own about CR-LF conversion. */ 12041 fname = get_tv_string(&argvars[0]); 12042 if (*fname == NUL || (fd = mch_fopen((char *)fname, READBIN)) == NULL) 12043 { 12044 EMSG2(_(e_notopen), *fname == NUL ? (char_u *)_("<empty>") : fname); 12045 return; 12046 } 12047 12048 filtd = 0; 12049 while (cnt < maxline || maxline < 0) 12050 { 12051 readlen = fread(buf + filtd, 1, FREAD_SIZE - filtd, fd); 12052 buflen = filtd + readlen; 12053 tolist = 0; 12054 for ( ; filtd < buflen || readlen <= 0; ++filtd) 12055 { 12056 if (buf[filtd] == '\n' || readlen <= 0) 12057 { 12058 /* Only when in binary mode add an empty list item when the 12059 * last line ends in a '\n'. */ 12060 if (!binary && readlen == 0 && filtd == 0) 12061 break; 12062 12063 /* Found end-of-line or end-of-file: add a text line to the 12064 * list. */ 12065 chop = 0; 12066 if (!binary) 12067 while (filtd - chop - 1 >= tolist 12068 && buf[filtd - chop - 1] == '\r') 12069 ++chop; 12070 len = filtd - tolist - chop; 12071 if (prev == NULL) 12072 s = vim_strnsave(buf + tolist, len); 12073 else 12074 { 12075 s = alloc((unsigned)(prevlen + len + 1)); 12076 if (s != NULL) 12077 { 12078 mch_memmove(s, prev, prevlen); 12079 vim_free(prev); 12080 prev = NULL; 12081 mch_memmove(s + prevlen, buf + tolist, len); 12082 s[prevlen + len] = NUL; 12083 } 12084 } 12085 tolist = filtd + 1; 12086 12087 li = listitem_alloc(); 12088 if (li == NULL) 12089 { 12090 vim_free(s); 12091 break; 12092 } 12093 li->li_tv.v_type = VAR_STRING; 12094 li->li_tv.v_lock = 0; 12095 li->li_tv.vval.v_string = s; 12096 list_append(l, li); 12097 12098 if (++cnt >= maxline && maxline >= 0) 12099 break; 12100 if (readlen <= 0) 12101 break; 12102 } 12103 else if (buf[filtd] == NUL) 12104 buf[filtd] = '\n'; 12105 } 12106 if (readlen <= 0) 12107 break; 12108 12109 if (tolist == 0) 12110 { 12111 /* "buf" is full, need to move text to an allocated buffer */ 12112 if (prev == NULL) 12113 { 12114 prev = vim_strnsave(buf, buflen); 12115 prevlen = buflen; 12116 } 12117 else 12118 { 12119 s = alloc((unsigned)(prevlen + buflen)); 12120 if (s != NULL) 12121 { 12122 mch_memmove(s, prev, prevlen); 12123 mch_memmove(s + prevlen, buf, buflen); 12124 vim_free(prev); 12125 prev = s; 12126 prevlen += buflen; 12127 } 12128 } 12129 filtd = 0; 12130 } 12131 else 12132 { 12133 mch_memmove(buf, buf + tolist, buflen - tolist); 12134 filtd -= tolist; 12135 } 12136 } 12137 12138 /* 12139 * For a negative line count use only the lines at the end of the file, 12140 * free the rest. 12141 */ 12142 if (maxline < 0) 12143 while (cnt > -maxline) 12144 { 12145 listitem_remove(l, l->lv_first); 12146 --cnt; 12147 } 12148 12149 vim_free(prev); 12150 fclose(fd); 12151 } 12152 12153 12154 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 12155 static void make_connection __ARGS((void)); 12156 static int check_connection __ARGS((void)); 12157 12158 static void 12159 make_connection() 12160 { 12161 if (X_DISPLAY == NULL 12162 # ifdef FEAT_GUI 12163 && !gui.in_use 12164 # endif 12165 ) 12166 { 12167 x_force_connect = TRUE; 12168 setup_term_clip(); 12169 x_force_connect = FALSE; 12170 } 12171 } 12172 12173 static int 12174 check_connection() 12175 { 12176 make_connection(); 12177 if (X_DISPLAY == NULL) 12178 { 12179 EMSG(_("E240: No connection to Vim server")); 12180 return FAIL; 12181 } 12182 return OK; 12183 } 12184 #endif 12185 12186 #ifdef FEAT_CLIENTSERVER 12187 static void remote_common __ARGS((typval_T *argvars, typval_T *rettv, int expr)); 12188 12189 static void 12190 remote_common(argvars, rettv, expr) 12191 typval_T *argvars; 12192 typval_T *rettv; 12193 int expr; 12194 { 12195 char_u *server_name; 12196 char_u *keys; 12197 char_u *r = NULL; 12198 char_u buf[NUMBUFLEN]; 12199 # ifdef WIN32 12200 HWND w; 12201 # else 12202 Window w; 12203 # endif 12204 12205 if (check_restricted() || check_secure()) 12206 return; 12207 12208 # ifdef FEAT_X11 12209 if (check_connection() == FAIL) 12210 return; 12211 # endif 12212 12213 server_name = get_tv_string_chk(&argvars[0]); 12214 if (server_name == NULL) 12215 return; /* type error; errmsg already given */ 12216 keys = get_tv_string_buf(&argvars[1], buf); 12217 # ifdef WIN32 12218 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 12219 # else 12220 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 12221 < 0) 12222 # endif 12223 { 12224 if (r != NULL) 12225 EMSG(r); /* sending worked but evaluation failed */ 12226 else 12227 EMSG2(_("E241: Unable to send to %s"), server_name); 12228 return; 12229 } 12230 12231 rettv->vval.v_string = r; 12232 12233 if (argvars[2].v_type != VAR_UNKNOWN) 12234 { 12235 dictitem_T v; 12236 char_u str[30]; 12237 char_u *idvar; 12238 12239 sprintf((char *)str, "0x%x", (unsigned int)w); 12240 v.di_tv.v_type = VAR_STRING; 12241 v.di_tv.vval.v_string = vim_strsave(str); 12242 idvar = get_tv_string_chk(&argvars[2]); 12243 if (idvar != NULL) 12244 set_var(idvar, &v.di_tv, FALSE); 12245 vim_free(v.di_tv.vval.v_string); 12246 } 12247 } 12248 #endif 12249 12250 /* 12251 * "remote_expr()" function 12252 */ 12253 /*ARGSUSED*/ 12254 static void 12255 f_remote_expr(argvars, rettv) 12256 typval_T *argvars; 12257 typval_T *rettv; 12258 { 12259 rettv->v_type = VAR_STRING; 12260 rettv->vval.v_string = NULL; 12261 #ifdef FEAT_CLIENTSERVER 12262 remote_common(argvars, rettv, TRUE); 12263 #endif 12264 } 12265 12266 /* 12267 * "remote_foreground()" function 12268 */ 12269 /*ARGSUSED*/ 12270 static void 12271 f_remote_foreground(argvars, rettv) 12272 typval_T *argvars; 12273 typval_T *rettv; 12274 { 12275 rettv->vval.v_number = 0; 12276 #ifdef FEAT_CLIENTSERVER 12277 # ifdef WIN32 12278 /* On Win32 it's done in this application. */ 12279 { 12280 char_u *server_name = get_tv_string_chk(&argvars[0]); 12281 12282 if (server_name != NULL) 12283 serverForeground(server_name); 12284 } 12285 # else 12286 /* Send a foreground() expression to the server. */ 12287 argvars[1].v_type = VAR_STRING; 12288 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()"); 12289 argvars[2].v_type = VAR_UNKNOWN; 12290 remote_common(argvars, rettv, TRUE); 12291 vim_free(argvars[1].vval.v_string); 12292 # endif 12293 #endif 12294 } 12295 12296 /*ARGSUSED*/ 12297 static void 12298 f_remote_peek(argvars, rettv) 12299 typval_T *argvars; 12300 typval_T *rettv; 12301 { 12302 #ifdef FEAT_CLIENTSERVER 12303 dictitem_T v; 12304 char_u *s = NULL; 12305 # ifdef WIN32 12306 int n = 0; 12307 # endif 12308 char_u *serverid; 12309 12310 if (check_restricted() || check_secure()) 12311 { 12312 rettv->vval.v_number = -1; 12313 return; 12314 } 12315 serverid = get_tv_string_chk(&argvars[0]); 12316 if (serverid == NULL) 12317 { 12318 rettv->vval.v_number = -1; 12319 return; /* type error; errmsg already given */ 12320 } 12321 # ifdef WIN32 12322 sscanf(serverid, "%x", &n); 12323 if (n == 0) 12324 rettv->vval.v_number = -1; 12325 else 12326 { 12327 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 12328 rettv->vval.v_number = (s != NULL); 12329 } 12330 # else 12331 rettv->vval.v_number = 0; 12332 if (check_connection() == FAIL) 12333 return; 12334 12335 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 12336 serverStrToWin(serverid), &s); 12337 # endif 12338 12339 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 12340 { 12341 char_u *retvar; 12342 12343 v.di_tv.v_type = VAR_STRING; 12344 v.di_tv.vval.v_string = vim_strsave(s); 12345 retvar = get_tv_string_chk(&argvars[1]); 12346 if (retvar != NULL) 12347 set_var(retvar, &v.di_tv, FALSE); 12348 vim_free(v.di_tv.vval.v_string); 12349 } 12350 #else 12351 rettv->vval.v_number = -1; 12352 #endif 12353 } 12354 12355 /*ARGSUSED*/ 12356 static void 12357 f_remote_read(argvars, rettv) 12358 typval_T *argvars; 12359 typval_T *rettv; 12360 { 12361 char_u *r = NULL; 12362 12363 #ifdef FEAT_CLIENTSERVER 12364 char_u *serverid = get_tv_string_chk(&argvars[0]); 12365 12366 if (serverid != NULL && !check_restricted() && !check_secure()) 12367 { 12368 # ifdef WIN32 12369 /* The server's HWND is encoded in the 'id' parameter */ 12370 int n = 0; 12371 12372 sscanf(serverid, "%x", &n); 12373 if (n != 0) 12374 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 12375 if (r == NULL) 12376 # else 12377 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 12378 serverStrToWin(serverid), &r, FALSE) < 0) 12379 # endif 12380 EMSG(_("E277: Unable to read a server reply")); 12381 } 12382 #endif 12383 rettv->v_type = VAR_STRING; 12384 rettv->vval.v_string = r; 12385 } 12386 12387 /* 12388 * "remote_send()" function 12389 */ 12390 /*ARGSUSED*/ 12391 static void 12392 f_remote_send(argvars, rettv) 12393 typval_T *argvars; 12394 typval_T *rettv; 12395 { 12396 rettv->v_type = VAR_STRING; 12397 rettv->vval.v_string = NULL; 12398 #ifdef FEAT_CLIENTSERVER 12399 remote_common(argvars, rettv, FALSE); 12400 #endif 12401 } 12402 12403 /* 12404 * "remove()" function 12405 */ 12406 static void 12407 f_remove(argvars, rettv) 12408 typval_T *argvars; 12409 typval_T *rettv; 12410 { 12411 list_T *l; 12412 listitem_T *item, *item2; 12413 listitem_T *li; 12414 long idx; 12415 long end; 12416 char_u *key; 12417 dict_T *d; 12418 dictitem_T *di; 12419 12420 rettv->vval.v_number = 0; 12421 if (argvars[0].v_type == VAR_DICT) 12422 { 12423 if (argvars[2].v_type != VAR_UNKNOWN) 12424 EMSG2(_(e_toomanyarg), "remove()"); 12425 else if ((d = argvars[0].vval.v_dict) != NULL 12426 && !tv_check_lock(d->dv_lock, (char_u *)"remove()")) 12427 { 12428 key = get_tv_string_chk(&argvars[1]); 12429 if (key != NULL) 12430 { 12431 di = dict_find(d, key, -1); 12432 if (di == NULL) 12433 EMSG2(_(e_dictkey), key); 12434 else 12435 { 12436 *rettv = di->di_tv; 12437 init_tv(&di->di_tv); 12438 dictitem_remove(d, di); 12439 } 12440 } 12441 } 12442 } 12443 else if (argvars[0].v_type != VAR_LIST) 12444 EMSG2(_(e_listdictarg), "remove()"); 12445 else if ((l = argvars[0].vval.v_list) != NULL 12446 && !tv_check_lock(l->lv_lock, (char_u *)"remove()")) 12447 { 12448 int error = FALSE; 12449 12450 idx = get_tv_number_chk(&argvars[1], &error); 12451 if (error) 12452 ; /* type error: do nothing, errmsg already given */ 12453 else if ((item = list_find(l, idx)) == NULL) 12454 EMSGN(_(e_listidx), idx); 12455 else 12456 { 12457 if (argvars[2].v_type == VAR_UNKNOWN) 12458 { 12459 /* Remove one item, return its value. */ 12460 list_remove(l, item, item); 12461 *rettv = item->li_tv; 12462 vim_free(item); 12463 } 12464 else 12465 { 12466 /* Remove range of items, return list with values. */ 12467 end = get_tv_number_chk(&argvars[2], &error); 12468 if (error) 12469 ; /* type error: do nothing */ 12470 else if ((item2 = list_find(l, end)) == NULL) 12471 EMSGN(_(e_listidx), end); 12472 else 12473 { 12474 int cnt = 0; 12475 12476 for (li = item; li != NULL; li = li->li_next) 12477 { 12478 ++cnt; 12479 if (li == item2) 12480 break; 12481 } 12482 if (li == NULL) /* didn't find "item2" after "item" */ 12483 EMSG(_(e_invrange)); 12484 else 12485 { 12486 list_remove(l, item, item2); 12487 l = list_alloc(); 12488 if (l != NULL) 12489 { 12490 rettv->v_type = VAR_LIST; 12491 rettv->vval.v_list = l; 12492 l->lv_first = item; 12493 l->lv_last = item2; 12494 l->lv_refcount = 1; 12495 item->li_prev = NULL; 12496 item2->li_next = NULL; 12497 l->lv_len = cnt; 12498 } 12499 } 12500 } 12501 } 12502 } 12503 } 12504 } 12505 12506 /* 12507 * "rename({from}, {to})" function 12508 */ 12509 static void 12510 f_rename(argvars, rettv) 12511 typval_T *argvars; 12512 typval_T *rettv; 12513 { 12514 char_u buf[NUMBUFLEN]; 12515 12516 if (check_restricted() || check_secure()) 12517 rettv->vval.v_number = -1; 12518 else 12519 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), 12520 get_tv_string_buf(&argvars[1], buf)); 12521 } 12522 12523 /* 12524 * "repeat()" function 12525 */ 12526 /*ARGSUSED*/ 12527 static void 12528 f_repeat(argvars, rettv) 12529 typval_T *argvars; 12530 typval_T *rettv; 12531 { 12532 char_u *p; 12533 int n; 12534 int slen; 12535 int len; 12536 char_u *r; 12537 int i; 12538 list_T *l; 12539 12540 n = get_tv_number(&argvars[1]); 12541 if (argvars[0].v_type == VAR_LIST) 12542 { 12543 l = list_alloc(); 12544 if (l != NULL && argvars[0].vval.v_list != NULL) 12545 { 12546 l->lv_refcount = 1; 12547 while (n-- > 0) 12548 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) 12549 break; 12550 } 12551 rettv->v_type = VAR_LIST; 12552 rettv->vval.v_list = l; 12553 } 12554 else 12555 { 12556 p = get_tv_string(&argvars[0]); 12557 rettv->v_type = VAR_STRING; 12558 rettv->vval.v_string = NULL; 12559 12560 slen = (int)STRLEN(p); 12561 len = slen * n; 12562 if (len <= 0) 12563 return; 12564 12565 r = alloc(len + 1); 12566 if (r != NULL) 12567 { 12568 for (i = 0; i < n; i++) 12569 mch_memmove(r + i * slen, p, (size_t)slen); 12570 r[len] = NUL; 12571 } 12572 12573 rettv->vval.v_string = r; 12574 } 12575 } 12576 12577 /* 12578 * "resolve()" function 12579 */ 12580 static void 12581 f_resolve(argvars, rettv) 12582 typval_T *argvars; 12583 typval_T *rettv; 12584 { 12585 char_u *p; 12586 12587 p = get_tv_string(&argvars[0]); 12588 #ifdef FEAT_SHORTCUT 12589 { 12590 char_u *v = NULL; 12591 12592 v = mch_resolve_shortcut(p); 12593 if (v != NULL) 12594 rettv->vval.v_string = v; 12595 else 12596 rettv->vval.v_string = vim_strsave(p); 12597 } 12598 #else 12599 # ifdef HAVE_READLINK 12600 { 12601 char_u buf[MAXPATHL + 1]; 12602 char_u *cpy; 12603 int len; 12604 char_u *remain = NULL; 12605 char_u *q; 12606 int is_relative_to_current = FALSE; 12607 int has_trailing_pathsep = FALSE; 12608 int limit = 100; 12609 12610 p = vim_strsave(p); 12611 12612 if (p[0] == '.' && (vim_ispathsep(p[1]) 12613 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 12614 is_relative_to_current = TRUE; 12615 12616 len = STRLEN(p); 12617 if (len > 0 && after_pathsep(p, p + len)) 12618 has_trailing_pathsep = TRUE; 12619 12620 q = getnextcomp(p); 12621 if (*q != NUL) 12622 { 12623 /* Separate the first path component in "p", and keep the 12624 * remainder (beginning with the path separator). */ 12625 remain = vim_strsave(q - 1); 12626 q[-1] = NUL; 12627 } 12628 12629 for (;;) 12630 { 12631 for (;;) 12632 { 12633 len = readlink((char *)p, (char *)buf, MAXPATHL); 12634 if (len <= 0) 12635 break; 12636 buf[len] = NUL; 12637 12638 if (limit-- == 0) 12639 { 12640 vim_free(p); 12641 vim_free(remain); 12642 EMSG(_("E655: Too many symbolic links (cycle?)")); 12643 rettv->vval.v_string = NULL; 12644 goto fail; 12645 } 12646 12647 /* Ensure that the result will have a trailing path separator 12648 * if the argument has one. */ 12649 if (remain == NULL && has_trailing_pathsep) 12650 add_pathsep(buf); 12651 12652 /* Separate the first path component in the link value and 12653 * concatenate the remainders. */ 12654 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 12655 if (*q != NUL) 12656 { 12657 if (remain == NULL) 12658 remain = vim_strsave(q - 1); 12659 else 12660 { 12661 cpy = vim_strnsave(q-1, STRLEN(q-1) + STRLEN(remain)); 12662 if (cpy != NULL) 12663 { 12664 STRCAT(cpy, remain); 12665 vim_free(remain); 12666 remain = cpy; 12667 } 12668 } 12669 q[-1] = NUL; 12670 } 12671 12672 q = gettail(p); 12673 if (q > p && *q == NUL) 12674 { 12675 /* Ignore trailing path separator. */ 12676 q[-1] = NUL; 12677 q = gettail(p); 12678 } 12679 if (q > p && !mch_isFullName(buf)) 12680 { 12681 /* symlink is relative to directory of argument */ 12682 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 12683 if (cpy != NULL) 12684 { 12685 STRCPY(cpy, p); 12686 STRCPY(gettail(cpy), buf); 12687 vim_free(p); 12688 p = cpy; 12689 } 12690 } 12691 else 12692 { 12693 vim_free(p); 12694 p = vim_strsave(buf); 12695 } 12696 } 12697 12698 if (remain == NULL) 12699 break; 12700 12701 /* Append the first path component of "remain" to "p". */ 12702 q = getnextcomp(remain + 1); 12703 len = q - remain - (*q != NUL); 12704 cpy = vim_strnsave(p, STRLEN(p) + len); 12705 if (cpy != NULL) 12706 { 12707 STRNCAT(cpy, remain, len); 12708 vim_free(p); 12709 p = cpy; 12710 } 12711 /* Shorten "remain". */ 12712 if (*q != NUL) 12713 STRCPY(remain, q - 1); 12714 else 12715 { 12716 vim_free(remain); 12717 remain = NULL; 12718 } 12719 } 12720 12721 /* If the result is a relative path name, make it explicitly relative to 12722 * the current directory if and only if the argument had this form. */ 12723 if (!vim_ispathsep(*p)) 12724 { 12725 if (is_relative_to_current 12726 && *p != NUL 12727 && !(p[0] == '.' 12728 && (p[1] == NUL 12729 || vim_ispathsep(p[1]) 12730 || (p[1] == '.' 12731 && (p[2] == NUL 12732 || vim_ispathsep(p[2])))))) 12733 { 12734 /* Prepend "./". */ 12735 cpy = concat_str((char_u *)"./", p); 12736 if (cpy != NULL) 12737 { 12738 vim_free(p); 12739 p = cpy; 12740 } 12741 } 12742 else if (!is_relative_to_current) 12743 { 12744 /* Strip leading "./". */ 12745 q = p; 12746 while (q[0] == '.' && vim_ispathsep(q[1])) 12747 q += 2; 12748 if (q > p) 12749 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 12750 } 12751 } 12752 12753 /* Ensure that the result will have no trailing path separator 12754 * if the argument had none. But keep "/" or "//". */ 12755 if (!has_trailing_pathsep) 12756 { 12757 q = p + STRLEN(p); 12758 if (after_pathsep(p, q)) 12759 *gettail_sep(p) = NUL; 12760 } 12761 12762 rettv->vval.v_string = p; 12763 } 12764 # else 12765 rettv->vval.v_string = vim_strsave(p); 12766 # endif 12767 #endif 12768 12769 simplify_filename(rettv->vval.v_string); 12770 12771 #ifdef HAVE_READLINK 12772 fail: 12773 #endif 12774 rettv->v_type = VAR_STRING; 12775 } 12776 12777 /* 12778 * "reverse({list})" function 12779 */ 12780 static void 12781 f_reverse(argvars, rettv) 12782 typval_T *argvars; 12783 typval_T *rettv; 12784 { 12785 list_T *l; 12786 listitem_T *li, *ni; 12787 12788 rettv->vval.v_number = 0; 12789 if (argvars[0].v_type != VAR_LIST) 12790 EMSG2(_(e_listarg), "reverse()"); 12791 else if ((l = argvars[0].vval.v_list) != NULL 12792 && !tv_check_lock(l->lv_lock, (char_u *)"reverse()")) 12793 { 12794 li = l->lv_last; 12795 l->lv_first = l->lv_last = NULL; 12796 l->lv_len = 0; 12797 while (li != NULL) 12798 { 12799 ni = li->li_prev; 12800 list_append(l, li); 12801 li = ni; 12802 } 12803 rettv->vval.v_list = l; 12804 rettv->v_type = VAR_LIST; 12805 ++l->lv_refcount; 12806 } 12807 } 12808 12809 #define SP_NOMOVE 1 /* don't move cursor */ 12810 #define SP_REPEAT 2 /* repeat to find outer pair */ 12811 #define SP_RETCOUNT 4 /* return matchcount */ 12812 #define SP_SETPCMARK 8 /* set previous context mark */ 12813 12814 static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); 12815 12816 /* 12817 * Get flags for a search function. 12818 * Possibly sets "p_ws". 12819 * Returns BACKWARD, FORWARD or zero (for an error). 12820 */ 12821 static int 12822 get_search_arg(varp, flagsp) 12823 typval_T *varp; 12824 int *flagsp; 12825 { 12826 int dir = FORWARD; 12827 char_u *flags; 12828 char_u nbuf[NUMBUFLEN]; 12829 int mask; 12830 12831 if (varp->v_type != VAR_UNKNOWN) 12832 { 12833 flags = get_tv_string_buf_chk(varp, nbuf); 12834 if (flags == NULL) 12835 return 0; /* type error; errmsg already given */ 12836 while (*flags != NUL) 12837 { 12838 switch (*flags) 12839 { 12840 case 'b': dir = BACKWARD; break; 12841 case 'w': p_ws = TRUE; break; 12842 case 'W': p_ws = FALSE; break; 12843 default: mask = 0; 12844 if (flagsp != NULL) 12845 switch (*flags) 12846 { 12847 case 'n': mask = SP_NOMOVE; break; 12848 case 'r': mask = SP_REPEAT; break; 12849 case 'm': mask = SP_RETCOUNT; break; 12850 case 's': mask = SP_SETPCMARK; break; 12851 } 12852 if (mask == 0) 12853 { 12854 EMSG2(_(e_invarg2), flags); 12855 dir = 0; 12856 } 12857 else 12858 *flagsp |= mask; 12859 } 12860 if (dir == 0) 12861 break; 12862 ++flags; 12863 } 12864 } 12865 return dir; 12866 } 12867 12868 /* 12869 * "search()" function 12870 */ 12871 static void 12872 f_search(argvars, rettv) 12873 typval_T *argvars; 12874 typval_T *rettv; 12875 { 12876 char_u *pat; 12877 pos_T pos; 12878 pos_T save_cursor; 12879 int save_p_ws = p_ws; 12880 int dir; 12881 int flags = 0; 12882 12883 rettv->vval.v_number = 0; /* default: FAIL */ 12884 12885 pat = get_tv_string(&argvars[0]); 12886 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */ 12887 if (dir == 0) 12888 goto theend; 12889 /* 12890 * This function accepts only SP_NOMOVE and SP_SETPCMARK flags. 12891 * Check to make sure only those flags are set. 12892 * Also, Only the SP_NOMOVE or the SP_SETPCMARK flag can be set. Both 12893 * flags cannot be set. Check for that condition also. 12894 */ 12895 if (((flags & ~(SP_NOMOVE | SP_SETPCMARK)) != 0) || 12896 ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK))) 12897 { 12898 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 12899 goto theend; 12900 } 12901 12902 pos = save_cursor = curwin->w_cursor; 12903 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 12904 SEARCH_KEEP, RE_SEARCH) != FAIL) 12905 { 12906 rettv->vval.v_number = pos.lnum; 12907 if (flags & SP_SETPCMARK) 12908 setpcmark(); 12909 curwin->w_cursor = pos; 12910 /* "/$" will put the cursor after the end of the line, may need to 12911 * correct that here */ 12912 check_cursor(); 12913 } 12914 12915 /* If 'n' flag is used: restore cursor position. */ 12916 if (flags & SP_NOMOVE) 12917 curwin->w_cursor = save_cursor; 12918 theend: 12919 p_ws = save_p_ws; 12920 } 12921 12922 /* 12923 * "searchpair()" function 12924 */ 12925 static void 12926 f_searchpair(argvars, rettv) 12927 typval_T *argvars; 12928 typval_T *rettv; 12929 { 12930 char_u *spat, *mpat, *epat; 12931 char_u *skip; 12932 int save_p_ws = p_ws; 12933 int dir; 12934 int flags = 0; 12935 char_u nbuf1[NUMBUFLEN]; 12936 char_u nbuf2[NUMBUFLEN]; 12937 char_u nbuf3[NUMBUFLEN]; 12938 12939 rettv->vval.v_number = 0; /* default: FAIL */ 12940 12941 /* Get the three pattern arguments: start, middle, end. */ 12942 spat = get_tv_string_chk(&argvars[0]); 12943 mpat = get_tv_string_buf_chk(&argvars[1], nbuf1); 12944 epat = get_tv_string_buf_chk(&argvars[2], nbuf2); 12945 if (spat == NULL || mpat == NULL || epat == NULL) 12946 goto theend; /* type error */ 12947 12948 /* Handle the optional fourth argument: flags */ 12949 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 12950 if (dir == 0) 12951 goto theend; 12952 /* 12953 * Only one of the SP_NOMOVE or SP_SETPCMARK flags can be set. 12954 */ 12955 if ((flags & SP_NOMOVE) && (flags & SP_SETPCMARK)) 12956 { 12957 EMSG2(_(e_invarg2), get_tv_string(&argvars[1])); 12958 goto theend; 12959 } 12960 12961 /* Optional fifth argument: skip expresion */ 12962 if (argvars[3].v_type == VAR_UNKNOWN 12963 || argvars[4].v_type == VAR_UNKNOWN) 12964 skip = (char_u *)""; 12965 else 12966 skip = get_tv_string_buf_chk(&argvars[4], nbuf3); 12967 if (skip == NULL) 12968 goto theend; /* type error */ 12969 12970 rettv->vval.v_number = do_searchpair(spat, mpat, epat, dir, skip, flags); 12971 12972 theend: 12973 p_ws = save_p_ws; 12974 } 12975 12976 /* 12977 * Search for a start/middle/end thing. 12978 * Used by searchpair(), see its documentation for the details. 12979 * Returns 0 or -1 for no match, 12980 */ 12981 long 12982 do_searchpair(spat, mpat, epat, dir, skip, flags) 12983 char_u *spat; /* start pattern */ 12984 char_u *mpat; /* middle pattern */ 12985 char_u *epat; /* end pattern */ 12986 int dir; /* BACKWARD or FORWARD */ 12987 char_u *skip; /* skip expression */ 12988 int flags; /* SP_RETCOUNT, SP_REPEAT, SP_NOMOVE */ 12989 { 12990 char_u *save_cpo; 12991 char_u *pat, *pat2 = NULL, *pat3 = NULL; 12992 long retval = 0; 12993 pos_T pos; 12994 pos_T firstpos; 12995 pos_T foundpos; 12996 pos_T save_cursor; 12997 pos_T save_pos; 12998 int n; 12999 int r; 13000 int nest = 1; 13001 int err; 13002 13003 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13004 save_cpo = p_cpo; 13005 p_cpo = (char_u *)""; 13006 13007 /* Make two search patterns: start/end (pat2, for in nested pairs) and 13008 * start/middle/end (pat3, for the top pair). */ 13009 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 13010 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 13011 if (pat2 == NULL || pat3 == NULL) 13012 goto theend; 13013 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 13014 if (*mpat == NUL) 13015 STRCPY(pat3, pat2); 13016 else 13017 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 13018 spat, epat, mpat); 13019 13020 save_cursor = curwin->w_cursor; 13021 pos = curwin->w_cursor; 13022 firstpos.lnum = 0; 13023 foundpos.lnum = 0; 13024 pat = pat3; 13025 for (;;) 13026 { 13027 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 13028 SEARCH_KEEP, RE_SEARCH); 13029 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 13030 /* didn't find it or found the first match again: FAIL */ 13031 break; 13032 13033 if (firstpos.lnum == 0) 13034 firstpos = pos; 13035 if (equalpos(pos, foundpos)) 13036 { 13037 /* Found the same position again. Can happen with a pattern that 13038 * has "\zs" at the end and searching backwards. Advance one 13039 * character and try again. */ 13040 if (dir == BACKWARD) 13041 decl(&pos); 13042 else 13043 incl(&pos); 13044 } 13045 foundpos = pos; 13046 13047 /* If the skip pattern matches, ignore this match. */ 13048 if (*skip != NUL) 13049 { 13050 save_pos = curwin->w_cursor; 13051 curwin->w_cursor = pos; 13052 r = eval_to_bool(skip, &err, NULL, FALSE); 13053 curwin->w_cursor = save_pos; 13054 if (err) 13055 { 13056 /* Evaluating {skip} caused an error, break here. */ 13057 curwin->w_cursor = save_cursor; 13058 retval = -1; 13059 break; 13060 } 13061 if (r) 13062 continue; 13063 } 13064 13065 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 13066 { 13067 /* Found end when searching backwards or start when searching 13068 * forward: nested pair. */ 13069 ++nest; 13070 pat = pat2; /* nested, don't search for middle */ 13071 } 13072 else 13073 { 13074 /* Found end when searching forward or start when searching 13075 * backward: end of (nested) pair; or found middle in outer pair. */ 13076 if (--nest == 1) 13077 pat = pat3; /* outer level, search for middle */ 13078 } 13079 13080 if (nest == 0) 13081 { 13082 /* Found the match: return matchcount or line number. */ 13083 if (flags & SP_RETCOUNT) 13084 ++retval; 13085 else 13086 retval = pos.lnum; 13087 if (flags & SP_SETPCMARK) 13088 setpcmark(); 13089 curwin->w_cursor = pos; 13090 if (!(flags & SP_REPEAT)) 13091 break; 13092 nest = 1; /* search for next unmatched */ 13093 } 13094 } 13095 13096 /* If 'n' flag is used or search failed: restore cursor position. */ 13097 if ((flags & SP_NOMOVE) || retval == 0) 13098 curwin->w_cursor = save_cursor; 13099 13100 theend: 13101 vim_free(pat2); 13102 vim_free(pat3); 13103 p_cpo = save_cpo; 13104 13105 return retval; 13106 } 13107 13108 /*ARGSUSED*/ 13109 static void 13110 f_server2client(argvars, rettv) 13111 typval_T *argvars; 13112 typval_T *rettv; 13113 { 13114 #ifdef FEAT_CLIENTSERVER 13115 char_u buf[NUMBUFLEN]; 13116 char_u *server = get_tv_string_chk(&argvars[0]); 13117 char_u *reply = get_tv_string_buf_chk(&argvars[1], buf); 13118 13119 rettv->vval.v_number = -1; 13120 if (server == NULL || reply == NULL) 13121 return; 13122 if (check_restricted() || check_secure()) 13123 return; 13124 # ifdef FEAT_X11 13125 if (check_connection() == FAIL) 13126 return; 13127 # endif 13128 13129 if (serverSendReply(server, reply) < 0) 13130 { 13131 EMSG(_("E258: Unable to send to client")); 13132 return; 13133 } 13134 rettv->vval.v_number = 0; 13135 #else 13136 rettv->vval.v_number = -1; 13137 #endif 13138 } 13139 13140 /*ARGSUSED*/ 13141 static void 13142 f_serverlist(argvars, rettv) 13143 typval_T *argvars; 13144 typval_T *rettv; 13145 { 13146 char_u *r = NULL; 13147 13148 #ifdef FEAT_CLIENTSERVER 13149 # ifdef WIN32 13150 r = serverGetVimNames(); 13151 # else 13152 make_connection(); 13153 if (X_DISPLAY != NULL) 13154 r = serverGetVimNames(X_DISPLAY); 13155 # endif 13156 #endif 13157 rettv->v_type = VAR_STRING; 13158 rettv->vval.v_string = r; 13159 } 13160 13161 /* 13162 * "setbufvar()" function 13163 */ 13164 /*ARGSUSED*/ 13165 static void 13166 f_setbufvar(argvars, rettv) 13167 typval_T *argvars; 13168 typval_T *rettv; 13169 { 13170 buf_T *buf; 13171 #ifdef FEAT_AUTOCMD 13172 aco_save_T aco; 13173 #else 13174 buf_T *save_curbuf; 13175 #endif 13176 char_u *varname, *bufvarname; 13177 typval_T *varp; 13178 char_u nbuf[NUMBUFLEN]; 13179 13180 rettv->vval.v_number = 0; 13181 13182 if (check_restricted() || check_secure()) 13183 return; 13184 (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ 13185 varname = get_tv_string_chk(&argvars[1]); 13186 buf = get_buf_tv(&argvars[0]); 13187 varp = &argvars[2]; 13188 13189 if (buf != NULL && varname != NULL && varp != NULL) 13190 { 13191 /* set curbuf to be our buf, temporarily */ 13192 #ifdef FEAT_AUTOCMD 13193 aucmd_prepbuf(&aco, buf); 13194 #else 13195 save_curbuf = curbuf; 13196 curbuf = buf; 13197 #endif 13198 13199 if (*varname == '&') 13200 { 13201 long numval; 13202 char_u *strval; 13203 int error = FALSE; 13204 13205 ++varname; 13206 numval = get_tv_number_chk(varp, &error); 13207 strval = get_tv_string_buf_chk(varp, nbuf); 13208 if (!error && strval != NULL) 13209 set_option_value(varname, numval, strval, OPT_LOCAL); 13210 } 13211 else 13212 { 13213 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 13214 if (bufvarname != NULL) 13215 { 13216 STRCPY(bufvarname, "b:"); 13217 STRCPY(bufvarname + 2, varname); 13218 set_var(bufvarname, varp, TRUE); 13219 vim_free(bufvarname); 13220 } 13221 } 13222 13223 /* reset notion of buffer */ 13224 #ifdef FEAT_AUTOCMD 13225 aucmd_restbuf(&aco); 13226 #else 13227 curbuf = save_curbuf; 13228 #endif 13229 } 13230 } 13231 13232 /* 13233 * "setcmdpos()" function 13234 */ 13235 static void 13236 f_setcmdpos(argvars, rettv) 13237 typval_T *argvars; 13238 typval_T *rettv; 13239 { 13240 int pos = (int)get_tv_number(&argvars[0]) - 1; 13241 13242 if (pos >= 0) 13243 rettv->vval.v_number = set_cmdline_pos(pos); 13244 } 13245 13246 /* 13247 * "setline()" function 13248 */ 13249 static void 13250 f_setline(argvars, rettv) 13251 typval_T *argvars; 13252 typval_T *rettv; 13253 { 13254 linenr_T lnum; 13255 char_u *line = NULL; 13256 list_T *l = NULL; 13257 listitem_T *li = NULL; 13258 long added = 0; 13259 linenr_T lcount = curbuf->b_ml.ml_line_count; 13260 13261 lnum = get_tv_lnum(&argvars[0]); 13262 if (argvars[1].v_type == VAR_LIST) 13263 { 13264 l = argvars[1].vval.v_list; 13265 li = l->lv_first; 13266 } 13267 else 13268 line = get_tv_string_chk(&argvars[1]); 13269 13270 rettv->vval.v_number = 0; /* OK */ 13271 for (;;) 13272 { 13273 if (l != NULL) 13274 { 13275 /* list argument, get next string */ 13276 if (li == NULL) 13277 break; 13278 line = get_tv_string_chk(&li->li_tv); 13279 li = li->li_next; 13280 } 13281 13282 rettv->vval.v_number = 1; /* FAIL */ 13283 if (line == NULL || lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 13284 break; 13285 if (lnum <= curbuf->b_ml.ml_line_count) 13286 { 13287 /* existing line, replace it */ 13288 if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK) 13289 { 13290 changed_bytes(lnum, 0); 13291 check_cursor_col(); 13292 rettv->vval.v_number = 0; /* OK */ 13293 } 13294 } 13295 else if (added > 0 || u_save(lnum - 1, lnum) == OK) 13296 { 13297 /* lnum is one past the last line, append the line */ 13298 ++added; 13299 if (ml_append(lnum - 1, line, (colnr_T)0, FALSE) == OK) 13300 rettv->vval.v_number = 0; /* OK */ 13301 } 13302 13303 if (l == NULL) /* only one string argument */ 13304 break; 13305 ++lnum; 13306 } 13307 13308 if (added > 0) 13309 appended_lines_mark(lcount, added); 13310 } 13311 13312 /* 13313 * "setqflist()" function 13314 */ 13315 /*ARGSUSED*/ 13316 static void 13317 f_setqflist(argvars, rettv) 13318 typval_T *argvars; 13319 typval_T *rettv; 13320 { 13321 char_u *act; 13322 int action = ' '; 13323 13324 rettv->vval.v_number = -1; 13325 13326 #ifdef FEAT_QUICKFIX 13327 if (argvars[0].v_type != VAR_LIST) 13328 EMSG(_(e_listreq)); 13329 else 13330 { 13331 list_T *l = argvars[0].vval.v_list; 13332 13333 if (argvars[1].v_type == VAR_STRING) 13334 { 13335 act = get_tv_string_chk(&argvars[1]); 13336 if (act == NULL) 13337 return; /* type error; errmsg already given */ 13338 if (*act == 'a' || *act == 'r') 13339 action = *act; 13340 } 13341 13342 if (l != NULL && set_errorlist(l, action) == OK) 13343 rettv->vval.v_number = 0; 13344 } 13345 #endif 13346 } 13347 13348 /* 13349 * "setreg()" function 13350 */ 13351 static void 13352 f_setreg(argvars, rettv) 13353 typval_T *argvars; 13354 typval_T *rettv; 13355 { 13356 int regname; 13357 char_u *strregname; 13358 char_u *stropt; 13359 char_u *strval; 13360 int append; 13361 char_u yank_type; 13362 long block_len; 13363 13364 block_len = -1; 13365 yank_type = MAUTO; 13366 append = FALSE; 13367 13368 strregname = get_tv_string_chk(argvars); 13369 rettv->vval.v_number = 1; /* FAIL is default */ 13370 13371 if (strregname == NULL) 13372 return; /* type error; errmsg already given */ 13373 regname = *strregname; 13374 if (regname == 0 || regname == '@') 13375 regname = '"'; 13376 else if (regname == '=') 13377 return; 13378 13379 if (argvars[2].v_type != VAR_UNKNOWN) 13380 { 13381 stropt = get_tv_string_chk(&argvars[2]); 13382 if (stropt == NULL) 13383 return; /* type error */ 13384 for (; *stropt != NUL; ++stropt) 13385 switch (*stropt) 13386 { 13387 case 'a': case 'A': /* append */ 13388 append = TRUE; 13389 break; 13390 case 'v': case 'c': /* character-wise selection */ 13391 yank_type = MCHAR; 13392 break; 13393 case 'V': case 'l': /* line-wise selection */ 13394 yank_type = MLINE; 13395 break; 13396 #ifdef FEAT_VISUAL 13397 case 'b': case Ctrl_V: /* block-wise selection */ 13398 yank_type = MBLOCK; 13399 if (VIM_ISDIGIT(stropt[1])) 13400 { 13401 ++stropt; 13402 block_len = getdigits(&stropt) - 1; 13403 --stropt; 13404 } 13405 break; 13406 #endif 13407 } 13408 } 13409 13410 strval = get_tv_string_chk(&argvars[1]); 13411 if (strval != NULL) 13412 write_reg_contents_ex(regname, strval, -1, 13413 append, yank_type, block_len); 13414 rettv->vval.v_number = 0; 13415 } 13416 13417 13418 /* 13419 * "setwinvar(expr)" function 13420 */ 13421 /*ARGSUSED*/ 13422 static void 13423 f_setwinvar(argvars, rettv) 13424 typval_T *argvars; 13425 typval_T *rettv; 13426 { 13427 win_T *win; 13428 #ifdef FEAT_WINDOWS 13429 win_T *save_curwin; 13430 #endif 13431 char_u *varname, *winvarname; 13432 typval_T *varp; 13433 char_u nbuf[NUMBUFLEN]; 13434 13435 rettv->vval.v_number = 0; 13436 13437 if (check_restricted() || check_secure()) 13438 return; 13439 win = find_win_by_nr(&argvars[0]); 13440 varname = get_tv_string_chk(&argvars[1]); 13441 varp = &argvars[2]; 13442 13443 if (win != NULL && varname != NULL && varp != NULL) 13444 { 13445 #ifdef FEAT_WINDOWS 13446 /* set curwin to be our win, temporarily */ 13447 save_curwin = curwin; 13448 curwin = win; 13449 curbuf = curwin->w_buffer; 13450 #endif 13451 13452 if (*varname == '&') 13453 { 13454 long numval; 13455 char_u *strval; 13456 int error = FALSE; 13457 13458 ++varname; 13459 numval = get_tv_number_chk(varp, &error); 13460 strval = get_tv_string_buf_chk(varp, nbuf); 13461 if (!error && strval != NULL) 13462 set_option_value(varname, numval, strval, OPT_LOCAL); 13463 } 13464 else 13465 { 13466 winvarname = alloc((unsigned)STRLEN(varname) + 3); 13467 if (winvarname != NULL) 13468 { 13469 STRCPY(winvarname, "w:"); 13470 STRCPY(winvarname + 2, varname); 13471 set_var(winvarname, varp, TRUE); 13472 vim_free(winvarname); 13473 } 13474 } 13475 13476 #ifdef FEAT_WINDOWS 13477 /* Restore current window, if it's still valid (autocomands can make 13478 * it invalid). */ 13479 if (win_valid(save_curwin)) 13480 { 13481 curwin = save_curwin; 13482 curbuf = curwin->w_buffer; 13483 } 13484 #endif 13485 } 13486 } 13487 13488 /* 13489 * "simplify()" function 13490 */ 13491 static void 13492 f_simplify(argvars, rettv) 13493 typval_T *argvars; 13494 typval_T *rettv; 13495 { 13496 char_u *p; 13497 13498 p = get_tv_string(&argvars[0]); 13499 rettv->vval.v_string = vim_strsave(p); 13500 simplify_filename(rettv->vval.v_string); /* simplify in place */ 13501 rettv->v_type = VAR_STRING; 13502 } 13503 13504 static int 13505 #ifdef __BORLANDC__ 13506 _RTLENTRYF 13507 #endif 13508 item_compare __ARGS((const void *s1, const void *s2)); 13509 static int 13510 #ifdef __BORLANDC__ 13511 _RTLENTRYF 13512 #endif 13513 item_compare2 __ARGS((const void *s1, const void *s2)); 13514 13515 static int item_compare_ic; 13516 static char_u *item_compare_func; 13517 static int item_compare_func_err; 13518 #define ITEM_COMPARE_FAIL 999 13519 13520 /* 13521 * Compare functions for f_sort() below. 13522 */ 13523 static int 13524 #ifdef __BORLANDC__ 13525 _RTLENTRYF 13526 #endif 13527 item_compare(s1, s2) 13528 const void *s1; 13529 const void *s2; 13530 { 13531 char_u *p1, *p2; 13532 char_u *tofree1, *tofree2; 13533 int res; 13534 char_u numbuf1[NUMBUFLEN]; 13535 char_u numbuf2[NUMBUFLEN]; 13536 13537 p1 = tv2string(&(*(listitem_T **)s1)->li_tv, &tofree1, numbuf1); 13538 p2 = tv2string(&(*(listitem_T **)s2)->li_tv, &tofree2, numbuf2); 13539 if (item_compare_ic) 13540 res = STRICMP(p1, p2); 13541 else 13542 res = STRCMP(p1, p2); 13543 vim_free(tofree1); 13544 vim_free(tofree2); 13545 return res; 13546 } 13547 13548 static int 13549 #ifdef __BORLANDC__ 13550 _RTLENTRYF 13551 #endif 13552 item_compare2(s1, s2) 13553 const void *s1; 13554 const void *s2; 13555 { 13556 int res; 13557 typval_T rettv; 13558 typval_T argv[2]; 13559 int dummy; 13560 13561 /* shortcut after failure in previous call; compare all items equal */ 13562 if (item_compare_func_err) 13563 return 0; 13564 13565 /* copy the values. This is needed to be able to set v_lock to VAR_FIXED 13566 * in the copy without changing the original list items. */ 13567 copy_tv(&(*(listitem_T **)s1)->li_tv, &argv[0]); 13568 copy_tv(&(*(listitem_T **)s2)->li_tv, &argv[1]); 13569 13570 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */ 13571 res = call_func(item_compare_func, STRLEN(item_compare_func), 13572 &rettv, 2, argv, 0L, 0L, &dummy, TRUE, NULL); 13573 clear_tv(&argv[0]); 13574 clear_tv(&argv[1]); 13575 13576 if (res == FAIL) 13577 res = ITEM_COMPARE_FAIL; 13578 else 13579 /* return value has wrong type */ 13580 res = get_tv_number_chk(&rettv, &item_compare_func_err); 13581 if (item_compare_func_err) 13582 res = ITEM_COMPARE_FAIL; 13583 clear_tv(&rettv); 13584 return res; 13585 } 13586 13587 /* 13588 * "sort({list})" function 13589 */ 13590 static void 13591 f_sort(argvars, rettv) 13592 typval_T *argvars; 13593 typval_T *rettv; 13594 { 13595 list_T *l; 13596 listitem_T *li; 13597 listitem_T **ptrs; 13598 long len; 13599 long i; 13600 13601 rettv->vval.v_number = 0; 13602 if (argvars[0].v_type != VAR_LIST) 13603 EMSG2(_(e_listarg), "sort()"); 13604 else 13605 { 13606 l = argvars[0].vval.v_list; 13607 if (l == NULL || tv_check_lock(l->lv_lock, (char_u *)"sort()")) 13608 return; 13609 rettv->vval.v_list = l; 13610 rettv->v_type = VAR_LIST; 13611 ++l->lv_refcount; 13612 13613 len = list_len(l); 13614 if (len <= 1) 13615 return; /* short list sorts pretty quickly */ 13616 13617 item_compare_ic = FALSE; 13618 item_compare_func = NULL; 13619 if (argvars[1].v_type != VAR_UNKNOWN) 13620 { 13621 if (argvars[1].v_type == VAR_FUNC) 13622 item_compare_func = argvars[1].vval.v_string; 13623 else 13624 { 13625 int error = FALSE; 13626 13627 i = get_tv_number_chk(&argvars[1], &error); 13628 if (error) 13629 return; /* type error; errmsg already given */ 13630 if (i == 1) 13631 item_compare_ic = TRUE; 13632 else 13633 item_compare_func = get_tv_string(&argvars[1]); 13634 } 13635 } 13636 13637 /* Make an array with each entry pointing to an item in the List. */ 13638 ptrs = (listitem_T **)alloc((int)(len * sizeof(listitem_T *))); 13639 if (ptrs == NULL) 13640 return; 13641 i = 0; 13642 for (li = l->lv_first; li != NULL; li = li->li_next) 13643 ptrs[i++] = li; 13644 13645 item_compare_func_err = FALSE; 13646 /* test the compare function */ 13647 if (item_compare_func != NULL 13648 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1]) 13649 == ITEM_COMPARE_FAIL) 13650 EMSG(_("E702: Sort compare function failed")); 13651 else 13652 { 13653 /* Sort the array with item pointers. */ 13654 qsort((void *)ptrs, (size_t)len, sizeof(listitem_T *), 13655 item_compare_func == NULL ? item_compare : item_compare2); 13656 13657 if (!item_compare_func_err) 13658 { 13659 /* Clear the List and append the items in the sorted order. */ 13660 l->lv_first = l->lv_last = NULL; 13661 l->lv_len = 0; 13662 for (i = 0; i < len; ++i) 13663 list_append(l, ptrs[i]); 13664 } 13665 } 13666 13667 vim_free(ptrs); 13668 } 13669 } 13670 13671 /* 13672 * "soundfold({word})" function 13673 */ 13674 static void 13675 f_soundfold(argvars, rettv) 13676 typval_T *argvars; 13677 typval_T *rettv; 13678 { 13679 char_u *s; 13680 13681 rettv->v_type = VAR_STRING; 13682 s = get_tv_string(&argvars[0]); 13683 #ifdef FEAT_SYN_HL 13684 rettv->vval.v_string = eval_soundfold(s); 13685 #else 13686 rettv->vval.v_string = vim_strsave(s); 13687 #endif 13688 } 13689 13690 /* 13691 * "spellbadword()" function 13692 */ 13693 /* ARGSUSED */ 13694 static void 13695 f_spellbadword(argvars, rettv) 13696 typval_T *argvars; 13697 typval_T *rettv; 13698 { 13699 int attr; 13700 char_u *ptr; 13701 int len; 13702 13703 rettv->vval.v_string = NULL; 13704 rettv->v_type = VAR_STRING; 13705 13706 #ifdef FEAT_SYN_HL 13707 /* Find the start of the badly spelled word. */ 13708 if (spell_move_to(FORWARD, TRUE, TRUE) == FAIL) 13709 return; 13710 13711 /* Get the length of the word and copy it. */ 13712 ptr = ml_get_cursor(); 13713 len = spell_check(curwin, ptr, &attr, NULL); 13714 rettv->vval.v_string = vim_strnsave(ptr, len); 13715 #endif 13716 } 13717 13718 /* 13719 * "spellsuggest()" function 13720 */ 13721 static void 13722 f_spellsuggest(argvars, rettv) 13723 typval_T *argvars; 13724 typval_T *rettv; 13725 { 13726 char_u *str; 13727 int maxcount; 13728 garray_T ga; 13729 list_T *l; 13730 listitem_T *li; 13731 int i; 13732 13733 l = list_alloc(); 13734 if (l == NULL) 13735 return; 13736 rettv->v_type = VAR_LIST; 13737 rettv->vval.v_list = l; 13738 ++l->lv_refcount; 13739 13740 #ifdef FEAT_SYN_HL 13741 if (curwin->w_p_spell && *curbuf->b_p_spl != NUL) 13742 { 13743 str = get_tv_string(&argvars[0]); 13744 if (argvars[1].v_type != VAR_UNKNOWN) 13745 { 13746 maxcount = get_tv_number(&argvars[1]); 13747 if (maxcount <= 0) 13748 return; 13749 } 13750 else 13751 maxcount = 25; 13752 13753 spell_suggest_list(&ga, str, maxcount); 13754 13755 for (i = 0; i < ga.ga_len; ++i) 13756 { 13757 str = ((char_u **)ga.ga_data)[i]; 13758 13759 li = listitem_alloc(); 13760 if (li == NULL) 13761 vim_free(str); 13762 else 13763 { 13764 li->li_tv.v_type = VAR_STRING; 13765 li->li_tv.v_lock = 0; 13766 li->li_tv.vval.v_string = str; 13767 list_append(l, li); 13768 } 13769 } 13770 ga_clear(&ga); 13771 } 13772 #endif 13773 } 13774 13775 static void 13776 f_split(argvars, rettv) 13777 typval_T *argvars; 13778 typval_T *rettv; 13779 { 13780 char_u *str; 13781 char_u *end; 13782 char_u *pat = NULL; 13783 regmatch_T regmatch; 13784 char_u patbuf[NUMBUFLEN]; 13785 char_u *save_cpo; 13786 int match; 13787 listitem_T *ni; 13788 list_T *l; 13789 colnr_T col = 0; 13790 int keepempty = FALSE; 13791 int typeerr = FALSE; 13792 13793 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 13794 save_cpo = p_cpo; 13795 p_cpo = (char_u *)""; 13796 13797 str = get_tv_string(&argvars[0]); 13798 if (argvars[1].v_type != VAR_UNKNOWN) 13799 { 13800 pat = get_tv_string_buf_chk(&argvars[1], patbuf); 13801 if (pat == NULL) 13802 typeerr = TRUE; 13803 if (argvars[2].v_type != VAR_UNKNOWN) 13804 keepempty = get_tv_number_chk(&argvars[2], &typeerr); 13805 } 13806 if (pat == NULL || *pat == NUL) 13807 pat = (char_u *)"[\\x01- ]\\+"; 13808 13809 l = list_alloc(); 13810 if (l == NULL) 13811 return; 13812 rettv->v_type = VAR_LIST; 13813 rettv->vval.v_list = l; 13814 ++l->lv_refcount; 13815 if (typeerr) 13816 return; 13817 13818 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 13819 if (regmatch.regprog != NULL) 13820 { 13821 regmatch.rm_ic = FALSE; 13822 while (*str != NUL || keepempty) 13823 { 13824 if (*str == NUL) 13825 match = FALSE; /* empty item at the end */ 13826 else 13827 match = vim_regexec_nl(®match, str, col); 13828 if (match) 13829 end = regmatch.startp[0]; 13830 else 13831 end = str + STRLEN(str); 13832 if (keepempty || end > str || (l->lv_len > 0 && *str != NUL 13833 && match && end < regmatch.endp[0])) 13834 { 13835 ni = listitem_alloc(); 13836 if (ni == NULL) 13837 break; 13838 ni->li_tv.v_type = VAR_STRING; 13839 ni->li_tv.v_lock = 0; 13840 ni->li_tv.vval.v_string = vim_strnsave(str, end - str); 13841 list_append(l, ni); 13842 } 13843 if (!match) 13844 break; 13845 /* Advance to just after the match. */ 13846 if (regmatch.endp[0] > str) 13847 col = 0; 13848 else 13849 { 13850 /* Don't get stuck at the same match. */ 13851 #ifdef FEAT_MBYTE 13852 col = mb_ptr2len_check(regmatch.endp[0]); 13853 #else 13854 col = 1; 13855 #endif 13856 } 13857 str = regmatch.endp[0]; 13858 } 13859 13860 vim_free(regmatch.regprog); 13861 } 13862 13863 p_cpo = save_cpo; 13864 } 13865 13866 #ifdef HAVE_STRFTIME 13867 /* 13868 * "strftime({format}[, {time}])" function 13869 */ 13870 static void 13871 f_strftime(argvars, rettv) 13872 typval_T *argvars; 13873 typval_T *rettv; 13874 { 13875 char_u result_buf[256]; 13876 struct tm *curtime; 13877 time_t seconds; 13878 char_u *p; 13879 13880 rettv->v_type = VAR_STRING; 13881 13882 p = get_tv_string(&argvars[0]); 13883 if (argvars[1].v_type == VAR_UNKNOWN) 13884 seconds = time(NULL); 13885 else 13886 seconds = (time_t)get_tv_number(&argvars[1]); 13887 curtime = localtime(&seconds); 13888 /* MSVC returns NULL for an invalid value of seconds. */ 13889 if (curtime == NULL) 13890 rettv->vval.v_string = vim_strsave((char_u *)_("(Invalid)")); 13891 else 13892 { 13893 # ifdef FEAT_MBYTE 13894 vimconv_T conv; 13895 char_u *enc; 13896 13897 conv.vc_type = CONV_NONE; 13898 enc = enc_locale(); 13899 convert_setup(&conv, p_enc, enc); 13900 if (conv.vc_type != CONV_NONE) 13901 p = string_convert(&conv, p, NULL); 13902 # endif 13903 if (p != NULL) 13904 (void)strftime((char *)result_buf, sizeof(result_buf), 13905 (char *)p, curtime); 13906 else 13907 result_buf[0] = NUL; 13908 13909 # ifdef FEAT_MBYTE 13910 if (conv.vc_type != CONV_NONE) 13911 vim_free(p); 13912 convert_setup(&conv, enc, p_enc); 13913 if (conv.vc_type != CONV_NONE) 13914 rettv->vval.v_string = string_convert(&conv, result_buf, NULL); 13915 else 13916 # endif 13917 rettv->vval.v_string = vim_strsave(result_buf); 13918 13919 # ifdef FEAT_MBYTE 13920 /* Release conversion descriptors */ 13921 convert_setup(&conv, NULL, NULL); 13922 vim_free(enc); 13923 # endif 13924 } 13925 } 13926 #endif 13927 13928 /* 13929 * "stridx()" function 13930 */ 13931 static void 13932 f_stridx(argvars, rettv) 13933 typval_T *argvars; 13934 typval_T *rettv; 13935 { 13936 char_u buf[NUMBUFLEN]; 13937 char_u *needle; 13938 char_u *haystack; 13939 char_u *save_haystack; 13940 char_u *pos; 13941 int start_idx; 13942 13943 needle = get_tv_string_chk(&argvars[1]); 13944 save_haystack = haystack = get_tv_string_buf_chk(&argvars[0], buf); 13945 rettv->vval.v_number = -1; 13946 if (needle == NULL || haystack == NULL) 13947 return; /* type error; errmsg already given */ 13948 13949 if (argvars[2].v_type != VAR_UNKNOWN) 13950 { 13951 int error = FALSE; 13952 13953 start_idx = get_tv_number_chk(&argvars[2], &error); 13954 if (error || start_idx >= (int)STRLEN(haystack)) 13955 return; 13956 if (start_idx >= 0) 13957 haystack += start_idx; 13958 } 13959 13960 pos = (char_u *)strstr((char *)haystack, (char *)needle); 13961 if (pos != NULL) 13962 rettv->vval.v_number = (varnumber_T)(pos - save_haystack); 13963 } 13964 13965 /* 13966 * "string()" function 13967 */ 13968 static void 13969 f_string(argvars, rettv) 13970 typval_T *argvars; 13971 typval_T *rettv; 13972 { 13973 char_u *tofree; 13974 char_u numbuf[NUMBUFLEN]; 13975 13976 rettv->v_type = VAR_STRING; 13977 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); 13978 if (tofree == NULL) 13979 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); 13980 } 13981 13982 /* 13983 * "strlen()" function 13984 */ 13985 static void 13986 f_strlen(argvars, rettv) 13987 typval_T *argvars; 13988 typval_T *rettv; 13989 { 13990 rettv->vval.v_number = (varnumber_T)(STRLEN( 13991 get_tv_string(&argvars[0]))); 13992 } 13993 13994 /* 13995 * "strpart()" function 13996 */ 13997 static void 13998 f_strpart(argvars, rettv) 13999 typval_T *argvars; 14000 typval_T *rettv; 14001 { 14002 char_u *p; 14003 int n; 14004 int len; 14005 int slen; 14006 int error = FALSE; 14007 14008 p = get_tv_string(&argvars[0]); 14009 slen = (int)STRLEN(p); 14010 14011 n = get_tv_number_chk(&argvars[1], &error); 14012 if (error) 14013 len = 0; 14014 else if (argvars[2].v_type != VAR_UNKNOWN) 14015 len = get_tv_number(&argvars[2]); 14016 else 14017 len = slen - n; /* default len: all bytes that are available. */ 14018 14019 /* 14020 * Only return the overlap between the specified part and the actual 14021 * string. 14022 */ 14023 if (n < 0) 14024 { 14025 len += n; 14026 n = 0; 14027 } 14028 else if (n > slen) 14029 n = slen; 14030 if (len < 0) 14031 len = 0; 14032 else if (n + len > slen) 14033 len = slen - n; 14034 14035 rettv->v_type = VAR_STRING; 14036 rettv->vval.v_string = vim_strnsave(p + n, len); 14037 } 14038 14039 /* 14040 * "strridx()" function 14041 */ 14042 static void 14043 f_strridx(argvars, rettv) 14044 typval_T *argvars; 14045 typval_T *rettv; 14046 { 14047 char_u buf[NUMBUFLEN]; 14048 char_u *needle; 14049 char_u *haystack; 14050 char_u *rest; 14051 char_u *lastmatch = NULL; 14052 int haystack_len, end_idx; 14053 14054 needle = get_tv_string_chk(&argvars[1]); 14055 haystack = get_tv_string_buf_chk(&argvars[0], buf); 14056 haystack_len = STRLEN(haystack); 14057 14058 rettv->vval.v_number = -1; 14059 if (needle == NULL || haystack == NULL) 14060 return; /* type error; errmsg already given */ 14061 if (argvars[2].v_type != VAR_UNKNOWN) 14062 { 14063 /* Third argument: upper limit for index */ 14064 end_idx = get_tv_number_chk(&argvars[2], NULL); 14065 if (end_idx < 0) 14066 return; /* can never find a match */ 14067 } 14068 else 14069 end_idx = haystack_len; 14070 14071 if (*needle == NUL) 14072 { 14073 /* Empty string matches past the end. */ 14074 lastmatch = haystack + end_idx; 14075 } 14076 else 14077 { 14078 for (rest = haystack; *rest != '\0'; ++rest) 14079 { 14080 rest = (char_u *)strstr((char *)rest, (char *)needle); 14081 if (rest == NULL || rest > haystack + end_idx) 14082 break; 14083 lastmatch = rest; 14084 } 14085 } 14086 14087 if (lastmatch == NULL) 14088 rettv->vval.v_number = -1; 14089 else 14090 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 14091 } 14092 14093 /* 14094 * "strtrans()" function 14095 */ 14096 static void 14097 f_strtrans(argvars, rettv) 14098 typval_T *argvars; 14099 typval_T *rettv; 14100 { 14101 rettv->v_type = VAR_STRING; 14102 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 14103 } 14104 14105 /* 14106 * "submatch()" function 14107 */ 14108 static void 14109 f_submatch(argvars, rettv) 14110 typval_T *argvars; 14111 typval_T *rettv; 14112 { 14113 rettv->v_type = VAR_STRING; 14114 rettv->vval.v_string = 14115 reg_submatch((int)get_tv_number_chk(&argvars[0], NULL)); 14116 } 14117 14118 /* 14119 * "substitute()" function 14120 */ 14121 static void 14122 f_substitute(argvars, rettv) 14123 typval_T *argvars; 14124 typval_T *rettv; 14125 { 14126 char_u patbuf[NUMBUFLEN]; 14127 char_u subbuf[NUMBUFLEN]; 14128 char_u flagsbuf[NUMBUFLEN]; 14129 14130 char_u *str = get_tv_string_chk(&argvars[0]); 14131 char_u *pat = get_tv_string_buf_chk(&argvars[1], patbuf); 14132 char_u *sub = get_tv_string_buf_chk(&argvars[2], subbuf); 14133 char_u *flg = get_tv_string_buf_chk(&argvars[3], flagsbuf); 14134 14135 rettv->v_type = VAR_STRING; 14136 if (str == NULL || pat == NULL || sub == NULL || flg == NULL) 14137 rettv->vval.v_string = NULL; 14138 else 14139 rettv->vval.v_string = do_string_sub(str, pat, sub, flg); 14140 } 14141 14142 /* 14143 * "synID(lnum, col, trans)" function 14144 */ 14145 /*ARGSUSED*/ 14146 static void 14147 f_synID(argvars, rettv) 14148 typval_T *argvars; 14149 typval_T *rettv; 14150 { 14151 int id = 0; 14152 #ifdef FEAT_SYN_HL 14153 long lnum; 14154 long col; 14155 int trans; 14156 int transerr = FALSE; 14157 14158 lnum = get_tv_lnum(argvars); /* -1 on type error */ 14159 col = get_tv_number(&argvars[1]) - 1; /* -1 on type error */ 14160 trans = get_tv_number_chk(&argvars[2], &transerr); 14161 14162 if (!transerr && lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count 14163 && col >= 0 && col < (long)STRLEN(ml_get(lnum))) 14164 id = syn_get_id(lnum, (colnr_T)col, trans, NULL); 14165 #endif 14166 14167 rettv->vval.v_number = id; 14168 } 14169 14170 /* 14171 * "synIDattr(id, what [, mode])" function 14172 */ 14173 /*ARGSUSED*/ 14174 static void 14175 f_synIDattr(argvars, rettv) 14176 typval_T *argvars; 14177 typval_T *rettv; 14178 { 14179 char_u *p = NULL; 14180 #ifdef FEAT_SYN_HL 14181 int id; 14182 char_u *what; 14183 char_u *mode; 14184 char_u modebuf[NUMBUFLEN]; 14185 int modec; 14186 14187 id = get_tv_number(&argvars[0]); 14188 what = get_tv_string(&argvars[1]); 14189 if (argvars[2].v_type != VAR_UNKNOWN) 14190 { 14191 mode = get_tv_string_buf(&argvars[2], modebuf); 14192 modec = TOLOWER_ASC(mode[0]); 14193 if (modec != 't' && modec != 'c' 14194 #ifdef FEAT_GUI 14195 && modec != 'g' 14196 #endif 14197 ) 14198 modec = 0; /* replace invalid with current */ 14199 } 14200 else 14201 { 14202 #ifdef FEAT_GUI 14203 if (gui.in_use) 14204 modec = 'g'; 14205 else 14206 #endif 14207 if (t_colors > 1) 14208 modec = 'c'; 14209 else 14210 modec = 't'; 14211 } 14212 14213 14214 switch (TOLOWER_ASC(what[0])) 14215 { 14216 case 'b': 14217 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 14218 p = highlight_color(id, what, modec); 14219 else /* bold */ 14220 p = highlight_has_attr(id, HL_BOLD, modec); 14221 break; 14222 14223 case 'f': /* fg[#] */ 14224 p = highlight_color(id, what, modec); 14225 break; 14226 14227 case 'i': 14228 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 14229 p = highlight_has_attr(id, HL_INVERSE, modec); 14230 else /* italic */ 14231 p = highlight_has_attr(id, HL_ITALIC, modec); 14232 break; 14233 14234 case 'n': /* name */ 14235 p = get_highlight_name(NULL, id - 1); 14236 break; 14237 14238 case 'r': /* reverse */ 14239 p = highlight_has_attr(id, HL_INVERSE, modec); 14240 break; 14241 14242 case 's': /* standout */ 14243 p = highlight_has_attr(id, HL_STANDOUT, modec); 14244 break; 14245 14246 case 'u': 14247 if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') 14248 /* underline */ 14249 p = highlight_has_attr(id, HL_UNDERLINE, modec); 14250 else 14251 /* undercurl */ 14252 p = highlight_has_attr(id, HL_UNDERCURL, modec); 14253 break; 14254 } 14255 14256 if (p != NULL) 14257 p = vim_strsave(p); 14258 #endif 14259 rettv->v_type = VAR_STRING; 14260 rettv->vval.v_string = p; 14261 } 14262 14263 /* 14264 * "synIDtrans(id)" function 14265 */ 14266 /*ARGSUSED*/ 14267 static void 14268 f_synIDtrans(argvars, rettv) 14269 typval_T *argvars; 14270 typval_T *rettv; 14271 { 14272 int id; 14273 14274 #ifdef FEAT_SYN_HL 14275 id = get_tv_number(&argvars[0]); 14276 14277 if (id > 0) 14278 id = syn_get_final_id(id); 14279 else 14280 #endif 14281 id = 0; 14282 14283 rettv->vval.v_number = id; 14284 } 14285 14286 /* 14287 * "system()" function 14288 */ 14289 static void 14290 f_system(argvars, rettv) 14291 typval_T *argvars; 14292 typval_T *rettv; 14293 { 14294 char_u *res = NULL; 14295 char_u *p; 14296 char_u *infile = NULL; 14297 char_u buf[NUMBUFLEN]; 14298 int err = FALSE; 14299 FILE *fd; 14300 14301 if (argvars[1].v_type != VAR_UNKNOWN) 14302 { 14303 /* 14304 * Write the string to a temp file, to be used for input of the shell 14305 * command. 14306 */ 14307 if ((infile = vim_tempname('i')) == NULL) 14308 { 14309 EMSG(_(e_notmp)); 14310 return; 14311 } 14312 14313 fd = mch_fopen((char *)infile, WRITEBIN); 14314 if (fd == NULL) 14315 { 14316 EMSG2(_(e_notopen), infile); 14317 goto done; 14318 } 14319 p = get_tv_string_buf_chk(&argvars[1], buf); 14320 if (p == NULL) 14321 goto done; /* type error; errmsg already given */ 14322 if (fwrite(p, STRLEN(p), 1, fd) != 1) 14323 err = TRUE; 14324 if (fclose(fd) != 0) 14325 err = TRUE; 14326 if (err) 14327 { 14328 EMSG(_("E677: Error writing temp file")); 14329 goto done; 14330 } 14331 } 14332 14333 res = get_cmd_output(get_tv_string(&argvars[0]), infile, SHELL_SILENT); 14334 14335 #ifdef USE_CR 14336 /* translate <CR> into <NL> */ 14337 if (res != NULL) 14338 { 14339 char_u *s; 14340 14341 for (s = res; *s; ++s) 14342 { 14343 if (*s == CAR) 14344 *s = NL; 14345 } 14346 } 14347 #else 14348 # ifdef USE_CRNL 14349 /* translate <CR><NL> into <NL> */ 14350 if (res != NULL) 14351 { 14352 char_u *s, *d; 14353 14354 d = res; 14355 for (s = res; *s; ++s) 14356 { 14357 if (s[0] == CAR && s[1] == NL) 14358 ++s; 14359 *d++ = *s; 14360 } 14361 *d = NUL; 14362 } 14363 # endif 14364 #endif 14365 14366 done: 14367 if (infile != NULL) 14368 { 14369 mch_remove(infile); 14370 vim_free(infile); 14371 } 14372 rettv->v_type = VAR_STRING; 14373 rettv->vval.v_string = res; 14374 } 14375 14376 /* 14377 * "taglist()" function 14378 */ 14379 static void 14380 f_taglist(argvars, rettv) 14381 typval_T *argvars; 14382 typval_T *rettv; 14383 { 14384 char_u *tag_pattern; 14385 list_T *l; 14386 14387 tag_pattern = get_tv_string(&argvars[0]); 14388 14389 rettv->vval.v_number = FALSE; 14390 if (*tag_pattern == NUL) 14391 return; 14392 14393 l = list_alloc(); 14394 if (l != NULL) 14395 { 14396 if (get_tags(l, tag_pattern) != FAIL) 14397 { 14398 rettv->vval.v_list = l; 14399 rettv->v_type = VAR_LIST; 14400 ++l->lv_refcount; 14401 } 14402 else 14403 list_free(l); 14404 } 14405 } 14406 14407 /* 14408 * "tempname()" function 14409 */ 14410 /*ARGSUSED*/ 14411 static void 14412 f_tempname(argvars, rettv) 14413 typval_T *argvars; 14414 typval_T *rettv; 14415 { 14416 static int x = 'A'; 14417 14418 rettv->v_type = VAR_STRING; 14419 rettv->vval.v_string = vim_tempname(x); 14420 14421 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 14422 * names. Skip 'I' and 'O', they are used for shell redirection. */ 14423 do 14424 { 14425 if (x == 'Z') 14426 x = '0'; 14427 else if (x == '9') 14428 x = 'A'; 14429 else 14430 { 14431 #ifdef EBCDIC 14432 if (x == 'I') 14433 x = 'J'; 14434 else if (x == 'R') 14435 x = 'S'; 14436 else 14437 #endif 14438 ++x; 14439 } 14440 } while (x == 'I' || x == 'O'); 14441 } 14442 14443 /* 14444 * "tolower(string)" function 14445 */ 14446 static void 14447 f_tolower(argvars, rettv) 14448 typval_T *argvars; 14449 typval_T *rettv; 14450 { 14451 char_u *p; 14452 14453 p = vim_strsave(get_tv_string(&argvars[0])); 14454 rettv->v_type = VAR_STRING; 14455 rettv->vval.v_string = p; 14456 14457 if (p != NULL) 14458 while (*p != NUL) 14459 { 14460 #ifdef FEAT_MBYTE 14461 int l; 14462 14463 if (enc_utf8) 14464 { 14465 int c, lc; 14466 14467 c = utf_ptr2char(p); 14468 lc = utf_tolower(c); 14469 l = utf_ptr2len_check(p); 14470 /* TODO: reallocate string when byte count changes. */ 14471 if (utf_char2len(lc) == l) 14472 utf_char2bytes(lc, p); 14473 p += l; 14474 } 14475 else if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1) 14476 p += l; /* skip multi-byte character */ 14477 else 14478 #endif 14479 { 14480 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 14481 ++p; 14482 } 14483 } 14484 } 14485 14486 /* 14487 * "toupper(string)" function 14488 */ 14489 static void 14490 f_toupper(argvars, rettv) 14491 typval_T *argvars; 14492 typval_T *rettv; 14493 { 14494 rettv->v_type = VAR_STRING; 14495 rettv->vval.v_string = strup_save(get_tv_string(&argvars[0])); 14496 } 14497 14498 /* 14499 * "tr(string, fromstr, tostr)" function 14500 */ 14501 static void 14502 f_tr(argvars, rettv) 14503 typval_T *argvars; 14504 typval_T *rettv; 14505 { 14506 char_u *instr; 14507 char_u *fromstr; 14508 char_u *tostr; 14509 char_u *p; 14510 #ifdef FEAT_MBYTE 14511 int inlen; 14512 int fromlen; 14513 int tolen; 14514 int idx; 14515 char_u *cpstr; 14516 int cplen; 14517 int first = TRUE; 14518 #endif 14519 char_u buf[NUMBUFLEN]; 14520 char_u buf2[NUMBUFLEN]; 14521 garray_T ga; 14522 14523 instr = get_tv_string(&argvars[0]); 14524 fromstr = get_tv_string_buf_chk(&argvars[1], buf); 14525 tostr = get_tv_string_buf_chk(&argvars[2], buf2); 14526 14527 /* Default return value: empty string. */ 14528 rettv->v_type = VAR_STRING; 14529 rettv->vval.v_string = NULL; 14530 if (fromstr == NULL || tostr == NULL) 14531 return; /* type error; errmsg already given */ 14532 ga_init2(&ga, (int)sizeof(char), 80); 14533 14534 #ifdef FEAT_MBYTE 14535 if (!has_mbyte) 14536 #endif 14537 /* not multi-byte: fromstr and tostr must be the same length */ 14538 if (STRLEN(fromstr) != STRLEN(tostr)) 14539 { 14540 #ifdef FEAT_MBYTE 14541 error: 14542 #endif 14543 EMSG2(_(e_invarg2), fromstr); 14544 ga_clear(&ga); 14545 return; 14546 } 14547 14548 /* fromstr and tostr have to contain the same number of chars */ 14549 while (*instr != NUL) 14550 { 14551 #ifdef FEAT_MBYTE 14552 if (has_mbyte) 14553 { 14554 inlen = mb_ptr2len_check(instr); 14555 cpstr = instr; 14556 cplen = inlen; 14557 idx = 0; 14558 for (p = fromstr; *p != NUL; p += fromlen) 14559 { 14560 fromlen = mb_ptr2len_check(p); 14561 if (fromlen == inlen && STRNCMP(instr, p, inlen) == 0) 14562 { 14563 for (p = tostr; *p != NUL; p += tolen) 14564 { 14565 tolen = mb_ptr2len_check(p); 14566 if (idx-- == 0) 14567 { 14568 cplen = tolen; 14569 cpstr = p; 14570 break; 14571 } 14572 } 14573 if (*p == NUL) /* tostr is shorter than fromstr */ 14574 goto error; 14575 break; 14576 } 14577 ++idx; 14578 } 14579 14580 if (first && cpstr == instr) 14581 { 14582 /* Check that fromstr and tostr have the same number of 14583 * (multi-byte) characters. Done only once when a character 14584 * of instr doesn't appear in fromstr. */ 14585 first = FALSE; 14586 for (p = tostr; *p != NUL; p += tolen) 14587 { 14588 tolen = mb_ptr2len_check(p); 14589 --idx; 14590 } 14591 if (idx != 0) 14592 goto error; 14593 } 14594 14595 ga_grow(&ga, cplen); 14596 mch_memmove((char *)ga.ga_data + ga.ga_len, cpstr, (size_t)cplen); 14597 ga.ga_len += cplen; 14598 14599 instr += inlen; 14600 } 14601 else 14602 #endif 14603 { 14604 /* When not using multi-byte chars we can do it faster. */ 14605 p = vim_strchr(fromstr, *instr); 14606 if (p != NULL) 14607 ga_append(&ga, tostr[p - fromstr]); 14608 else 14609 ga_append(&ga, *instr); 14610 ++instr; 14611 } 14612 } 14613 14614 rettv->vval.v_string = ga.ga_data; 14615 } 14616 14617 /* 14618 * "type(expr)" function 14619 */ 14620 static void 14621 f_type(argvars, rettv) 14622 typval_T *argvars; 14623 typval_T *rettv; 14624 { 14625 int n; 14626 14627 switch (argvars[0].v_type) 14628 { 14629 case VAR_NUMBER: n = 0; break; 14630 case VAR_STRING: n = 1; break; 14631 case VAR_FUNC: n = 2; break; 14632 case VAR_LIST: n = 3; break; 14633 case VAR_DICT: n = 4; break; 14634 default: EMSG2(_(e_intern2), "f_type()"); n = 0; break; 14635 } 14636 rettv->vval.v_number = n; 14637 } 14638 14639 /* 14640 * "values(dict)" function 14641 */ 14642 static void 14643 f_values(argvars, rettv) 14644 typval_T *argvars; 14645 typval_T *rettv; 14646 { 14647 dict_list(argvars, rettv, 1); 14648 } 14649 14650 /* 14651 * "virtcol(string)" function 14652 */ 14653 static void 14654 f_virtcol(argvars, rettv) 14655 typval_T *argvars; 14656 typval_T *rettv; 14657 { 14658 colnr_T vcol = 0; 14659 pos_T *fp; 14660 14661 fp = var2fpos(&argvars[0], FALSE); 14662 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 14663 { 14664 getvvcol(curwin, fp, NULL, NULL, &vcol); 14665 ++vcol; 14666 } 14667 14668 rettv->vval.v_number = vcol; 14669 } 14670 14671 /* 14672 * "visualmode()" function 14673 */ 14674 /*ARGSUSED*/ 14675 static void 14676 f_visualmode(argvars, rettv) 14677 typval_T *argvars; 14678 typval_T *rettv; 14679 { 14680 #ifdef FEAT_VISUAL 14681 char_u str[2]; 14682 14683 rettv->v_type = VAR_STRING; 14684 str[0] = curbuf->b_visual_mode_eval; 14685 str[1] = NUL; 14686 rettv->vval.v_string = vim_strsave(str); 14687 14688 /* A non-zero number or non-empty string argument: reset mode. */ 14689 if ((argvars[0].v_type == VAR_NUMBER 14690 && argvars[0].vval.v_number != 0) 14691 || (argvars[0].v_type == VAR_STRING 14692 && *get_tv_string(&argvars[0]) != NUL)) 14693 curbuf->b_visual_mode_eval = NUL; 14694 #else 14695 rettv->vval.v_number = 0; /* return anything, it won't work anyway */ 14696 #endif 14697 } 14698 14699 /* 14700 * "winbufnr(nr)" function 14701 */ 14702 static void 14703 f_winbufnr(argvars, rettv) 14704 typval_T *argvars; 14705 typval_T *rettv; 14706 { 14707 win_T *wp; 14708 14709 wp = find_win_by_nr(&argvars[0]); 14710 if (wp == NULL) 14711 rettv->vval.v_number = -1; 14712 else 14713 rettv->vval.v_number = wp->w_buffer->b_fnum; 14714 } 14715 14716 /* 14717 * "wincol()" function 14718 */ 14719 /*ARGSUSED*/ 14720 static void 14721 f_wincol(argvars, rettv) 14722 typval_T *argvars; 14723 typval_T *rettv; 14724 { 14725 validate_cursor(); 14726 rettv->vval.v_number = curwin->w_wcol + 1; 14727 } 14728 14729 /* 14730 * "winheight(nr)" function 14731 */ 14732 static void 14733 f_winheight(argvars, rettv) 14734 typval_T *argvars; 14735 typval_T *rettv; 14736 { 14737 win_T *wp; 14738 14739 wp = find_win_by_nr(&argvars[0]); 14740 if (wp == NULL) 14741 rettv->vval.v_number = -1; 14742 else 14743 rettv->vval.v_number = wp->w_height; 14744 } 14745 14746 /* 14747 * "winline()" function 14748 */ 14749 /*ARGSUSED*/ 14750 static void 14751 f_winline(argvars, rettv) 14752 typval_T *argvars; 14753 typval_T *rettv; 14754 { 14755 validate_cursor(); 14756 rettv->vval.v_number = curwin->w_wrow + 1; 14757 } 14758 14759 /* 14760 * "winnr()" function 14761 */ 14762 /* ARGSUSED */ 14763 static void 14764 f_winnr(argvars, rettv) 14765 typval_T *argvars; 14766 typval_T *rettv; 14767 { 14768 int nr = 1; 14769 #ifdef FEAT_WINDOWS 14770 win_T *wp; 14771 win_T *twin = curwin; 14772 char_u *arg; 14773 14774 if (argvars[0].v_type != VAR_UNKNOWN) 14775 { 14776 arg = get_tv_string_chk(&argvars[0]); 14777 if (arg == NULL) 14778 nr = 0; /* type error; errmsg already given */ 14779 else if (STRCMP(arg, "$") == 0) 14780 twin = lastwin; 14781 else if (STRCMP(arg, "#") == 0) 14782 { 14783 twin = prevwin; 14784 if (prevwin == NULL) 14785 nr = 0; 14786 } 14787 else 14788 { 14789 EMSG2(_(e_invexpr2), arg); 14790 nr = 0; 14791 } 14792 } 14793 14794 if (nr > 0) 14795 for (wp = firstwin; wp != twin; wp = wp->w_next) 14796 ++nr; 14797 #endif 14798 rettv->vval.v_number = nr; 14799 } 14800 14801 /* 14802 * "winrestcmd()" function 14803 */ 14804 /* ARGSUSED */ 14805 static void 14806 f_winrestcmd(argvars, rettv) 14807 typval_T *argvars; 14808 typval_T *rettv; 14809 { 14810 #ifdef FEAT_WINDOWS 14811 win_T *wp; 14812 int winnr = 1; 14813 garray_T ga; 14814 char_u buf[50]; 14815 14816 ga_init2(&ga, (int)sizeof(char), 70); 14817 for (wp = firstwin; wp != NULL; wp = wp->w_next) 14818 { 14819 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 14820 ga_concat(&ga, buf); 14821 # ifdef FEAT_VERTSPLIT 14822 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 14823 ga_concat(&ga, buf); 14824 # endif 14825 ++winnr; 14826 } 14827 ga_append(&ga, NUL); 14828 14829 rettv->vval.v_string = ga.ga_data; 14830 #else 14831 rettv->vval.v_string = NULL; 14832 #endif 14833 rettv->v_type = VAR_STRING; 14834 } 14835 14836 /* 14837 * "winwidth(nr)" function 14838 */ 14839 static void 14840 f_winwidth(argvars, rettv) 14841 typval_T *argvars; 14842 typval_T *rettv; 14843 { 14844 win_T *wp; 14845 14846 wp = find_win_by_nr(&argvars[0]); 14847 if (wp == NULL) 14848 rettv->vval.v_number = -1; 14849 else 14850 #ifdef FEAT_VERTSPLIT 14851 rettv->vval.v_number = wp->w_width; 14852 #else 14853 rettv->vval.v_number = Columns; 14854 #endif 14855 } 14856 14857 /* 14858 * "writefile()" function 14859 */ 14860 static void 14861 f_writefile(argvars, rettv) 14862 typval_T *argvars; 14863 typval_T *rettv; 14864 { 14865 int binary = FALSE; 14866 char_u *fname; 14867 FILE *fd; 14868 listitem_T *li; 14869 char_u *s; 14870 int ret = 0; 14871 int c; 14872 14873 if (argvars[0].v_type != VAR_LIST) 14874 { 14875 EMSG2(_(e_listarg), "writefile()"); 14876 return; 14877 } 14878 if (argvars[0].vval.v_list == NULL) 14879 return; 14880 14881 if (argvars[2].v_type != VAR_UNKNOWN 14882 && STRCMP(get_tv_string(&argvars[2]), "b") == 0) 14883 binary = TRUE; 14884 14885 /* Always open the file in binary mode, library functions have a mind of 14886 * their own about CR-LF conversion. */ 14887 fname = get_tv_string(&argvars[1]); 14888 if (*fname == NUL || (fd = mch_fopen((char *)fname, WRITEBIN)) == NULL) 14889 { 14890 EMSG2(_(e_notcreate), *fname == NUL ? (char_u *)_("<empty>") : fname); 14891 ret = -1; 14892 } 14893 else 14894 { 14895 for (li = argvars[0].vval.v_list->lv_first; li != NULL; 14896 li = li->li_next) 14897 { 14898 for (s = get_tv_string(&li->li_tv); *s != NUL; ++s) 14899 { 14900 if (*s == '\n') 14901 c = putc(NUL, fd); 14902 else 14903 c = putc(*s, fd); 14904 if (c == EOF) 14905 { 14906 ret = -1; 14907 break; 14908 } 14909 } 14910 if (!binary || li->li_next != NULL) 14911 if (putc('\n', fd) == EOF) 14912 { 14913 ret = -1; 14914 break; 14915 } 14916 if (ret < 0) 14917 { 14918 EMSG(_(e_write)); 14919 break; 14920 } 14921 } 14922 fclose(fd); 14923 } 14924 14925 rettv->vval.v_number = ret; 14926 } 14927 14928 /* 14929 * Translate a String variable into a position. 14930 */ 14931 static pos_T * 14932 var2fpos(varp, lnum) 14933 typval_T *varp; 14934 int lnum; /* TRUE when $ is last line */ 14935 { 14936 char_u *name; 14937 static pos_T pos; 14938 pos_T *pp; 14939 14940 name = get_tv_string_chk(varp); 14941 if (name == NULL) 14942 return NULL; 14943 if (name[0] == '.') /* cursor */ 14944 return &curwin->w_cursor; 14945 if (name[0] == '\'') /* mark */ 14946 { 14947 pp = getmark(name[1], FALSE); 14948 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 14949 return NULL; 14950 return pp; 14951 } 14952 if (name[0] == '$') /* last column or line */ 14953 { 14954 if (lnum) 14955 { 14956 pos.lnum = curbuf->b_ml.ml_line_count; 14957 pos.col = 0; 14958 } 14959 else 14960 { 14961 pos.lnum = curwin->w_cursor.lnum; 14962 pos.col = (colnr_T)STRLEN(ml_get_curline()); 14963 } 14964 return &pos; 14965 } 14966 return NULL; 14967 } 14968 14969 /* 14970 * Get the length of an environment variable name. 14971 * Advance "arg" to the first character after the name. 14972 * Return 0 for error. 14973 */ 14974 static int 14975 get_env_len(arg) 14976 char_u **arg; 14977 { 14978 char_u *p; 14979 int len; 14980 14981 for (p = *arg; vim_isIDc(*p); ++p) 14982 ; 14983 if (p == *arg) /* no name found */ 14984 return 0; 14985 14986 len = (int)(p - *arg); 14987 *arg = p; 14988 return len; 14989 } 14990 14991 /* 14992 * Get the length of the name of a function or internal variable. 14993 * "arg" is advanced to the first non-white character after the name. 14994 * Return 0 if something is wrong. 14995 */ 14996 static int 14997 get_id_len(arg) 14998 char_u **arg; 14999 { 15000 char_u *p; 15001 int len; 15002 15003 /* Find the end of the name. */ 15004 for (p = *arg; eval_isnamec(*p); ++p) 15005 ; 15006 if (p == *arg) /* no name found */ 15007 return 0; 15008 15009 len = (int)(p - *arg); 15010 *arg = skipwhite(p); 15011 15012 return len; 15013 } 15014 15015 /* 15016 * Get the length of the name of a variable or function. 15017 * Only the name is recognized, does not handle ".key" or "[idx]". 15018 * "arg" is advanced to the first non-white character after the name. 15019 * Return -1 if curly braces expansion failed. 15020 * Return 0 if something else is wrong. 15021 * If the name contains 'magic' {}'s, expand them and return the 15022 * expanded name in an allocated string via 'alias' - caller must free. 15023 */ 15024 static int 15025 get_name_len(arg, alias, evaluate, verbose) 15026 char_u **arg; 15027 char_u **alias; 15028 int evaluate; 15029 int verbose; 15030 { 15031 int len; 15032 char_u *p; 15033 char_u *expr_start; 15034 char_u *expr_end; 15035 15036 *alias = NULL; /* default to no alias */ 15037 15038 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 15039 && (*arg)[2] == (int)KE_SNR) 15040 { 15041 /* hard coded <SNR>, already translated */ 15042 *arg += 3; 15043 return get_id_len(arg) + 3; 15044 } 15045 len = eval_fname_script(*arg); 15046 if (len > 0) 15047 { 15048 /* literal "<SID>", "s:" or "<SNR>" */ 15049 *arg += len; 15050 } 15051 15052 /* 15053 * Find the end of the name; check for {} construction. 15054 */ 15055 p = find_name_end(*arg, &expr_start, &expr_end, 15056 len > 0 ? 0 : FNE_CHECK_START); 15057 if (expr_start != NULL) 15058 { 15059 char_u *temp_string; 15060 15061 if (!evaluate) 15062 { 15063 len += (int)(p - *arg); 15064 *arg = skipwhite(p); 15065 return len; 15066 } 15067 15068 /* 15069 * Include any <SID> etc in the expanded string: 15070 * Thus the -len here. 15071 */ 15072 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 15073 if (temp_string == NULL) 15074 return -1; 15075 *alias = temp_string; 15076 *arg = skipwhite(p); 15077 return (int)STRLEN(temp_string); 15078 } 15079 15080 len += get_id_len(arg); 15081 if (len == 0 && verbose) 15082 EMSG2(_(e_invexpr2), *arg); 15083 15084 return len; 15085 } 15086 15087 /* 15088 * Find the end of a variable or function name, taking care of magic braces. 15089 * If "expr_start" is not NULL then "expr_start" and "expr_end" are set to the 15090 * start and end of the first magic braces item. 15091 * "flags" can have FNE_INCL_BR and FNE_CHECK_START. 15092 * Return a pointer to just after the name. Equal to "arg" if there is no 15093 * valid name. 15094 */ 15095 static char_u * 15096 find_name_end(arg, expr_start, expr_end, flags) 15097 char_u *arg; 15098 char_u **expr_start; 15099 char_u **expr_end; 15100 int flags; 15101 { 15102 int mb_nest = 0; 15103 int br_nest = 0; 15104 char_u *p; 15105 15106 if (expr_start != NULL) 15107 { 15108 *expr_start = NULL; 15109 *expr_end = NULL; 15110 } 15111 15112 /* Quick check for valid starting character. */ 15113 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') 15114 return arg; 15115 15116 for (p = arg; *p != NUL 15117 && (eval_isnamec(*p) 15118 || *p == '{' 15119 || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) 15120 || mb_nest != 0 15121 || br_nest != 0); ++p) 15122 { 15123 if (mb_nest == 0) 15124 { 15125 if (*p == '[') 15126 ++br_nest; 15127 else if (*p == ']') 15128 --br_nest; 15129 } 15130 if (br_nest == 0) 15131 { 15132 if (*p == '{') 15133 { 15134 mb_nest++; 15135 if (expr_start != NULL && *expr_start == NULL) 15136 *expr_start = p; 15137 } 15138 else if (*p == '}') 15139 { 15140 mb_nest--; 15141 if (expr_start != NULL && mb_nest == 0 && *expr_end == NULL) 15142 *expr_end = p; 15143 } 15144 } 15145 } 15146 15147 return p; 15148 } 15149 15150 /* 15151 * Expands out the 'magic' {}'s in a variable/function name. 15152 * Note that this can call itself recursively, to deal with 15153 * constructs like foo{bar}{baz}{bam} 15154 * The four pointer arguments point to "foo{expre}ss{ion}bar" 15155 * "in_start" ^ 15156 * "expr_start" ^ 15157 * "expr_end" ^ 15158 * "in_end" ^ 15159 * 15160 * Returns a new allocated string, which the caller must free. 15161 * Returns NULL for failure. 15162 */ 15163 static char_u * 15164 make_expanded_name(in_start, expr_start, expr_end, in_end) 15165 char_u *in_start; 15166 char_u *expr_start; 15167 char_u *expr_end; 15168 char_u *in_end; 15169 { 15170 char_u c1; 15171 char_u *retval = NULL; 15172 char_u *temp_result; 15173 char_u *nextcmd = NULL; 15174 15175 if (expr_end == NULL || in_end == NULL) 15176 return NULL; 15177 *expr_start = NUL; 15178 *expr_end = NUL; 15179 c1 = *in_end; 15180 *in_end = NUL; 15181 15182 temp_result = eval_to_string(expr_start + 1, &nextcmd); 15183 if (temp_result != NULL && nextcmd == NULL) 15184 { 15185 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 15186 + (in_end - expr_end) + 1)); 15187 if (retval != NULL) 15188 { 15189 STRCPY(retval, in_start); 15190 STRCAT(retval, temp_result); 15191 STRCAT(retval, expr_end + 1); 15192 } 15193 } 15194 vim_free(temp_result); 15195 15196 *in_end = c1; /* put char back for error messages */ 15197 *expr_start = '{'; 15198 *expr_end = '}'; 15199 15200 if (retval != NULL) 15201 { 15202 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); 15203 if (expr_start != NULL) 15204 { 15205 /* Further expansion! */ 15206 temp_result = make_expanded_name(retval, expr_start, 15207 expr_end, temp_result); 15208 vim_free(retval); 15209 retval = temp_result; 15210 } 15211 } 15212 15213 return retval; 15214 } 15215 15216 /* 15217 * Return TRUE if character "c" can be used in a variable or function name. 15218 * Does not include '{' or '}' for magic braces. 15219 */ 15220 static int 15221 eval_isnamec(c) 15222 int c; 15223 { 15224 return (ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR); 15225 } 15226 15227 /* 15228 * Return TRUE if character "c" can be used as the first character in a 15229 * variable or function name (excluding '{' and '}'). 15230 */ 15231 static int 15232 eval_isnamec1(c) 15233 int c; 15234 { 15235 return (ASCII_ISALPHA(c) || c == '_'); 15236 } 15237 15238 /* 15239 * Set number v: variable to "val". 15240 */ 15241 void 15242 set_vim_var_nr(idx, val) 15243 int idx; 15244 long val; 15245 { 15246 vimvars[idx].vv_nr = val; 15247 } 15248 15249 /* 15250 * Get number v: variable value. 15251 */ 15252 long 15253 get_vim_var_nr(idx) 15254 int idx; 15255 { 15256 return vimvars[idx].vv_nr; 15257 } 15258 15259 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15260 /* 15261 * Get string v: variable value. Uses a static buffer, can only be used once. 15262 */ 15263 char_u * 15264 get_vim_var_str(idx) 15265 int idx; 15266 { 15267 return get_tv_string(&vimvars[idx].vv_tv); 15268 } 15269 #endif 15270 15271 /* 15272 * Set v:count, v:count1 and v:prevcount. 15273 */ 15274 void 15275 set_vcount(count, count1) 15276 long count; 15277 long count1; 15278 { 15279 vimvars[VV_PREVCOUNT].vv_nr = vimvars[VV_COUNT].vv_nr; 15280 vimvars[VV_COUNT].vv_nr = count; 15281 vimvars[VV_COUNT1].vv_nr = count1; 15282 } 15283 15284 /* 15285 * Set string v: variable to a copy of "val". 15286 */ 15287 void 15288 set_vim_var_string(idx, val, len) 15289 int idx; 15290 char_u *val; 15291 int len; /* length of "val" to use or -1 (whole string) */ 15292 { 15293 /* Need to do this (at least) once, since we can't initialize a union. 15294 * Will always be invoked when "v:progname" is set. */ 15295 vimvars[VV_VERSION].vv_nr = VIM_VERSION_100; 15296 15297 vim_free(vimvars[idx].vv_str); 15298 if (val == NULL) 15299 vimvars[idx].vv_str = NULL; 15300 else if (len == -1) 15301 vimvars[idx].vv_str = vim_strsave(val); 15302 else 15303 vimvars[idx].vv_str = vim_strnsave(val, len); 15304 } 15305 15306 /* 15307 * Set v:register if needed. 15308 */ 15309 void 15310 set_reg_var(c) 15311 int c; 15312 { 15313 char_u regname; 15314 15315 if (c == 0 || c == ' ') 15316 regname = '"'; 15317 else 15318 regname = c; 15319 /* Avoid free/alloc when the value is already right. */ 15320 if (vimvars[VV_REG].vv_str == NULL || vimvars[VV_REG].vv_str[0] != c) 15321 set_vim_var_string(VV_REG, ®name, 1); 15322 } 15323 15324 /* 15325 * Get or set v:exception. If "oldval" == NULL, return the current value. 15326 * Otherwise, restore the value to "oldval" and return NULL. 15327 * Must always be called in pairs to save and restore v:exception! Does not 15328 * take care of memory allocations. 15329 */ 15330 char_u * 15331 v_exception(oldval) 15332 char_u *oldval; 15333 { 15334 if (oldval == NULL) 15335 return vimvars[VV_EXCEPTION].vv_str; 15336 15337 vimvars[VV_EXCEPTION].vv_str = oldval; 15338 return NULL; 15339 } 15340 15341 /* 15342 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 15343 * Otherwise, restore the value to "oldval" and return NULL. 15344 * Must always be called in pairs to save and restore v:throwpoint! Does not 15345 * take care of memory allocations. 15346 */ 15347 char_u * 15348 v_throwpoint(oldval) 15349 char_u *oldval; 15350 { 15351 if (oldval == NULL) 15352 return vimvars[VV_THROWPOINT].vv_str; 15353 15354 vimvars[VV_THROWPOINT].vv_str = oldval; 15355 return NULL; 15356 } 15357 15358 #if defined(FEAT_AUTOCMD) || defined(PROTO) 15359 /* 15360 * Set v:cmdarg. 15361 * If "eap" != NULL, use "eap" to generate the value and return the old value. 15362 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 15363 * Must always be called in pairs! 15364 */ 15365 char_u * 15366 set_cmdarg(eap, oldarg) 15367 exarg_T *eap; 15368 char_u *oldarg; 15369 { 15370 char_u *oldval; 15371 char_u *newval; 15372 unsigned len; 15373 15374 oldval = vimvars[VV_CMDARG].vv_str; 15375 if (eap == NULL) 15376 { 15377 vim_free(oldval); 15378 vimvars[VV_CMDARG].vv_str = oldarg; 15379 return NULL; 15380 } 15381 15382 if (eap->force_bin == FORCE_BIN) 15383 len = 6; 15384 else if (eap->force_bin == FORCE_NOBIN) 15385 len = 8; 15386 else 15387 len = 0; 15388 if (eap->force_ff != 0) 15389 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 15390 # ifdef FEAT_MBYTE 15391 if (eap->force_enc != 0) 15392 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 15393 # endif 15394 15395 newval = alloc(len + 1); 15396 if (newval == NULL) 15397 return NULL; 15398 15399 if (eap->force_bin == FORCE_BIN) 15400 sprintf((char *)newval, " ++bin"); 15401 else if (eap->force_bin == FORCE_NOBIN) 15402 sprintf((char *)newval, " ++nobin"); 15403 else 15404 *newval = NUL; 15405 if (eap->force_ff != 0) 15406 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 15407 eap->cmd + eap->force_ff); 15408 # ifdef FEAT_MBYTE 15409 if (eap->force_enc != 0) 15410 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 15411 eap->cmd + eap->force_enc); 15412 # endif 15413 vimvars[VV_CMDARG].vv_str = newval; 15414 return oldval; 15415 } 15416 #endif 15417 15418 /* 15419 * Get the value of internal variable "name". 15420 * Return OK or FAIL. 15421 */ 15422 static int 15423 get_var_tv(name, len, rettv, verbose) 15424 char_u *name; 15425 int len; /* length of "name" */ 15426 typval_T *rettv; /* NULL when only checking existence */ 15427 int verbose; /* may give error message */ 15428 { 15429 int ret = OK; 15430 typval_T *tv = NULL; 15431 typval_T atv; 15432 dictitem_T *v; 15433 int cc; 15434 15435 /* truncate the name, so that we can use strcmp() */ 15436 cc = name[len]; 15437 name[len] = NUL; 15438 15439 /* 15440 * Check for "b:changedtick". 15441 */ 15442 if (STRCMP(name, "b:changedtick") == 0) 15443 { 15444 atv.v_type = VAR_NUMBER; 15445 atv.vval.v_number = curbuf->b_changedtick; 15446 tv = &atv; 15447 } 15448 15449 /* 15450 * Check for user-defined variables. 15451 */ 15452 else 15453 { 15454 v = find_var(name, NULL); 15455 if (v != NULL) 15456 tv = &v->di_tv; 15457 } 15458 15459 if (tv == NULL) 15460 { 15461 if (rettv != NULL && verbose) 15462 EMSG2(_(e_undefvar), name); 15463 ret = FAIL; 15464 } 15465 else if (rettv != NULL) 15466 copy_tv(tv, rettv); 15467 15468 name[len] = cc; 15469 15470 return ret; 15471 } 15472 15473 /* 15474 * Handle expr[expr], expr[expr:expr] subscript and .name lookup. 15475 * Also handle function call with Funcref variable: func(expr) 15476 * Can all be combined: dict.func(expr)[idx]['func'](expr) 15477 */ 15478 static int 15479 handle_subscript(arg, rettv, evaluate, verbose) 15480 char_u **arg; 15481 typval_T *rettv; 15482 int evaluate; /* do more than finding the end */ 15483 int verbose; /* give error messages */ 15484 { 15485 int ret = OK; 15486 dict_T *selfdict = NULL; 15487 char_u *s; 15488 int len; 15489 typval_T functv; 15490 15491 while (ret == OK 15492 && (**arg == '[' 15493 || (**arg == '.' && rettv->v_type == VAR_DICT) 15494 || (**arg == '(' && rettv->v_type == VAR_FUNC)) 15495 && !vim_iswhite(*(*arg - 1))) 15496 { 15497 if (**arg == '(') 15498 { 15499 /* need to copy the funcref so that we can clear rettv */ 15500 functv = *rettv; 15501 rettv->v_type = VAR_UNKNOWN; 15502 15503 /* Invoke the function. Recursive! */ 15504 s = functv.vval.v_string; 15505 ret = get_func_tv(s, STRLEN(s), rettv, arg, 15506 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 15507 &len, evaluate, selfdict); 15508 15509 /* Clear the funcref afterwards, so that deleting it while 15510 * evaluating the arguments is possible (see test55). */ 15511 clear_tv(&functv); 15512 15513 /* Stop the expression evaluation when immediately aborting on 15514 * error, or when an interrupt occurred or an exception was thrown 15515 * but not caught. */ 15516 if (aborting()) 15517 { 15518 if (ret == OK) 15519 clear_tv(rettv); 15520 ret = FAIL; 15521 } 15522 dict_unref(selfdict); 15523 selfdict = NULL; 15524 } 15525 else /* **arg == '[' || **arg == '.' */ 15526 { 15527 dict_unref(selfdict); 15528 if (rettv->v_type == VAR_DICT) 15529 { 15530 selfdict = rettv->vval.v_dict; 15531 if (selfdict != NULL) 15532 ++selfdict->dv_refcount; 15533 } 15534 else 15535 selfdict = NULL; 15536 if (eval_index(arg, rettv, evaluate, verbose) == FAIL) 15537 { 15538 clear_tv(rettv); 15539 ret = FAIL; 15540 } 15541 } 15542 } 15543 dict_unref(selfdict); 15544 return ret; 15545 } 15546 15547 /* 15548 * Allocate memory for a variable type-value, and make it emtpy (0 or NULL 15549 * value). 15550 */ 15551 static typval_T * 15552 alloc_tv() 15553 { 15554 return (typval_T *)alloc_clear((unsigned)sizeof(typval_T)); 15555 } 15556 15557 /* 15558 * Allocate memory for a variable type-value, and assign a string to it. 15559 * The string "s" must have been allocated, it is consumed. 15560 * Return NULL for out of memory, the variable otherwise. 15561 */ 15562 static typval_T * 15563 alloc_string_tv(s) 15564 char_u *s; 15565 { 15566 typval_T *rettv; 15567 15568 rettv = alloc_tv(); 15569 if (rettv != NULL) 15570 { 15571 rettv->v_type = VAR_STRING; 15572 rettv->vval.v_string = s; 15573 } 15574 else 15575 vim_free(s); 15576 return rettv; 15577 } 15578 15579 /* 15580 * Free the memory for a variable type-value. 15581 */ 15582 static void 15583 free_tv(varp) 15584 typval_T *varp; 15585 { 15586 if (varp != NULL) 15587 { 15588 switch (varp->v_type) 15589 { 15590 case VAR_FUNC: 15591 func_unref(varp->vval.v_string); 15592 /*FALLTHROUGH*/ 15593 case VAR_STRING: 15594 vim_free(varp->vval.v_string); 15595 break; 15596 case VAR_LIST: 15597 list_unref(varp->vval.v_list); 15598 break; 15599 case VAR_DICT: 15600 dict_unref(varp->vval.v_dict); 15601 break; 15602 case VAR_NUMBER: 15603 case VAR_UNKNOWN: 15604 break; 15605 default: 15606 EMSG2(_(e_intern2), "free_tv()"); 15607 break; 15608 } 15609 vim_free(varp); 15610 } 15611 } 15612 15613 /* 15614 * Free the memory for a variable value and set the value to NULL or 0. 15615 */ 15616 void 15617 clear_tv(varp) 15618 typval_T *varp; 15619 { 15620 if (varp != NULL) 15621 { 15622 switch (varp->v_type) 15623 { 15624 case VAR_FUNC: 15625 func_unref(varp->vval.v_string); 15626 /*FALLTHROUGH*/ 15627 case VAR_STRING: 15628 vim_free(varp->vval.v_string); 15629 varp->vval.v_string = NULL; 15630 break; 15631 case VAR_LIST: 15632 list_unref(varp->vval.v_list); 15633 varp->vval.v_list = NULL; 15634 break; 15635 case VAR_DICT: 15636 dict_unref(varp->vval.v_dict); 15637 varp->vval.v_dict = NULL; 15638 break; 15639 case VAR_NUMBER: 15640 varp->vval.v_number = 0; 15641 break; 15642 case VAR_UNKNOWN: 15643 break; 15644 default: 15645 EMSG2(_(e_intern2), "clear_tv()"); 15646 } 15647 varp->v_lock = 0; 15648 } 15649 } 15650 15651 /* 15652 * Set the value of a variable to NULL without freeing items. 15653 */ 15654 static void 15655 init_tv(varp) 15656 typval_T *varp; 15657 { 15658 if (varp != NULL) 15659 vim_memset(varp, 0, sizeof(typval_T)); 15660 } 15661 15662 /* 15663 * Get the number value of a variable. 15664 * If it is a String variable, uses vim_str2nr(). 15665 * For incompatible types, return 0. 15666 * get_tv_number_chk() is similar to get_tv_number(), but informs the 15667 * caller of incompatible types: it sets *denote to TRUE if "denote" 15668 * is not NULL or returns -1 otherwise. 15669 */ 15670 static long 15671 get_tv_number(varp) 15672 typval_T *varp; 15673 { 15674 int error = FALSE; 15675 15676 return get_tv_number_chk(varp, &error); /* return 0L on error */ 15677 } 15678 15679 long 15680 get_tv_number_chk(varp, denote) 15681 typval_T *varp; 15682 int *denote; 15683 { 15684 long n = 0L; 15685 15686 switch (varp->v_type) 15687 { 15688 case VAR_NUMBER: 15689 return (long)(varp->vval.v_number); 15690 case VAR_FUNC: 15691 EMSG(_("E703: Using a Funcref as a number")); 15692 break; 15693 case VAR_STRING: 15694 if (varp->vval.v_string != NULL) 15695 vim_str2nr(varp->vval.v_string, NULL, NULL, 15696 TRUE, TRUE, &n, NULL); 15697 return n; 15698 case VAR_LIST: 15699 EMSG(_("E745: Using a List as a number")); 15700 break; 15701 case VAR_DICT: 15702 EMSG(_("E728: Using a Dictionary as a number")); 15703 break; 15704 default: 15705 EMSG2(_(e_intern2), "get_tv_number()"); 15706 break; 15707 } 15708 if (denote == NULL) /* useful for values that must be unsigned */ 15709 n = -1; 15710 else 15711 *denote = TRUE; 15712 return n; 15713 } 15714 15715 /* 15716 * Get the lnum from the first argument. 15717 * Also accepts ".", "$", etc., but that only works for the current buffer. 15718 * Returns -1 on error. 15719 */ 15720 static linenr_T 15721 get_tv_lnum(argvars) 15722 typval_T *argvars; 15723 { 15724 typval_T rettv; 15725 linenr_T lnum; 15726 15727 lnum = get_tv_number_chk(&argvars[0], NULL); 15728 if (lnum == 0) /* no valid number, try using line() */ 15729 { 15730 rettv.v_type = VAR_NUMBER; 15731 f_line(argvars, &rettv); 15732 lnum = rettv.vval.v_number; 15733 clear_tv(&rettv); 15734 } 15735 return lnum; 15736 } 15737 15738 /* 15739 * Get the lnum from the first argument. 15740 * Also accepts "$", then "buf" is used. 15741 * Returns 0 on error. 15742 */ 15743 static linenr_T 15744 get_tv_lnum_buf(argvars, buf) 15745 typval_T *argvars; 15746 buf_T *buf; 15747 { 15748 if (argvars[0].v_type == VAR_STRING 15749 && argvars[0].vval.v_string != NULL 15750 && argvars[0].vval.v_string[0] == '$' 15751 && buf != NULL) 15752 return buf->b_ml.ml_line_count; 15753 return get_tv_number_chk(&argvars[0], NULL); 15754 } 15755 15756 /* 15757 * Get the string value of a variable. 15758 * If it is a Number variable, the number is converted into a string. 15759 * get_tv_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 15760 * get_tv_string_buf() uses a given buffer. 15761 * If the String variable has never been set, return an empty string. 15762 * Never returns NULL; 15763 * get_tv_string_chk() and get_tv_string_buf_chk() are similar, but return 15764 * NULL on error. 15765 */ 15766 static char_u * 15767 get_tv_string(varp) 15768 typval_T *varp; 15769 { 15770 static char_u mybuf[NUMBUFLEN]; 15771 15772 return get_tv_string_buf(varp, mybuf); 15773 } 15774 15775 static char_u * 15776 get_tv_string_buf(varp, buf) 15777 typval_T *varp; 15778 char_u *buf; 15779 { 15780 char_u *res = get_tv_string_buf_chk(varp, buf); 15781 15782 return res != NULL ? res : (char_u *)""; 15783 } 15784 15785 char_u * 15786 get_tv_string_chk(varp) 15787 typval_T *varp; 15788 { 15789 static char_u mybuf[NUMBUFLEN]; 15790 15791 return get_tv_string_buf_chk(varp, mybuf); 15792 } 15793 15794 static char_u * 15795 get_tv_string_buf_chk(varp, buf) 15796 typval_T *varp; 15797 char_u *buf; 15798 { 15799 switch (varp->v_type) 15800 { 15801 case VAR_NUMBER: 15802 sprintf((char *)buf, "%ld", (long)varp->vval.v_number); 15803 return buf; 15804 case VAR_FUNC: 15805 EMSG(_("E729: using Funcref as a String")); 15806 break; 15807 case VAR_LIST: 15808 EMSG(_("E730: using List as a String")); 15809 break; 15810 case VAR_DICT: 15811 EMSG(_("E731: using Dictionary as a String")); 15812 break; 15813 case VAR_STRING: 15814 if (varp->vval.v_string != NULL) 15815 return varp->vval.v_string; 15816 return (char_u *)""; 15817 default: 15818 EMSG2(_(e_intern2), "get_tv_string_buf()"); 15819 break; 15820 } 15821 return NULL; 15822 } 15823 15824 /* 15825 * Find variable "name" in the list of variables. 15826 * Return a pointer to it if found, NULL if not found. 15827 * Careful: "a:0" variables don't have a name. 15828 * When "htp" is not NULL we are writing to the variable, set "htp" to the 15829 * hashtab_T used. 15830 */ 15831 static dictitem_T * 15832 find_var(name, htp) 15833 char_u *name; 15834 hashtab_T **htp; 15835 { 15836 char_u *varname; 15837 hashtab_T *ht; 15838 15839 ht = find_var_ht(name, &varname); 15840 if (htp != NULL) 15841 *htp = ht; 15842 if (ht == NULL) 15843 return NULL; 15844 return find_var_in_ht(ht, varname, htp != NULL); 15845 } 15846 15847 /* 15848 * Find variable "varname" in hashtab "ht". 15849 * Returns NULL if not found. 15850 */ 15851 static dictitem_T * 15852 find_var_in_ht(ht, varname, writing) 15853 hashtab_T *ht; 15854 char_u *varname; 15855 int writing; 15856 { 15857 hashitem_T *hi; 15858 15859 if (*varname == NUL) 15860 { 15861 /* Must be something like "s:", otherwise "ht" would be NULL. */ 15862 switch (varname[-2]) 15863 { 15864 case 's': return &SCRIPT_SV(current_SID).sv_var; 15865 case 'g': return &globvars_var; 15866 case 'v': return &vimvars_var; 15867 case 'b': return &curbuf->b_bufvar; 15868 case 'w': return &curwin->w_winvar; 15869 case 'l': return current_funccal == NULL 15870 ? NULL : ¤t_funccal->l_vars_var; 15871 case 'a': return current_funccal == NULL 15872 ? NULL : ¤t_funccal->l_avars_var; 15873 } 15874 return NULL; 15875 } 15876 15877 hi = hash_find(ht, varname); 15878 if (HASHITEM_EMPTY(hi)) 15879 { 15880 /* For global variables we may try auto-loading the script. If it 15881 * worked find the variable again. Don't auto-load a script if it was 15882 * loaded already, otherwise it would be loaded every time when 15883 * checking if a function name is a Funcref variable. */ 15884 if (ht == &globvarht && !writing 15885 && script_autoload(varname, FALSE) && !aborting()) 15886 hi = hash_find(ht, varname); 15887 if (HASHITEM_EMPTY(hi)) 15888 return NULL; 15889 } 15890 return HI2DI(hi); 15891 } 15892 15893 /* 15894 * Find the hashtab used for a variable name. 15895 * Set "varname" to the start of name without ':'. 15896 */ 15897 static hashtab_T * 15898 find_var_ht(name, varname) 15899 char_u *name; 15900 char_u **varname; 15901 { 15902 hashitem_T *hi; 15903 15904 if (name[1] != ':') 15905 { 15906 /* The name must not start with a colon or #. */ 15907 if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) 15908 return NULL; 15909 *varname = name; 15910 15911 /* "version" is "v:version" in all scopes */ 15912 hi = hash_find(&compat_hashtab, name); 15913 if (!HASHITEM_EMPTY(hi)) 15914 return &compat_hashtab; 15915 15916 if (current_funccal == NULL) 15917 return &globvarht; /* global variable */ 15918 return ¤t_funccal->l_vars.dv_hashtab; /* l: variable */ 15919 } 15920 *varname = name + 2; 15921 if (*name == 'g') /* global variable */ 15922 return &globvarht; 15923 /* There must be no ':' or '#' in the rest of the name, unless g: is used 15924 */ 15925 if (vim_strchr(name + 2, ':') != NULL 15926 || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) 15927 return NULL; 15928 if (*name == 'b') /* buffer variable */ 15929 return &curbuf->b_vars.dv_hashtab; 15930 if (*name == 'w') /* window variable */ 15931 return &curwin->w_vars.dv_hashtab; 15932 if (*name == 'v') /* v: variable */ 15933 return &vimvarht; 15934 if (*name == 'a' && current_funccal != NULL) /* function argument */ 15935 return ¤t_funccal->l_avars.dv_hashtab; 15936 if (*name == 'l' && current_funccal != NULL) /* local function variable */ 15937 return ¤t_funccal->l_vars.dv_hashtab; 15938 if (*name == 's' /* script variable */ 15939 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 15940 return &SCRIPT_VARS(current_SID); 15941 return NULL; 15942 } 15943 15944 /* 15945 * Get the string value of a (global/local) variable. 15946 * Returns NULL when it doesn't exist. 15947 */ 15948 char_u * 15949 get_var_value(name) 15950 char_u *name; 15951 { 15952 dictitem_T *v; 15953 15954 v = find_var(name, NULL); 15955 if (v == NULL) 15956 return NULL; 15957 return get_tv_string(&v->di_tv); 15958 } 15959 15960 /* 15961 * Allocate a new hashtab for a sourced script. It will be used while 15962 * sourcing this script and when executing functions defined in the script. 15963 */ 15964 void 15965 new_script_vars(id) 15966 scid_T id; 15967 { 15968 int i; 15969 hashtab_T *ht; 15970 scriptvar_T *sv; 15971 15972 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 15973 { 15974 /* Re-allocating ga_data means that an ht_array pointing to 15975 * ht_smallarray becomes invalid. We can recognize this: ht_mask is 15976 * at its init value. Also reset "v_dict", it's always the same. */ 15977 for (i = 1; i <= ga_scripts.ga_len; ++i) 15978 { 15979 ht = &SCRIPT_VARS(i); 15980 if (ht->ht_mask == HT_INIT_SIZE - 1) 15981 ht->ht_array = ht->ht_smallarray; 15982 sv = &SCRIPT_SV(i); 15983 sv->sv_var.di_tv.vval.v_dict = &sv->sv_dict; 15984 } 15985 15986 while (ga_scripts.ga_len < id) 15987 { 15988 sv = &SCRIPT_SV(ga_scripts.ga_len + 1); 15989 init_var_dict(&sv->sv_dict, &sv->sv_var); 15990 ++ga_scripts.ga_len; 15991 } 15992 } 15993 } 15994 15995 /* 15996 * Initialize dictionary "dict" as a scope and set variable "dict_var" to 15997 * point to it. 15998 */ 15999 void 16000 init_var_dict(dict, dict_var) 16001 dict_T *dict; 16002 dictitem_T *dict_var; 16003 { 16004 hash_init(&dict->dv_hashtab); 16005 dict->dv_refcount = 99999; 16006 dict_var->di_tv.vval.v_dict = dict; 16007 dict_var->di_tv.v_type = VAR_DICT; 16008 dict_var->di_tv.v_lock = VAR_FIXED; 16009 dict_var->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 16010 dict_var->di_key[0] = NUL; 16011 } 16012 16013 /* 16014 * Clean up a list of internal variables. 16015 * Frees all allocated variables and the value they contain. 16016 * Clears hashtab "ht", does not free it. 16017 */ 16018 void 16019 vars_clear(ht) 16020 hashtab_T *ht; 16021 { 16022 vars_clear_ext(ht, TRUE); 16023 } 16024 16025 /* 16026 * Like vars_clear(), but only free the value if "free_val" is TRUE. 16027 */ 16028 static void 16029 vars_clear_ext(ht, free_val) 16030 hashtab_T *ht; 16031 int free_val; 16032 { 16033 int todo; 16034 hashitem_T *hi; 16035 dictitem_T *v; 16036 16037 hash_lock(ht); 16038 todo = ht->ht_used; 16039 for (hi = ht->ht_array; todo > 0; ++hi) 16040 { 16041 if (!HASHITEM_EMPTY(hi)) 16042 { 16043 --todo; 16044 16045 /* Free the variable. Don't remove it from the hashtab, 16046 * ht_array might change then. hash_clear() takes care of it 16047 * later. */ 16048 v = HI2DI(hi); 16049 if (free_val) 16050 clear_tv(&v->di_tv); 16051 if ((v->di_flags & DI_FLAGS_FIX) == 0) 16052 vim_free(v); 16053 } 16054 } 16055 hash_clear(ht); 16056 ht->ht_used = 0; 16057 } 16058 16059 /* 16060 * Delete a variable from hashtab "ht" at item "hi". 16061 * Clear the variable value and free the dictitem. 16062 */ 16063 static void 16064 delete_var(ht, hi) 16065 hashtab_T *ht; 16066 hashitem_T *hi; 16067 { 16068 dictitem_T *di = HI2DI(hi); 16069 16070 hash_remove(ht, hi); 16071 clear_tv(&di->di_tv); 16072 vim_free(di); 16073 } 16074 16075 /* 16076 * List the value of one internal variable. 16077 */ 16078 static void 16079 list_one_var(v, prefix) 16080 dictitem_T *v; 16081 char_u *prefix; 16082 { 16083 char_u *tofree; 16084 char_u *s; 16085 char_u numbuf[NUMBUFLEN]; 16086 16087 s = echo_string(&v->di_tv, &tofree, numbuf); 16088 list_one_var_a(prefix, v->di_key, v->di_tv.v_type, 16089 s == NULL ? (char_u *)"" : s); 16090 vim_free(tofree); 16091 } 16092 16093 static void 16094 list_one_var_a(prefix, name, type, string) 16095 char_u *prefix; 16096 char_u *name; 16097 int type; 16098 char_u *string; 16099 { 16100 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 16101 if (name != NULL) /* "a:" vars don't have a name stored */ 16102 msg_puts(name); 16103 msg_putchar(' '); 16104 msg_advance(22); 16105 if (type == VAR_NUMBER) 16106 msg_putchar('#'); 16107 else if (type == VAR_FUNC) 16108 msg_putchar('*'); 16109 else if (type == VAR_LIST) 16110 { 16111 msg_putchar('['); 16112 if (*string == '[') 16113 ++string; 16114 } 16115 else if (type == VAR_DICT) 16116 { 16117 msg_putchar('{'); 16118 if (*string == '{') 16119 ++string; 16120 } 16121 else 16122 msg_putchar(' '); 16123 16124 msg_outtrans(string); 16125 16126 if (type == VAR_FUNC) 16127 msg_puts((char_u *)"()"); 16128 } 16129 16130 /* 16131 * Set variable "name" to value in "tv". 16132 * If the variable already exists, the value is updated. 16133 * Otherwise the variable is created. 16134 */ 16135 static void 16136 set_var(name, tv, copy) 16137 char_u *name; 16138 typval_T *tv; 16139 int copy; /* make copy of value in "tv" */ 16140 { 16141 dictitem_T *v; 16142 char_u *varname; 16143 hashtab_T *ht; 16144 char_u *p; 16145 16146 if (tv->v_type == VAR_FUNC) 16147 { 16148 if (!(vim_strchr((char_u *)"wbs", name[0]) != NULL && name[1] == ':') 16149 && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') 16150 ? name[2] : name[0])) 16151 { 16152 EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); 16153 return; 16154 } 16155 if (function_exists(name)) 16156 { 16157 EMSG2(_("E705: Variable name conflicts with existing function: %s"), 16158 name); 16159 return; 16160 } 16161 } 16162 16163 ht = find_var_ht(name, &varname); 16164 if (ht == NULL || *varname == NUL) 16165 { 16166 EMSG2(_(e_illvar), name); 16167 return; 16168 } 16169 16170 v = find_var_in_ht(ht, varname, TRUE); 16171 if (v != NULL) 16172 { 16173 /* existing variable, need to clear the value */ 16174 if (var_check_ro(v->di_flags, name) 16175 || tv_check_lock(v->di_tv.v_lock, name)) 16176 return; 16177 if (v->di_tv.v_type != tv->v_type 16178 && !((v->di_tv.v_type == VAR_STRING 16179 || v->di_tv.v_type == VAR_NUMBER) 16180 && (tv->v_type == VAR_STRING 16181 || tv->v_type == VAR_NUMBER))) 16182 { 16183 EMSG2(_("E706: Variable type mismatch for: %s"), name); 16184 return; 16185 } 16186 16187 /* 16188 * Handle setting internal v: variables separately: we don't change 16189 * the type. 16190 */ 16191 if (ht == &vimvarht) 16192 { 16193 if (v->di_tv.v_type == VAR_STRING) 16194 { 16195 vim_free(v->di_tv.vval.v_string); 16196 if (copy || tv->v_type != VAR_STRING) 16197 v->di_tv.vval.v_string = vim_strsave(get_tv_string(tv)); 16198 else 16199 { 16200 /* Take over the string to avoid an extra alloc/free. */ 16201 v->di_tv.vval.v_string = tv->vval.v_string; 16202 tv->vval.v_string = NULL; 16203 } 16204 } 16205 else if (v->di_tv.v_type != VAR_NUMBER) 16206 EMSG2(_(e_intern2), "set_var()"); 16207 else 16208 v->di_tv.vval.v_number = get_tv_number(tv); 16209 return; 16210 } 16211 16212 clear_tv(&v->di_tv); 16213 } 16214 else /* add a new variable */ 16215 { 16216 /* Make sure the variable name is valid. */ 16217 for (p = varname; *p != NUL; ++p) 16218 if (!eval_isnamec1(*p) && (p == varname || !VIM_ISDIGIT(*p))) 16219 { 16220 EMSG2(_(e_illvar), varname); 16221 return; 16222 } 16223 16224 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 16225 + STRLEN(varname))); 16226 if (v == NULL) 16227 return; 16228 STRCPY(v->di_key, varname); 16229 if (hash_add(ht, DI2HIKEY(v)) == FAIL) 16230 { 16231 vim_free(v); 16232 return; 16233 } 16234 v->di_flags = 0; 16235 } 16236 16237 if (copy || tv->v_type == VAR_NUMBER) 16238 copy_tv(tv, &v->di_tv); 16239 else 16240 { 16241 v->di_tv = *tv; 16242 v->di_tv.v_lock = 0; 16243 init_tv(tv); 16244 } 16245 } 16246 16247 /* 16248 * Return TRUE if di_flags "flags" indicate read-only variable "name". 16249 * Also give an error message. 16250 */ 16251 static int 16252 var_check_ro(flags, name) 16253 int flags; 16254 char_u *name; 16255 { 16256 if (flags & DI_FLAGS_RO) 16257 { 16258 EMSG2(_(e_readonlyvar), name); 16259 return TRUE; 16260 } 16261 if ((flags & DI_FLAGS_RO_SBX) && sandbox) 16262 { 16263 EMSG2(_(e_readonlysbx), name); 16264 return TRUE; 16265 } 16266 return FALSE; 16267 } 16268 16269 /* 16270 * Return TRUE if typeval "tv" is set to be locked (immutable). 16271 * Also give an error message, using "name". 16272 */ 16273 static int 16274 tv_check_lock(lock, name) 16275 int lock; 16276 char_u *name; 16277 { 16278 if (lock & VAR_LOCKED) 16279 { 16280 EMSG2(_("E741: Value is locked: %s"), 16281 name == NULL ? (char_u *)_("Unknown") : name); 16282 return TRUE; 16283 } 16284 if (lock & VAR_FIXED) 16285 { 16286 EMSG2(_("E742: Cannot change value of %s"), 16287 name == NULL ? (char_u *)_("Unknown") : name); 16288 return TRUE; 16289 } 16290 return FALSE; 16291 } 16292 16293 /* 16294 * Copy the values from typval_T "from" to typval_T "to". 16295 * When needed allocates string or increases reference count. 16296 * Does not make a copy of a list or dict but copies the reference! 16297 */ 16298 static void 16299 copy_tv(from, to) 16300 typval_T *from; 16301 typval_T *to; 16302 { 16303 to->v_type = from->v_type; 16304 to->v_lock = 0; 16305 switch (from->v_type) 16306 { 16307 case VAR_NUMBER: 16308 to->vval.v_number = from->vval.v_number; 16309 break; 16310 case VAR_STRING: 16311 case VAR_FUNC: 16312 if (from->vval.v_string == NULL) 16313 to->vval.v_string = NULL; 16314 else 16315 { 16316 to->vval.v_string = vim_strsave(from->vval.v_string); 16317 if (from->v_type == VAR_FUNC) 16318 func_ref(to->vval.v_string); 16319 } 16320 break; 16321 case VAR_LIST: 16322 if (from->vval.v_list == NULL) 16323 to->vval.v_list = NULL; 16324 else 16325 { 16326 to->vval.v_list = from->vval.v_list; 16327 ++to->vval.v_list->lv_refcount; 16328 } 16329 break; 16330 case VAR_DICT: 16331 if (from->vval.v_dict == NULL) 16332 to->vval.v_dict = NULL; 16333 else 16334 { 16335 to->vval.v_dict = from->vval.v_dict; 16336 ++to->vval.v_dict->dv_refcount; 16337 } 16338 break; 16339 default: 16340 EMSG2(_(e_intern2), "copy_tv()"); 16341 break; 16342 } 16343 } 16344 16345 /* 16346 * Make a copy of an item. 16347 * Lists and Dictionaries are also copied. A deep copy if "deep" is set. 16348 * For deepcopy() "copyID" is zero for a full copy or the ID for when a 16349 * reference to an already copied list/dict can be used. 16350 * Returns FAIL or OK. 16351 */ 16352 static int 16353 item_copy(from, to, deep, copyID) 16354 typval_T *from; 16355 typval_T *to; 16356 int deep; 16357 int copyID; 16358 { 16359 static int recurse = 0; 16360 int ret = OK; 16361 16362 if (recurse >= DICT_MAXNEST) 16363 { 16364 EMSG(_("E698: variable nested too deep for making a copy")); 16365 return FAIL; 16366 } 16367 ++recurse; 16368 16369 switch (from->v_type) 16370 { 16371 case VAR_NUMBER: 16372 case VAR_STRING: 16373 case VAR_FUNC: 16374 copy_tv(from, to); 16375 break; 16376 case VAR_LIST: 16377 to->v_type = VAR_LIST; 16378 to->v_lock = 0; 16379 if (from->vval.v_list == NULL) 16380 to->vval.v_list = NULL; 16381 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) 16382 { 16383 /* use the copy made earlier */ 16384 to->vval.v_list = from->vval.v_list->lv_copylist; 16385 ++to->vval.v_list->lv_refcount; 16386 } 16387 else 16388 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); 16389 if (to->vval.v_list == NULL) 16390 ret = FAIL; 16391 break; 16392 case VAR_DICT: 16393 to->v_type = VAR_DICT; 16394 to->v_lock = 0; 16395 if (from->vval.v_dict == NULL) 16396 to->vval.v_dict = NULL; 16397 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) 16398 { 16399 /* use the copy made earlier */ 16400 to->vval.v_dict = from->vval.v_dict->dv_copydict; 16401 ++to->vval.v_dict->dv_refcount; 16402 } 16403 else 16404 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); 16405 if (to->vval.v_dict == NULL) 16406 ret = FAIL; 16407 break; 16408 default: 16409 EMSG2(_(e_intern2), "item_copy()"); 16410 ret = FAIL; 16411 } 16412 --recurse; 16413 return ret; 16414 } 16415 16416 /* 16417 * ":echo expr1 ..." print each argument separated with a space, add a 16418 * newline at the end. 16419 * ":echon expr1 ..." print each argument plain. 16420 */ 16421 void 16422 ex_echo(eap) 16423 exarg_T *eap; 16424 { 16425 char_u *arg = eap->arg; 16426 typval_T rettv; 16427 char_u *tofree; 16428 char_u *p; 16429 int needclr = TRUE; 16430 int atstart = TRUE; 16431 char_u numbuf[NUMBUFLEN]; 16432 16433 if (eap->skip) 16434 ++emsg_skip; 16435 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 16436 { 16437 p = arg; 16438 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16439 { 16440 /* 16441 * Report the invalid expression unless the expression evaluation 16442 * has been cancelled due to an aborting error, an interrupt, or an 16443 * exception. 16444 */ 16445 if (!aborting()) 16446 EMSG2(_(e_invexpr2), p); 16447 break; 16448 } 16449 if (!eap->skip) 16450 { 16451 if (atstart) 16452 { 16453 atstart = FALSE; 16454 /* Call msg_start() after eval1(), evaluating the expression 16455 * may cause a message to appear. */ 16456 if (eap->cmdidx == CMD_echo) 16457 msg_start(); 16458 } 16459 else if (eap->cmdidx == CMD_echo) 16460 msg_puts_attr((char_u *)" ", echo_attr); 16461 p = echo_string(&rettv, &tofree, numbuf); 16462 if (p != NULL) 16463 for ( ; *p != NUL && !got_int; ++p) 16464 { 16465 if (*p == '\n' || *p == '\r' || *p == TAB) 16466 { 16467 if (*p != TAB && needclr) 16468 { 16469 /* remove any text still there from the command */ 16470 msg_clr_eos(); 16471 needclr = FALSE; 16472 } 16473 msg_putchar_attr(*p, echo_attr); 16474 } 16475 else 16476 { 16477 #ifdef FEAT_MBYTE 16478 if (has_mbyte) 16479 { 16480 int i = (*mb_ptr2len_check)(p); 16481 16482 (void)msg_outtrans_len_attr(p, i, echo_attr); 16483 p += i - 1; 16484 } 16485 else 16486 #endif 16487 (void)msg_outtrans_len_attr(p, 1, echo_attr); 16488 } 16489 } 16490 vim_free(tofree); 16491 } 16492 clear_tv(&rettv); 16493 arg = skipwhite(arg); 16494 } 16495 eap->nextcmd = check_nextcmd(arg); 16496 16497 if (eap->skip) 16498 --emsg_skip; 16499 else 16500 { 16501 /* remove text that may still be there from the command */ 16502 if (needclr) 16503 msg_clr_eos(); 16504 if (eap->cmdidx == CMD_echo) 16505 msg_end(); 16506 } 16507 } 16508 16509 /* 16510 * ":echohl {name}". 16511 */ 16512 void 16513 ex_echohl(eap) 16514 exarg_T *eap; 16515 { 16516 int id; 16517 16518 id = syn_name2id(eap->arg); 16519 if (id == 0) 16520 echo_attr = 0; 16521 else 16522 echo_attr = syn_id2attr(id); 16523 } 16524 16525 /* 16526 * ":execute expr1 ..." execute the result of an expression. 16527 * ":echomsg expr1 ..." Print a message 16528 * ":echoerr expr1 ..." Print an error 16529 * Each gets spaces around each argument and a newline at the end for 16530 * echo commands 16531 */ 16532 void 16533 ex_execute(eap) 16534 exarg_T *eap; 16535 { 16536 char_u *arg = eap->arg; 16537 typval_T rettv; 16538 int ret = OK; 16539 char_u *p; 16540 garray_T ga; 16541 int len; 16542 int save_did_emsg; 16543 16544 ga_init2(&ga, 1, 80); 16545 16546 if (eap->skip) 16547 ++emsg_skip; 16548 while (*arg != NUL && *arg != '|' && *arg != '\n') 16549 { 16550 p = arg; 16551 if (eval1(&arg, &rettv, !eap->skip) == FAIL) 16552 { 16553 /* 16554 * Report the invalid expression unless the expression evaluation 16555 * has been cancelled due to an aborting error, an interrupt, or an 16556 * exception. 16557 */ 16558 if (!aborting()) 16559 EMSG2(_(e_invexpr2), p); 16560 ret = FAIL; 16561 break; 16562 } 16563 16564 if (!eap->skip) 16565 { 16566 p = get_tv_string(&rettv); 16567 len = (int)STRLEN(p); 16568 if (ga_grow(&ga, len + 2) == FAIL) 16569 { 16570 clear_tv(&rettv); 16571 ret = FAIL; 16572 break; 16573 } 16574 if (ga.ga_len) 16575 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 16576 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 16577 ga.ga_len += len; 16578 } 16579 16580 clear_tv(&rettv); 16581 arg = skipwhite(arg); 16582 } 16583 16584 if (ret != FAIL && ga.ga_data != NULL) 16585 { 16586 if (eap->cmdidx == CMD_echomsg) 16587 MSG_ATTR(ga.ga_data, echo_attr); 16588 else if (eap->cmdidx == CMD_echoerr) 16589 { 16590 /* We don't want to abort following commands, restore did_emsg. */ 16591 save_did_emsg = did_emsg; 16592 EMSG((char_u *)ga.ga_data); 16593 if (!force_abort) 16594 did_emsg = save_did_emsg; 16595 } 16596 else if (eap->cmdidx == CMD_execute) 16597 do_cmdline((char_u *)ga.ga_data, 16598 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 16599 } 16600 16601 ga_clear(&ga); 16602 16603 if (eap->skip) 16604 --emsg_skip; 16605 16606 eap->nextcmd = check_nextcmd(arg); 16607 } 16608 16609 /* 16610 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 16611 * "arg" points to the "&" or '+' when called, to "option" when returning. 16612 * Returns NULL when no option name found. Otherwise pointer to the char 16613 * after the option name. 16614 */ 16615 static char_u * 16616 find_option_end(arg, opt_flags) 16617 char_u **arg; 16618 int *opt_flags; 16619 { 16620 char_u *p = *arg; 16621 16622 ++p; 16623 if (*p == 'g' && p[1] == ':') 16624 { 16625 *opt_flags = OPT_GLOBAL; 16626 p += 2; 16627 } 16628 else if (*p == 'l' && p[1] == ':') 16629 { 16630 *opt_flags = OPT_LOCAL; 16631 p += 2; 16632 } 16633 else 16634 *opt_flags = 0; 16635 16636 if (!ASCII_ISALPHA(*p)) 16637 return NULL; 16638 *arg = p; 16639 16640 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 16641 p += 4; /* termcap option */ 16642 else 16643 while (ASCII_ISALPHA(*p)) 16644 ++p; 16645 return p; 16646 } 16647 16648 /* 16649 * ":function" 16650 */ 16651 void 16652 ex_function(eap) 16653 exarg_T *eap; 16654 { 16655 char_u *theline; 16656 int j; 16657 int c; 16658 int saved_did_emsg; 16659 char_u *name = NULL; 16660 char_u *p; 16661 char_u *arg; 16662 garray_T newargs; 16663 garray_T newlines; 16664 int varargs = FALSE; 16665 int mustend = FALSE; 16666 int flags = 0; 16667 ufunc_T *fp; 16668 int indent; 16669 int nesting; 16670 char_u *skip_until = NULL; 16671 dictitem_T *v; 16672 funcdict_T fudi; 16673 static int func_nr = 0; /* number for nameless function */ 16674 int paren; 16675 hashtab_T *ht; 16676 int todo; 16677 hashitem_T *hi; 16678 16679 /* 16680 * ":function" without argument: list functions. 16681 */ 16682 if (ends_excmd(*eap->arg)) 16683 { 16684 if (!eap->skip) 16685 { 16686 todo = func_hashtab.ht_used; 16687 for (hi = func_hashtab.ht_array; todo > 0 && !got_int; ++hi) 16688 { 16689 if (!HASHITEM_EMPTY(hi)) 16690 { 16691 --todo; 16692 fp = HI2UF(hi); 16693 if (!isdigit(*fp->uf_name)) 16694 list_func_head(fp, FALSE); 16695 } 16696 } 16697 } 16698 eap->nextcmd = check_nextcmd(eap->arg); 16699 return; 16700 } 16701 16702 /* 16703 * Get the function name. There are these situations: 16704 * func normal function name 16705 * "name" == func, "fudi.fd_dict" == NULL 16706 * dict.func new dictionary entry 16707 * "name" == NULL, "fudi.fd_dict" set, 16708 * "fudi.fd_di" == NULL, "fudi.fd_newkey" == func 16709 * dict.func existing dict entry with a Funcref 16710 * "name" == func, "fudi.fd_dict" set, 16711 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16712 * dict.func existing dict entry that's not a Funcref 16713 * "name" == NULL, "fudi.fd_dict" set, 16714 * "fudi.fd_di" set, "fudi.fd_newkey" == NULL 16715 */ 16716 p = eap->arg; 16717 name = trans_function_name(&p, eap->skip, 0, &fudi); 16718 paren = (vim_strchr(p, '(') != NULL); 16719 if (name == NULL && (fudi.fd_dict == NULL || !paren) && !eap->skip) 16720 { 16721 /* 16722 * Return on an invalid expression in braces, unless the expression 16723 * evaluation has been cancelled due to an aborting error, an 16724 * interrupt, or an exception. 16725 */ 16726 if (!aborting()) 16727 { 16728 if (!eap->skip && fudi.fd_newkey != NULL) 16729 EMSG2(_(e_dictkey), fudi.fd_newkey); 16730 vim_free(fudi.fd_newkey); 16731 return; 16732 } 16733 else 16734 eap->skip = TRUE; 16735 } 16736 /* An error in a function call during evaluation of an expression in magic 16737 * braces should not cause the function not to be defined. */ 16738 saved_did_emsg = did_emsg; 16739 did_emsg = FALSE; 16740 16741 /* 16742 * ":function func" with only function name: list function. 16743 */ 16744 if (!paren) 16745 { 16746 if (!ends_excmd(*skipwhite(p))) 16747 { 16748 EMSG(_(e_trailing)); 16749 goto ret_free; 16750 } 16751 eap->nextcmd = check_nextcmd(p); 16752 if (eap->nextcmd != NULL) 16753 *p = NUL; 16754 if (!eap->skip && !got_int) 16755 { 16756 fp = find_func(name); 16757 if (fp != NULL) 16758 { 16759 list_func_head(fp, TRUE); 16760 for (j = 0; j < fp->uf_lines.ga_len && !got_int; ++j) 16761 { 16762 msg_putchar('\n'); 16763 msg_outnum((long)(j + 1)); 16764 if (j < 9) 16765 msg_putchar(' '); 16766 if (j < 99) 16767 msg_putchar(' '); 16768 msg_prt_line(FUNCLINE(fp, j), FALSE); 16769 out_flush(); /* show a line at a time */ 16770 ui_breakcheck(); 16771 } 16772 if (!got_int) 16773 { 16774 msg_putchar('\n'); 16775 msg_puts((char_u *)" endfunction"); 16776 } 16777 } 16778 else 16779 emsg_funcname("E123: Undefined function: %s", name); 16780 } 16781 goto ret_free; 16782 } 16783 16784 /* 16785 * ":function name(arg1, arg2)" Define function. 16786 */ 16787 p = skipwhite(p); 16788 if (*p != '(') 16789 { 16790 if (!eap->skip) 16791 { 16792 EMSG2(_("E124: Missing '(': %s"), eap->arg); 16793 goto ret_free; 16794 } 16795 /* attempt to continue by skipping some text */ 16796 if (vim_strchr(p, '(') != NULL) 16797 p = vim_strchr(p, '('); 16798 } 16799 p = skipwhite(p + 1); 16800 16801 ga_init2(&newargs, (int)sizeof(char_u *), 3); 16802 ga_init2(&newlines, (int)sizeof(char_u *), 3); 16803 16804 if (!eap->skip) 16805 { 16806 /* Check the name of the function. */ 16807 if (name != NULL) 16808 arg = name; 16809 else 16810 arg = fudi.fd_newkey; 16811 if (arg != NULL) 16812 { 16813 if (*arg == K_SPECIAL) 16814 j = 3; 16815 else 16816 j = 0; 16817 while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j]) 16818 : eval_isnamec(arg[j]))) 16819 ++j; 16820 if (arg[j] != NUL) 16821 emsg_funcname(_(e_invarg2), arg); 16822 } 16823 } 16824 16825 /* 16826 * Isolate the arguments: "arg1, arg2, ...)" 16827 */ 16828 while (*p != ')') 16829 { 16830 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 16831 { 16832 varargs = TRUE; 16833 p += 3; 16834 mustend = TRUE; 16835 } 16836 else 16837 { 16838 arg = p; 16839 while (ASCII_ISALNUM(*p) || *p == '_') 16840 ++p; 16841 if (arg == p || isdigit(*arg) 16842 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 16843 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 16844 { 16845 if (!eap->skip) 16846 EMSG2(_("E125: Illegal argument: %s"), arg); 16847 break; 16848 } 16849 if (ga_grow(&newargs, 1) == FAIL) 16850 goto erret; 16851 c = *p; 16852 *p = NUL; 16853 arg = vim_strsave(arg); 16854 if (arg == NULL) 16855 goto erret; 16856 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 16857 *p = c; 16858 newargs.ga_len++; 16859 if (*p == ',') 16860 ++p; 16861 else 16862 mustend = TRUE; 16863 } 16864 p = skipwhite(p); 16865 if (mustend && *p != ')') 16866 { 16867 if (!eap->skip) 16868 EMSG2(_(e_invarg2), eap->arg); 16869 break; 16870 } 16871 } 16872 ++p; /* skip the ')' */ 16873 16874 /* find extra arguments "range", "dict" and "abort" */ 16875 for (;;) 16876 { 16877 p = skipwhite(p); 16878 if (STRNCMP(p, "range", 5) == 0) 16879 { 16880 flags |= FC_RANGE; 16881 p += 5; 16882 } 16883 else if (STRNCMP(p, "dict", 4) == 0) 16884 { 16885 flags |= FC_DICT; 16886 p += 4; 16887 } 16888 else if (STRNCMP(p, "abort", 5) == 0) 16889 { 16890 flags |= FC_ABORT; 16891 p += 5; 16892 } 16893 else 16894 break; 16895 } 16896 16897 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 16898 EMSG(_(e_trailing)); 16899 16900 /* 16901 * Read the body of the function, until ":endfunction" is found. 16902 */ 16903 if (KeyTyped) 16904 { 16905 /* Check if the function already exists, don't let the user type the 16906 * whole function before telling him it doesn't work! For a script we 16907 * need to skip the body to be able to find what follows. */ 16908 if (!eap->skip && !eap->forceit) 16909 { 16910 if (fudi.fd_dict != NULL && fudi.fd_newkey == NULL) 16911 EMSG(_(e_funcdict)); 16912 else if (name != NULL && find_func(name) != NULL) 16913 emsg_funcname(e_funcexts, name); 16914 } 16915 16916 if (!eap->skip && did_emsg) 16917 goto erret; 16918 16919 msg_putchar('\n'); /* don't overwrite the function name */ 16920 cmdline_row = msg_row; 16921 } 16922 16923 indent = 2; 16924 nesting = 0; 16925 for (;;) 16926 { 16927 msg_scroll = TRUE; 16928 need_wait_return = FALSE; 16929 if (eap->getline == NULL) 16930 theline = getcmdline(':', 0L, indent); 16931 else 16932 theline = eap->getline(':', eap->cookie, indent); 16933 if (KeyTyped) 16934 lines_left = Rows - 1; 16935 if (theline == NULL) 16936 { 16937 EMSG(_("E126: Missing :endfunction")); 16938 goto erret; 16939 } 16940 16941 if (skip_until != NULL) 16942 { 16943 /* between ":append" and "." and between ":python <<EOF" and "EOF" 16944 * don't check for ":endfunc". */ 16945 if (STRCMP(theline, skip_until) == 0) 16946 { 16947 vim_free(skip_until); 16948 skip_until = NULL; 16949 } 16950 } 16951 else 16952 { 16953 /* skip ':' and blanks*/ 16954 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 16955 ; 16956 16957 /* Check for "endfunction". */ 16958 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) 16959 { 16960 vim_free(theline); 16961 break; 16962 } 16963 16964 /* Increase indent inside "if", "while", "for" and "try", decrease 16965 * at "end". */ 16966 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 16967 indent -= 2; 16968 else if (STRNCMP(p, "if", 2) == 0 16969 || STRNCMP(p, "wh", 2) == 0 16970 || STRNCMP(p, "for", 3) == 0 16971 || STRNCMP(p, "try", 3) == 0) 16972 indent += 2; 16973 16974 /* Check for defining a function inside this function. */ 16975 if (checkforcmd(&p, "function", 2)) 16976 { 16977 if (*p == '!') 16978 p = skipwhite(p + 1); 16979 p += eval_fname_script(p); 16980 if (ASCII_ISALPHA(*p)) 16981 { 16982 vim_free(trans_function_name(&p, TRUE, 0, NULL)); 16983 if (*skipwhite(p) == '(') 16984 { 16985 ++nesting; 16986 indent += 2; 16987 } 16988 } 16989 } 16990 16991 /* Check for ":append" or ":insert". */ 16992 p = skip_range(p, NULL); 16993 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 16994 || (p[0] == 'i' 16995 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 16996 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 16997 skip_until = vim_strsave((char_u *)"."); 16998 16999 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 17000 arg = skipwhite(skiptowhite(p)); 17001 if (arg[0] == '<' && arg[1] =='<' 17002 && ((p[0] == 'p' && p[1] == 'y' 17003 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 17004 || (p[0] == 'p' && p[1] == 'e' 17005 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 17006 || (p[0] == 't' && p[1] == 'c' 17007 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 17008 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 17009 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 17010 || (p[0] == 'm' && p[1] == 'z' 17011 && (!ASCII_ISALPHA(p[2]) || p[2] == 's')) 17012 )) 17013 { 17014 /* ":python <<" continues until a dot, like ":append" */ 17015 p = skipwhite(arg + 2); 17016 if (*p == NUL) 17017 skip_until = vim_strsave((char_u *)"."); 17018 else 17019 skip_until = vim_strsave(p); 17020 } 17021 } 17022 17023 /* Add the line to the function. */ 17024 if (ga_grow(&newlines, 1) == FAIL) 17025 { 17026 vim_free(theline); 17027 goto erret; 17028 } 17029 17030 /* Copy the line to newly allocated memory. get_one_sourceline() 17031 * allocates 250 bytes per line, this saves 80% on average. The cost 17032 * is an extra alloc/free. */ 17033 p = vim_strsave(theline); 17034 if (p != NULL) 17035 { 17036 vim_free(theline); 17037 theline = p; 17038 } 17039 17040 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 17041 newlines.ga_len++; 17042 } 17043 17044 /* Don't define the function when skipping commands or when an error was 17045 * detected. */ 17046 if (eap->skip || did_emsg) 17047 goto erret; 17048 17049 /* 17050 * If there are no errors, add the function 17051 */ 17052 if (fudi.fd_dict == NULL) 17053 { 17054 v = find_var(name, &ht); 17055 if (v != NULL && v->di_tv.v_type == VAR_FUNC) 17056 { 17057 emsg_funcname("E707: Function name conflicts with variable: %s", 17058 name); 17059 goto erret; 17060 } 17061 17062 fp = find_func(name); 17063 if (fp != NULL) 17064 { 17065 if (!eap->forceit) 17066 { 17067 emsg_funcname(e_funcexts, name); 17068 goto erret; 17069 } 17070 if (fp->uf_calls > 0) 17071 { 17072 emsg_funcname("E127: Cannot redefine function %s: It is in use", 17073 name); 17074 goto erret; 17075 } 17076 /* redefine existing function */ 17077 ga_clear_strings(&(fp->uf_args)); 17078 ga_clear_strings(&(fp->uf_lines)); 17079 vim_free(name); 17080 name = NULL; 17081 } 17082 } 17083 else 17084 { 17085 char numbuf[20]; 17086 17087 fp = NULL; 17088 if (fudi.fd_newkey == NULL && !eap->forceit) 17089 { 17090 EMSG(_(e_funcdict)); 17091 goto erret; 17092 } 17093 if (fudi.fd_di == NULL) 17094 { 17095 /* Can't add a function to a locked dictionary */ 17096 if (tv_check_lock(fudi.fd_dict->dv_lock, eap->arg)) 17097 goto erret; 17098 } 17099 /* Can't change an existing function if it is locked */ 17100 else if (tv_check_lock(fudi.fd_di->di_tv.v_lock, eap->arg)) 17101 goto erret; 17102 17103 /* Give the function a sequential number. Can only be used with a 17104 * Funcref! */ 17105 vim_free(name); 17106 sprintf(numbuf, "%d", ++func_nr); 17107 name = vim_strsave((char_u *)numbuf); 17108 if (name == NULL) 17109 goto erret; 17110 } 17111 17112 if (fp == NULL) 17113 { 17114 if (fudi.fd_dict == NULL && vim_strchr(name, AUTOLOAD_CHAR) != NULL) 17115 { 17116 int slen, plen; 17117 char_u *scriptname; 17118 17119 /* Check that the autoload name matches the script name. */ 17120 j = FAIL; 17121 if (sourcing_name != NULL) 17122 { 17123 scriptname = autoload_name(name); 17124 if (scriptname != NULL) 17125 { 17126 p = vim_strchr(scriptname, '/'); 17127 plen = STRLEN(p); 17128 slen = STRLEN(sourcing_name); 17129 if (slen > plen && fnamecmp(p, 17130 sourcing_name + slen - plen) == 0) 17131 j = OK; 17132 vim_free(scriptname); 17133 } 17134 } 17135 if (j == FAIL) 17136 { 17137 EMSG2(_("E746: Function name does not match script file name: %s"), name); 17138 goto erret; 17139 } 17140 } 17141 17142 fp = (ufunc_T *)alloc((unsigned)(sizeof(ufunc_T) + STRLEN(name))); 17143 if (fp == NULL) 17144 goto erret; 17145 17146 if (fudi.fd_dict != NULL) 17147 { 17148 if (fudi.fd_di == NULL) 17149 { 17150 /* add new dict entry */ 17151 fudi.fd_di = dictitem_alloc(fudi.fd_newkey); 17152 if (fudi.fd_di == NULL) 17153 { 17154 vim_free(fp); 17155 goto erret; 17156 } 17157 if (dict_add(fudi.fd_dict, fudi.fd_di) == FAIL) 17158 { 17159 vim_free(fudi.fd_di); 17160 goto erret; 17161 } 17162 } 17163 else 17164 /* overwrite existing dict entry */ 17165 clear_tv(&fudi.fd_di->di_tv); 17166 fudi.fd_di->di_tv.v_type = VAR_FUNC; 17167 fudi.fd_di->di_tv.v_lock = 0; 17168 fudi.fd_di->di_tv.vval.v_string = vim_strsave(name); 17169 fp->uf_refcount = 1; 17170 } 17171 17172 /* insert the new function in the function list */ 17173 STRCPY(fp->uf_name, name); 17174 hash_add(&func_hashtab, UF2HIKEY(fp)); 17175 } 17176 fp->uf_args = newargs; 17177 fp->uf_lines = newlines; 17178 #ifdef FEAT_PROFILE 17179 fp->uf_tml_count = NULL; 17180 fp->uf_tml_total = NULL; 17181 fp->uf_tml_self = NULL; 17182 fp->uf_profiling = FALSE; 17183 if (prof_def_func()) 17184 func_do_profile(fp); 17185 #endif 17186 fp->uf_varargs = varargs; 17187 fp->uf_flags = flags; 17188 fp->uf_calls = 0; 17189 fp->uf_script_ID = current_SID; 17190 goto ret_free; 17191 17192 erret: 17193 ga_clear_strings(&newargs); 17194 ga_clear_strings(&newlines); 17195 ret_free: 17196 vim_free(skip_until); 17197 vim_free(fudi.fd_newkey); 17198 vim_free(name); 17199 did_emsg |= saved_did_emsg; 17200 } 17201 17202 /* 17203 * Get a function name, translating "<SID>" and "<SNR>". 17204 * Also handles a Funcref in a List or Dictionary. 17205 * Returns the function name in allocated memory, or NULL for failure. 17206 * flags: 17207 * TFN_INT: internal function name OK 17208 * TFN_QUIET: be quiet 17209 * Advances "pp" to just after the function name (if no error). 17210 */ 17211 static char_u * 17212 trans_function_name(pp, skip, flags, fdp) 17213 char_u **pp; 17214 int skip; /* only find the end, don't evaluate */ 17215 int flags; 17216 funcdict_T *fdp; /* return: info about dictionary used */ 17217 { 17218 char_u *name = NULL; 17219 char_u *start; 17220 char_u *end; 17221 int lead; 17222 char_u sid_buf[20]; 17223 int len; 17224 lval_T lv; 17225 17226 if (fdp != NULL) 17227 vim_memset(fdp, 0, sizeof(funcdict_T)); 17228 start = *pp; 17229 17230 /* Check for hard coded <SNR>: already translated function ID (from a user 17231 * command). */ 17232 if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA 17233 && (*pp)[2] == (int)KE_SNR) 17234 { 17235 *pp += 3; 17236 len = get_id_len(pp) + 3; 17237 return vim_strnsave(start, len); 17238 } 17239 17240 /* A name starting with "<SID>" or "<SNR>" is local to a script. But 17241 * don't skip over "s:", get_lval() needs it for "s:dict.func". */ 17242 lead = eval_fname_script(start); 17243 if (lead > 2) 17244 start += lead; 17245 17246 end = get_lval(start, NULL, &lv, FALSE, skip, flags & TFN_QUIET, 17247 lead > 2 ? 0 : FNE_CHECK_START); 17248 if (end == start) 17249 { 17250 if (!skip) 17251 EMSG(_("E129: Function name required")); 17252 goto theend; 17253 } 17254 if (end == NULL || (lv.ll_tv != NULL && (lead > 2 || lv.ll_range))) 17255 { 17256 /* 17257 * Report an invalid expression in braces, unless the expression 17258 * evaluation has been cancelled due to an aborting error, an 17259 * interrupt, or an exception. 17260 */ 17261 if (!aborting()) 17262 { 17263 if (end != NULL) 17264 EMSG2(_(e_invarg2), start); 17265 } 17266 else 17267 *pp = find_name_end(start, NULL, NULL, FNE_INCL_BR); 17268 goto theend; 17269 } 17270 17271 if (lv.ll_tv != NULL) 17272 { 17273 if (fdp != NULL) 17274 { 17275 fdp->fd_dict = lv.ll_dict; 17276 fdp->fd_newkey = lv.ll_newkey; 17277 lv.ll_newkey = NULL; 17278 fdp->fd_di = lv.ll_di; 17279 } 17280 if (lv.ll_tv->v_type == VAR_FUNC && lv.ll_tv->vval.v_string != NULL) 17281 { 17282 name = vim_strsave(lv.ll_tv->vval.v_string); 17283 *pp = end; 17284 } 17285 else 17286 { 17287 if (!skip && !(flags & TFN_QUIET) && (fdp == NULL 17288 || lv.ll_dict == NULL || fdp->fd_newkey == NULL)) 17289 EMSG(_(e_funcref)); 17290 else 17291 *pp = end; 17292 name = NULL; 17293 } 17294 goto theend; 17295 } 17296 17297 if (lv.ll_name == NULL) 17298 { 17299 /* Error found, but continue after the function name. */ 17300 *pp = end; 17301 goto theend; 17302 } 17303 17304 if (lv.ll_exp_name != NULL) 17305 len = STRLEN(lv.ll_exp_name); 17306 else 17307 { 17308 if (lead == 2) /* skip over "s:" */ 17309 lv.ll_name += 2; 17310 len = (int)(end - lv.ll_name); 17311 } 17312 17313 /* 17314 * Copy the function name to allocated memory. 17315 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 17316 * Accept <SNR>123_name() outside a script. 17317 */ 17318 if (skip) 17319 lead = 0; /* do nothing */ 17320 else if (lead > 0) 17321 { 17322 lead = 3; 17323 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 17324 { 17325 if (current_SID <= 0) 17326 { 17327 EMSG(_(e_usingsid)); 17328 goto theend; 17329 } 17330 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 17331 lead += (int)STRLEN(sid_buf); 17332 } 17333 } 17334 else if (!(flags & TFN_INT) && builtin_function(lv.ll_name)) 17335 { 17336 EMSG2(_("E128: Function name must start with a capital or contain a colon: %s"), lv.ll_name); 17337 goto theend; 17338 } 17339 name = alloc((unsigned)(len + lead + 1)); 17340 if (name != NULL) 17341 { 17342 if (lead > 0) 17343 { 17344 name[0] = K_SPECIAL; 17345 name[1] = KS_EXTRA; 17346 name[2] = (int)KE_SNR; 17347 if (lead > 3) /* If it's "<SID>" */ 17348 STRCPY(name + 3, sid_buf); 17349 } 17350 mch_memmove(name + lead, lv.ll_name, (size_t)len); 17351 name[len + lead] = NUL; 17352 } 17353 *pp = end; 17354 17355 theend: 17356 clear_lval(&lv); 17357 return name; 17358 } 17359 17360 /* 17361 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 17362 * Return 2 if "p" starts with "s:". 17363 * Return 0 otherwise. 17364 */ 17365 static int 17366 eval_fname_script(p) 17367 char_u *p; 17368 { 17369 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 17370 || STRNICMP(p + 1, "SNR>", 4) == 0)) 17371 return 5; 17372 if (p[0] == 's' && p[1] == ':') 17373 return 2; 17374 return 0; 17375 } 17376 17377 /* 17378 * Return TRUE if "p" starts with "<SID>" or "s:". 17379 * Only works if eval_fname_script() returned non-zero for "p"! 17380 */ 17381 static int 17382 eval_fname_sid(p) 17383 char_u *p; 17384 { 17385 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 17386 } 17387 17388 /* 17389 * List the head of the function: "name(arg1, arg2)". 17390 */ 17391 static void 17392 list_func_head(fp, indent) 17393 ufunc_T *fp; 17394 int indent; 17395 { 17396 int j; 17397 17398 msg_start(); 17399 if (indent) 17400 MSG_PUTS(" "); 17401 MSG_PUTS("function "); 17402 if (fp->uf_name[0] == K_SPECIAL) 17403 { 17404 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 17405 msg_puts(fp->uf_name + 3); 17406 } 17407 else 17408 msg_puts(fp->uf_name); 17409 msg_putchar('('); 17410 for (j = 0; j < fp->uf_args.ga_len; ++j) 17411 { 17412 if (j) 17413 MSG_PUTS(", "); 17414 msg_puts(FUNCARG(fp, j)); 17415 } 17416 if (fp->uf_varargs) 17417 { 17418 if (j) 17419 MSG_PUTS(", "); 17420 MSG_PUTS("..."); 17421 } 17422 msg_putchar(')'); 17423 } 17424 17425 /* 17426 * Find a function by name, return pointer to it in ufuncs. 17427 * Return NULL for unknown function. 17428 */ 17429 static ufunc_T * 17430 find_func(name) 17431 char_u *name; 17432 { 17433 hashitem_T *hi; 17434 17435 hi = hash_find(&func_hashtab, name); 17436 if (!HASHITEM_EMPTY(hi)) 17437 return HI2UF(hi); 17438 return NULL; 17439 } 17440 17441 #if defined(EXITFREE) || defined(PROTO) 17442 void 17443 free_all_functions() 17444 { 17445 hashitem_T *hi; 17446 17447 /* Need to start all over every time, because func_free() may change the 17448 * hash table. */ 17449 while (func_hashtab.ht_used > 0) 17450 for (hi = func_hashtab.ht_array; ; ++hi) 17451 if (!HASHITEM_EMPTY(hi)) 17452 { 17453 func_free(HI2UF(hi)); 17454 break; 17455 } 17456 } 17457 #endif 17458 17459 /* 17460 * Return TRUE if a function "name" exists. 17461 */ 17462 static int 17463 function_exists(name) 17464 char_u *name; 17465 { 17466 char_u *p = name; 17467 int n = FALSE; 17468 17469 p = trans_function_name(&p, FALSE, TFN_INT|TFN_QUIET, NULL); 17470 if (p != NULL) 17471 { 17472 if (builtin_function(p)) 17473 n = (find_internal_func(p) >= 0); 17474 else 17475 n = (find_func(p) != NULL); 17476 vim_free(p); 17477 } 17478 return n; 17479 } 17480 17481 /* 17482 * Return TRUE if "name" looks like a builtin function name: starts with a 17483 * lower case letter and doesn't contain a ':' or AUTOLOAD_CHAR. 17484 */ 17485 static int 17486 builtin_function(name) 17487 char_u *name; 17488 { 17489 return ASCII_ISLOWER(name[0]) && vim_strchr(name, ':') == NULL 17490 && vim_strchr(name, AUTOLOAD_CHAR) == NULL; 17491 } 17492 17493 #if defined(FEAT_PROFILE) || defined(PROTO) 17494 /* 17495 * Start profiling function "fp". 17496 */ 17497 static void 17498 func_do_profile(fp) 17499 ufunc_T *fp; 17500 { 17501 fp->uf_tm_count = 0; 17502 profile_zero(&fp->uf_tm_self); 17503 profile_zero(&fp->uf_tm_total); 17504 if (fp->uf_tml_count == NULL) 17505 fp->uf_tml_count = (int *)alloc_clear((unsigned) 17506 (sizeof(int) * fp->uf_lines.ga_len)); 17507 if (fp->uf_tml_total == NULL) 17508 fp->uf_tml_total = (proftime_T *)alloc_clear((unsigned) 17509 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17510 if (fp->uf_tml_self == NULL) 17511 fp->uf_tml_self = (proftime_T *)alloc_clear((unsigned) 17512 (sizeof(proftime_T) * fp->uf_lines.ga_len)); 17513 fp->uf_tml_idx = -1; 17514 if (fp->uf_tml_count == NULL || fp->uf_tml_total == NULL 17515 || fp->uf_tml_self == NULL) 17516 return; /* out of memory */ 17517 17518 fp->uf_profiling = TRUE; 17519 } 17520 17521 /* 17522 * Dump the profiling results for all functions in file "fd". 17523 */ 17524 void 17525 func_dump_profile(fd) 17526 FILE *fd; 17527 { 17528 hashitem_T *hi; 17529 int todo; 17530 ufunc_T *fp; 17531 int i; 17532 ufunc_T **sorttab; 17533 int st_len = 0; 17534 17535 todo = func_hashtab.ht_used; 17536 sorttab = (ufunc_T **)alloc((unsigned)(sizeof(ufunc_T) * todo)); 17537 17538 for (hi = func_hashtab.ht_array; todo > 0; ++hi) 17539 { 17540 if (!HASHITEM_EMPTY(hi)) 17541 { 17542 --todo; 17543 fp = HI2UF(hi); 17544 if (fp->uf_profiling) 17545 { 17546 if (sorttab != NULL) 17547 sorttab[st_len++] = fp; 17548 17549 if (fp->uf_name[0] == K_SPECIAL) 17550 fprintf(fd, "FUNCTION <SNR>%s()\n", fp->uf_name + 3); 17551 else 17552 fprintf(fd, "FUNCTION %s()\n", fp->uf_name); 17553 if (fp->uf_tm_count == 1) 17554 fprintf(fd, "Called 1 time\n"); 17555 else 17556 fprintf(fd, "Called %d times\n", fp->uf_tm_count); 17557 fprintf(fd, "Total time: %s\n", profile_msg(&fp->uf_tm_total)); 17558 fprintf(fd, " Self time: %s\n", profile_msg(&fp->uf_tm_self)); 17559 fprintf(fd, "\n"); 17560 fprintf(fd, "count total (s) self (s)\n"); 17561 17562 for (i = 0; i < fp->uf_lines.ga_len; ++i) 17563 { 17564 prof_func_line(fd, fp->uf_tml_count[i], 17565 &fp->uf_tml_total[i], &fp->uf_tml_self[i], TRUE); 17566 fprintf(fd, "%s\n", FUNCLINE(fp, i)); 17567 } 17568 fprintf(fd, "\n"); 17569 } 17570 } 17571 } 17572 17573 if (sorttab != NULL && st_len > 0) 17574 { 17575 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17576 prof_total_cmp); 17577 prof_sort_list(fd, sorttab, st_len, "TOTAL", FALSE); 17578 qsort((void *)sorttab, (size_t)st_len, sizeof(ufunc_T *), 17579 prof_self_cmp); 17580 prof_sort_list(fd, sorttab, st_len, "SELF", TRUE); 17581 } 17582 } 17583 17584 static void 17585 prof_sort_list(fd, sorttab, st_len, title, prefer_self) 17586 FILE *fd; 17587 ufunc_T **sorttab; 17588 int st_len; 17589 char *title; 17590 int prefer_self; /* when equal print only self time */ 17591 { 17592 int i; 17593 ufunc_T *fp; 17594 17595 fprintf(fd, "FUNCTIONS SORTED ON %s TIME\n", title); 17596 fprintf(fd, "count total (s) self (s) function\n"); 17597 for (i = 0; i < 20 && i < st_len; ++i) 17598 { 17599 fp = sorttab[i]; 17600 prof_func_line(fd, fp->uf_tm_count, &fp->uf_tm_total, &fp->uf_tm_self, 17601 prefer_self); 17602 if (fp->uf_name[0] == K_SPECIAL) 17603 fprintf(fd, " <SNR>%s()\n", fp->uf_name + 3); 17604 else 17605 fprintf(fd, " %s()\n", fp->uf_name); 17606 } 17607 fprintf(fd, "\n"); 17608 } 17609 17610 /* 17611 * Print the count and times for one function or function line. 17612 */ 17613 static void 17614 prof_func_line(fd, count, total, self, prefer_self) 17615 FILE *fd; 17616 int count; 17617 proftime_T *total; 17618 proftime_T *self; 17619 int prefer_self; /* when equal print only self time */ 17620 { 17621 if (count > 0) 17622 { 17623 fprintf(fd, "%5d ", count); 17624 if (prefer_self && profile_equal(total, self)) 17625 fprintf(fd, " "); 17626 else 17627 fprintf(fd, "%s ", profile_msg(total)); 17628 if (!prefer_self && profile_equal(total, self)) 17629 fprintf(fd, " "); 17630 else 17631 fprintf(fd, "%s ", profile_msg(self)); 17632 } 17633 else 17634 fprintf(fd, " "); 17635 } 17636 17637 /* 17638 * Compare function for total time sorting. 17639 */ 17640 static int 17641 #ifdef __BORLANDC__ 17642 _RTLENTRYF 17643 #endif 17644 prof_total_cmp(s1, s2) 17645 const void *s1; 17646 const void *s2; 17647 { 17648 ufunc_T *p1, *p2; 17649 17650 p1 = *(ufunc_T **)s1; 17651 p2 = *(ufunc_T **)s2; 17652 return profile_cmp(&p1->uf_tm_total, &p2->uf_tm_total); 17653 } 17654 17655 /* 17656 * Compare function for self time sorting. 17657 */ 17658 static int 17659 #ifdef __BORLANDC__ 17660 _RTLENTRYF 17661 #endif 17662 prof_self_cmp(s1, s2) 17663 const void *s1; 17664 const void *s2; 17665 { 17666 ufunc_T *p1, *p2; 17667 17668 p1 = *(ufunc_T **)s1; 17669 p2 = *(ufunc_T **)s2; 17670 return profile_cmp(&p1->uf_tm_self, &p2->uf_tm_self); 17671 } 17672 17673 #endif 17674 17675 /* The names of packages that once were loaded is remembered. */ 17676 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; 17677 17678 /* 17679 * If "name" has a package name try autoloading the script for it. 17680 * Return TRUE if a package was loaded. 17681 */ 17682 static int 17683 script_autoload(name, reload) 17684 char_u *name; 17685 int reload; /* load script again when already loaded */ 17686 { 17687 char_u *p; 17688 char_u *scriptname, *tofree; 17689 int ret = FALSE; 17690 int i; 17691 17692 /* If there is no '#' after name[0] there is no package name. */ 17693 p = vim_strchr(name, AUTOLOAD_CHAR); 17694 if (p == NULL || p == name) 17695 return FALSE; 17696 17697 tofree = scriptname = autoload_name(name); 17698 17699 /* Find the name in the list of previously loaded package names. Skip 17700 * "autoload/", it's always the same. */ 17701 for (i = 0; i < ga_loaded.ga_len; ++i) 17702 if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) 17703 break; 17704 if (!reload && i < ga_loaded.ga_len) 17705 ret = FALSE; /* was loaded already */ 17706 else 17707 { 17708 /* Remember the name if it wasn't loaded already. */ 17709 if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK) 17710 { 17711 ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname; 17712 tofree = NULL; 17713 } 17714 17715 /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */ 17716 if (cmd_runtime(scriptname, FALSE) == OK) 17717 ret = TRUE; 17718 } 17719 17720 vim_free(tofree); 17721 return ret; 17722 } 17723 17724 /* 17725 * Return the autoload script name for a function or variable name. 17726 * Returns NULL when out of memory. 17727 */ 17728 static char_u * 17729 autoload_name(name) 17730 char_u *name; 17731 { 17732 char_u *p; 17733 char_u *scriptname; 17734 17735 /* Get the script file name: replace '#' with '/', append ".vim". */ 17736 scriptname = alloc((unsigned)(STRLEN(name) + 14)); 17737 if (scriptname == NULL) 17738 return FALSE; 17739 STRCPY(scriptname, "autoload/"); 17740 STRCAT(scriptname, name); 17741 *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; 17742 STRCAT(scriptname, ".vim"); 17743 while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) 17744 *p = '/'; 17745 return scriptname; 17746 } 17747 17748 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 17749 17750 /* 17751 * Function given to ExpandGeneric() to obtain the list of user defined 17752 * function names. 17753 */ 17754 char_u * 17755 get_user_func_name(xp, idx) 17756 expand_T *xp; 17757 int idx; 17758 { 17759 static long_u done; 17760 static hashitem_T *hi; 17761 ufunc_T *fp; 17762 17763 if (idx == 0) 17764 { 17765 done = 0; 17766 hi = func_hashtab.ht_array; 17767 } 17768 if (done < func_hashtab.ht_used) 17769 { 17770 if (done++ > 0) 17771 ++hi; 17772 while (HASHITEM_EMPTY(hi)) 17773 ++hi; 17774 fp = HI2UF(hi); 17775 17776 if (STRLEN(fp->uf_name) + 4 >= IOSIZE) 17777 return fp->uf_name; /* prevents overflow */ 17778 17779 cat_func_name(IObuff, fp); 17780 if (xp->xp_context != EXPAND_USER_FUNC) 17781 { 17782 STRCAT(IObuff, "("); 17783 if (!fp->uf_varargs && fp->uf_args.ga_len == 0) 17784 STRCAT(IObuff, ")"); 17785 } 17786 return IObuff; 17787 } 17788 return NULL; 17789 } 17790 17791 #endif /* FEAT_CMDL_COMPL */ 17792 17793 /* 17794 * Copy the function name of "fp" to buffer "buf". 17795 * "buf" must be able to hold the function name plus three bytes. 17796 * Takes care of script-local function names. 17797 */ 17798 static void 17799 cat_func_name(buf, fp) 17800 char_u *buf; 17801 ufunc_T *fp; 17802 { 17803 if (fp->uf_name[0] == K_SPECIAL) 17804 { 17805 STRCPY(buf, "<SNR>"); 17806 STRCAT(buf, fp->uf_name + 3); 17807 } 17808 else 17809 STRCPY(buf, fp->uf_name); 17810 } 17811 17812 /* 17813 * ":delfunction {name}" 17814 */ 17815 void 17816 ex_delfunction(eap) 17817 exarg_T *eap; 17818 { 17819 ufunc_T *fp = NULL; 17820 char_u *p; 17821 char_u *name; 17822 funcdict_T fudi; 17823 17824 p = eap->arg; 17825 name = trans_function_name(&p, eap->skip, 0, &fudi); 17826 vim_free(fudi.fd_newkey); 17827 if (name == NULL) 17828 { 17829 if (fudi.fd_dict != NULL && !eap->skip) 17830 EMSG(_(e_funcref)); 17831 return; 17832 } 17833 if (!ends_excmd(*skipwhite(p))) 17834 { 17835 vim_free(name); 17836 EMSG(_(e_trailing)); 17837 return; 17838 } 17839 eap->nextcmd = check_nextcmd(p); 17840 if (eap->nextcmd != NULL) 17841 *p = NUL; 17842 17843 if (!eap->skip) 17844 fp = find_func(name); 17845 vim_free(name); 17846 17847 if (!eap->skip) 17848 { 17849 if (fp == NULL) 17850 { 17851 EMSG2(_(e_nofunc), eap->arg); 17852 return; 17853 } 17854 if (fp->uf_calls > 0) 17855 { 17856 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 17857 return; 17858 } 17859 17860 if (fudi.fd_dict != NULL) 17861 { 17862 /* Delete the dict item that refers to the function, it will 17863 * invoke func_unref() and possibly delete the function. */ 17864 dictitem_remove(fudi.fd_dict, fudi.fd_di); 17865 } 17866 else 17867 func_free(fp); 17868 } 17869 } 17870 17871 /* 17872 * Free a function and remove it from the list of functions. 17873 */ 17874 static void 17875 func_free(fp) 17876 ufunc_T *fp; 17877 { 17878 hashitem_T *hi; 17879 17880 /* clear this function */ 17881 ga_clear_strings(&(fp->uf_args)); 17882 ga_clear_strings(&(fp->uf_lines)); 17883 #ifdef FEAT_PROFILE 17884 vim_free(fp->uf_tml_count); 17885 vim_free(fp->uf_tml_total); 17886 vim_free(fp->uf_tml_self); 17887 #endif 17888 17889 /* remove the function from the function hashtable */ 17890 hi = hash_find(&func_hashtab, UF2HIKEY(fp)); 17891 if (HASHITEM_EMPTY(hi)) 17892 EMSG2(_(e_intern2), "func_free()"); 17893 else 17894 hash_remove(&func_hashtab, hi); 17895 17896 vim_free(fp); 17897 } 17898 17899 /* 17900 * Unreference a Function: decrement the reference count and free it when it 17901 * becomes zero. Only for numbered functions. 17902 */ 17903 static void 17904 func_unref(name) 17905 char_u *name; 17906 { 17907 ufunc_T *fp; 17908 17909 if (name != NULL && isdigit(*name)) 17910 { 17911 fp = find_func(name); 17912 if (fp == NULL) 17913 EMSG2(_(e_intern2), "func_unref()"); 17914 else if (--fp->uf_refcount <= 0) 17915 { 17916 /* Only delete it when it's not being used. Otherwise it's done 17917 * when "uf_calls" becomes zero. */ 17918 if (fp->uf_calls == 0) 17919 func_free(fp); 17920 } 17921 } 17922 } 17923 17924 /* 17925 * Count a reference to a Function. 17926 */ 17927 static void 17928 func_ref(name) 17929 char_u *name; 17930 { 17931 ufunc_T *fp; 17932 17933 if (name != NULL && isdigit(*name)) 17934 { 17935 fp = find_func(name); 17936 if (fp == NULL) 17937 EMSG2(_(e_intern2), "func_ref()"); 17938 else 17939 ++fp->uf_refcount; 17940 } 17941 } 17942 17943 /* 17944 * Call a user function. 17945 */ 17946 static void 17947 call_user_func(fp, argcount, argvars, rettv, firstline, lastline, selfdict) 17948 ufunc_T *fp; /* pointer to function */ 17949 int argcount; /* nr of args */ 17950 typval_T *argvars; /* arguments */ 17951 typval_T *rettv; /* return value */ 17952 linenr_T firstline; /* first line of range */ 17953 linenr_T lastline; /* last line of range */ 17954 dict_T *selfdict; /* Dictionary for "self" */ 17955 { 17956 char_u *save_sourcing_name; 17957 linenr_T save_sourcing_lnum; 17958 scid_T save_current_SID; 17959 funccall_T fc; 17960 int save_did_emsg; 17961 static int depth = 0; 17962 dictitem_T *v; 17963 int fixvar_idx = 0; /* index in fixvar[] */ 17964 int i; 17965 int ai; 17966 char_u numbuf[NUMBUFLEN]; 17967 char_u *name; 17968 #ifdef FEAT_PROFILE 17969 proftime_T wait_start; 17970 #endif 17971 17972 /* If depth of calling is getting too high, don't execute the function */ 17973 if (depth >= p_mfd) 17974 { 17975 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 17976 rettv->v_type = VAR_NUMBER; 17977 rettv->vval.v_number = -1; 17978 return; 17979 } 17980 ++depth; 17981 17982 line_breakcheck(); /* check for CTRL-C hit */ 17983 17984 fc.caller = current_funccal; 17985 current_funccal = &fc; 17986 fc.func = fp; 17987 fc.rettv = rettv; 17988 rettv->vval.v_number = 0; 17989 fc.linenr = 0; 17990 fc.returned = FALSE; 17991 fc.level = ex_nesting_level; 17992 /* Check if this function has a breakpoint. */ 17993 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, (linenr_T)0); 17994 fc.dbg_tick = debug_tick; 17995 17996 /* 17997 * Note about using fc.fixvar[]: This is an array of FIXVAR_CNT variables 17998 * with names up to VAR_SHORT_LEN long. This avoids having to alloc/free 17999 * each argument variable and saves a lot of time. 18000 */ 18001 /* 18002 * Init l: variables. 18003 */ 18004 init_var_dict(&fc.l_vars, &fc.l_vars_var); 18005 if (selfdict != NULL) 18006 { 18007 /* Set l:self to "selfdict". */ 18008 v = &fc.fixvar[fixvar_idx++].var; 18009 STRCPY(v->di_key, "self"); 18010 v->di_flags = DI_FLAGS_RO + DI_FLAGS_FIX; 18011 hash_add(&fc.l_vars.dv_hashtab, DI2HIKEY(v)); 18012 v->di_tv.v_type = VAR_DICT; 18013 v->di_tv.v_lock = 0; 18014 v->di_tv.vval.v_dict = selfdict; 18015 ++selfdict->dv_refcount; 18016 } 18017 18018 /* 18019 * Init a: variables. 18020 * Set a:0 to "argcount". 18021 * Set a:000 to a list with room for the "..." arguments. 18022 */ 18023 init_var_dict(&fc.l_avars, &fc.l_avars_var); 18024 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "0", 18025 (varnumber_T)(argcount - fp->uf_args.ga_len)); 18026 v = &fc.fixvar[fixvar_idx++].var; 18027 STRCPY(v->di_key, "000"); 18028 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18029 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18030 v->di_tv.v_type = VAR_LIST; 18031 v->di_tv.v_lock = VAR_FIXED; 18032 v->di_tv.vval.v_list = &fc.l_varlist; 18033 vim_memset(&fc.l_varlist, 0, sizeof(list_T)); 18034 fc.l_varlist.lv_refcount = 99999; 18035 18036 /* 18037 * Set a:firstline to "firstline" and a:lastline to "lastline". 18038 * Set a:name to named arguments. 18039 * Set a:N to the "..." arguments. 18040 */ 18041 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "firstline", 18042 (varnumber_T)firstline); 18043 add_nr_var(&fc.l_avars, &fc.fixvar[fixvar_idx++].var, "lastline", 18044 (varnumber_T)lastline); 18045 for (i = 0; i < argcount; ++i) 18046 { 18047 ai = i - fp->uf_args.ga_len; 18048 if (ai < 0) 18049 /* named argument a:name */ 18050 name = FUNCARG(fp, i); 18051 else 18052 { 18053 /* "..." argument a:1, a:2, etc. */ 18054 sprintf((char *)numbuf, "%d", ai + 1); 18055 name = numbuf; 18056 } 18057 if (fixvar_idx < FIXVAR_CNT && STRLEN(name) <= VAR_SHORT_LEN) 18058 { 18059 v = &fc.fixvar[fixvar_idx++].var; 18060 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18061 } 18062 else 18063 { 18064 v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T) 18065 + STRLEN(name))); 18066 if (v == NULL) 18067 break; 18068 v->di_flags = DI_FLAGS_RO; 18069 } 18070 STRCPY(v->di_key, name); 18071 hash_add(&fc.l_avars.dv_hashtab, DI2HIKEY(v)); 18072 18073 /* Note: the values are copied directly to avoid alloc/free. 18074 * "argvars" must have VAR_FIXED for v_lock. */ 18075 v->di_tv = argvars[i]; 18076 v->di_tv.v_lock = VAR_FIXED; 18077 18078 if (ai >= 0 && ai < MAX_FUNC_ARGS) 18079 { 18080 list_append(&fc.l_varlist, &fc.l_listitems[ai]); 18081 fc.l_listitems[ai].li_tv = argvars[i]; 18082 fc.l_listitems[ai].li_tv.v_lock = VAR_FIXED; 18083 } 18084 } 18085 18086 /* Don't redraw while executing the function. */ 18087 ++RedrawingDisabled; 18088 save_sourcing_name = sourcing_name; 18089 save_sourcing_lnum = sourcing_lnum; 18090 sourcing_lnum = 1; 18091 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 18092 : STRLEN(save_sourcing_name)) + STRLEN(fp->uf_name) + 13)); 18093 if (sourcing_name != NULL) 18094 { 18095 if (save_sourcing_name != NULL 18096 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 18097 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 18098 else 18099 STRCPY(sourcing_name, "function "); 18100 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 18101 18102 if (p_verbose >= 12) 18103 { 18104 ++no_wait_return; 18105 verbose_enter_scroll(); 18106 18107 smsg((char_u *)_("calling %s"), sourcing_name); 18108 if (p_verbose >= 14) 18109 { 18110 char_u buf[MSG_BUF_LEN]; 18111 char_u numbuf[NUMBUFLEN]; 18112 char_u *tofree; 18113 18114 msg_puts((char_u *)"("); 18115 for (i = 0; i < argcount; ++i) 18116 { 18117 if (i > 0) 18118 msg_puts((char_u *)", "); 18119 if (argvars[i].v_type == VAR_NUMBER) 18120 msg_outnum((long)argvars[i].vval.v_number); 18121 else 18122 { 18123 trunc_string(tv2string(&argvars[i], &tofree, numbuf), 18124 buf, MSG_BUF_CLEN); 18125 msg_puts(buf); 18126 vim_free(tofree); 18127 } 18128 } 18129 msg_puts((char_u *)")"); 18130 } 18131 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18132 18133 verbose_leave_scroll(); 18134 --no_wait_return; 18135 } 18136 } 18137 #ifdef FEAT_PROFILE 18138 if (do_profiling) 18139 { 18140 if (!fp->uf_profiling && has_profiling(FALSE, fp->uf_name, NULL)) 18141 func_do_profile(fp); 18142 if (fp->uf_profiling 18143 || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18144 { 18145 ++fp->uf_tm_count; 18146 profile_start(&fp->uf_tm_start); 18147 profile_zero(&fp->uf_tm_children); 18148 } 18149 script_prof_save(&wait_start); 18150 } 18151 #endif 18152 18153 save_current_SID = current_SID; 18154 current_SID = fp->uf_script_ID; 18155 save_did_emsg = did_emsg; 18156 did_emsg = FALSE; 18157 18158 /* call do_cmdline() to execute the lines */ 18159 do_cmdline(NULL, get_func_line, (void *)&fc, 18160 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 18161 18162 --RedrawingDisabled; 18163 18164 /* when the function was aborted because of an error, return -1 */ 18165 if ((did_emsg && (fp->uf_flags & FC_ABORT)) || rettv->v_type == VAR_UNKNOWN) 18166 { 18167 clear_tv(rettv); 18168 rettv->v_type = VAR_NUMBER; 18169 rettv->vval.v_number = -1; 18170 } 18171 18172 #ifdef FEAT_PROFILE 18173 if (fp->uf_profiling || (fc.caller != NULL && &fc.caller->func->uf_profiling)) 18174 { 18175 profile_end(&fp->uf_tm_start); 18176 profile_sub_wait(&wait_start, &fp->uf_tm_start); 18177 profile_add(&fp->uf_tm_total, &fp->uf_tm_start); 18178 profile_add(&fp->uf_tm_self, &fp->uf_tm_start); 18179 profile_sub(&fp->uf_tm_self, &fp->uf_tm_children); 18180 if (fc.caller != NULL && &fc.caller->func->uf_profiling) 18181 { 18182 profile_add(&fc.caller->func->uf_tm_children, &fp->uf_tm_start); 18183 profile_add(&fc.caller->func->uf_tml_children, &fp->uf_tm_start); 18184 } 18185 } 18186 #endif 18187 18188 /* when being verbose, mention the return value */ 18189 if (p_verbose >= 12) 18190 { 18191 ++no_wait_return; 18192 verbose_enter_scroll(); 18193 18194 if (aborting()) 18195 smsg((char_u *)_("%s aborted"), sourcing_name); 18196 else if (fc.rettv->v_type == VAR_NUMBER) 18197 smsg((char_u *)_("%s returning #%ld"), sourcing_name, 18198 (long)fc.rettv->vval.v_number); 18199 else 18200 { 18201 char_u buf[MSG_BUF_LEN]; 18202 char_u numbuf[NUMBUFLEN]; 18203 char_u *tofree; 18204 18205 /* The value may be very long. Skip the middle part, so that we 18206 * have some idea how it starts and ends. smsg() would always 18207 * truncate it at the end. */ 18208 trunc_string(tv2string(fc.rettv, &tofree, numbuf), 18209 buf, MSG_BUF_CLEN); 18210 smsg((char_u *)_("%s returning %s"), sourcing_name, buf); 18211 vim_free(tofree); 18212 } 18213 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18214 18215 verbose_leave_scroll(); 18216 --no_wait_return; 18217 } 18218 18219 vim_free(sourcing_name); 18220 sourcing_name = save_sourcing_name; 18221 sourcing_lnum = save_sourcing_lnum; 18222 current_SID = save_current_SID; 18223 #ifdef FEAT_PROFILE 18224 if (do_profiling) 18225 script_prof_restore(&wait_start); 18226 #endif 18227 18228 if (p_verbose >= 12 && sourcing_name != NULL) 18229 { 18230 ++no_wait_return; 18231 verbose_enter_scroll(); 18232 18233 smsg((char_u *)_("continuing in %s"), sourcing_name); 18234 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 18235 18236 verbose_leave_scroll(); 18237 --no_wait_return; 18238 } 18239 18240 did_emsg |= save_did_emsg; 18241 current_funccal = fc.caller; 18242 18243 /* The a: variables typevals were not alloced, only free the allocated 18244 * variables. */ 18245 vars_clear_ext(&fc.l_avars.dv_hashtab, FALSE); 18246 18247 vars_clear(&fc.l_vars.dv_hashtab); /* free all l: variables */ 18248 --depth; 18249 } 18250 18251 /* 18252 * Add a number variable "name" to dict "dp" with value "nr". 18253 */ 18254 static void 18255 add_nr_var(dp, v, name, nr) 18256 dict_T *dp; 18257 dictitem_T *v; 18258 char *name; 18259 varnumber_T nr; 18260 { 18261 STRCPY(v->di_key, name); 18262 v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX; 18263 hash_add(&dp->dv_hashtab, DI2HIKEY(v)); 18264 v->di_tv.v_type = VAR_NUMBER; 18265 v->di_tv.v_lock = VAR_FIXED; 18266 v->di_tv.vval.v_number = nr; 18267 } 18268 18269 /* 18270 * ":return [expr]" 18271 */ 18272 void 18273 ex_return(eap) 18274 exarg_T *eap; 18275 { 18276 char_u *arg = eap->arg; 18277 typval_T rettv; 18278 int returning = FALSE; 18279 18280 if (current_funccal == NULL) 18281 { 18282 EMSG(_("E133: :return not inside a function")); 18283 return; 18284 } 18285 18286 if (eap->skip) 18287 ++emsg_skip; 18288 18289 eap->nextcmd = NULL; 18290 if ((*arg != NUL && *arg != '|' && *arg != '\n') 18291 && eval0(arg, &rettv, &eap->nextcmd, !eap->skip) != FAIL) 18292 { 18293 if (!eap->skip) 18294 returning = do_return(eap, FALSE, TRUE, &rettv); 18295 else 18296 clear_tv(&rettv); 18297 } 18298 /* It's safer to return also on error. */ 18299 else if (!eap->skip) 18300 { 18301 /* 18302 * Return unless the expression evaluation has been cancelled due to an 18303 * aborting error, an interrupt, or an exception. 18304 */ 18305 if (!aborting()) 18306 returning = do_return(eap, FALSE, TRUE, NULL); 18307 } 18308 18309 /* When skipping or the return gets pending, advance to the next command 18310 * in this line (!returning). Otherwise, ignore the rest of the line. 18311 * Following lines will be ignored by get_func_line(). */ 18312 if (returning) 18313 eap->nextcmd = NULL; 18314 else if (eap->nextcmd == NULL) /* no argument */ 18315 eap->nextcmd = check_nextcmd(arg); 18316 18317 if (eap->skip) 18318 --emsg_skip; 18319 } 18320 18321 /* 18322 * Return from a function. Possibly makes the return pending. Also called 18323 * for a pending return at the ":endtry" or after returning from an extra 18324 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 18325 * when called due to a ":return" command. "rettv" may point to a typval_T 18326 * with the return rettv. Returns TRUE when the return can be carried out, 18327 * FALSE when the return gets pending. 18328 */ 18329 int 18330 do_return(eap, reanimate, is_cmd, rettv) 18331 exarg_T *eap; 18332 int reanimate; 18333 int is_cmd; 18334 void *rettv; 18335 { 18336 int idx; 18337 struct condstack *cstack = eap->cstack; 18338 18339 if (reanimate) 18340 /* Undo the return. */ 18341 current_funccal->returned = FALSE; 18342 18343 /* 18344 * Cleanup (and inactivate) conditionals, but stop when a try conditional 18345 * not in its finally clause (which then is to be executed next) is found. 18346 * In this case, make the ":return" pending for execution at the ":endtry". 18347 * Otherwise, return normally. 18348 */ 18349 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 18350 if (idx >= 0) 18351 { 18352 cstack->cs_pending[idx] = CSTP_RETURN; 18353 18354 if (!is_cmd && !reanimate) 18355 /* A pending return again gets pending. "rettv" points to an 18356 * allocated variable with the rettv of the original ":return"'s 18357 * argument if present or is NULL else. */ 18358 cstack->cs_rettv[idx] = rettv; 18359 else 18360 { 18361 /* When undoing a return in order to make it pending, get the stored 18362 * return rettv. */ 18363 if (reanimate) 18364 rettv = current_funccal->rettv; 18365 18366 if (rettv != NULL) 18367 { 18368 /* Store the value of the pending return. */ 18369 if ((cstack->cs_rettv[idx] = alloc_tv()) != NULL) 18370 *(typval_T *)cstack->cs_rettv[idx] = *(typval_T *)rettv; 18371 else 18372 EMSG(_(e_outofmem)); 18373 } 18374 else 18375 cstack->cs_rettv[idx] = NULL; 18376 18377 if (reanimate) 18378 { 18379 /* The pending return value could be overwritten by a ":return" 18380 * without argument in a finally clause; reset the default 18381 * return value. */ 18382 current_funccal->rettv->v_type = VAR_NUMBER; 18383 current_funccal->rettv->vval.v_number = 0; 18384 } 18385 } 18386 report_make_pending(CSTP_RETURN, rettv); 18387 } 18388 else 18389 { 18390 current_funccal->returned = TRUE; 18391 18392 /* If the return is carried out now, store the return value. For 18393 * a return immediately after reanimation, the value is already 18394 * there. */ 18395 if (!reanimate && rettv != NULL) 18396 { 18397 clear_tv(current_funccal->rettv); 18398 *current_funccal->rettv = *(typval_T *)rettv; 18399 if (!is_cmd) 18400 vim_free(rettv); 18401 } 18402 } 18403 18404 return idx < 0; 18405 } 18406 18407 /* 18408 * Free the variable with a pending return value. 18409 */ 18410 void 18411 discard_pending_return(rettv) 18412 void *rettv; 18413 { 18414 free_tv((typval_T *)rettv); 18415 } 18416 18417 /* 18418 * Generate a return command for producing the value of "rettv". The result 18419 * is an allocated string. Used by report_pending() for verbose messages. 18420 */ 18421 char_u * 18422 get_return_cmd(rettv) 18423 void *rettv; 18424 { 18425 char_u *s = NULL; 18426 char_u *tofree = NULL; 18427 char_u numbuf[NUMBUFLEN]; 18428 18429 if (rettv != NULL) 18430 s = echo_string((typval_T *)rettv, &tofree, numbuf); 18431 if (s == NULL) 18432 s = (char_u *)""; 18433 18434 STRCPY(IObuff, ":return "); 18435 STRNCPY(IObuff + 8, s, IOSIZE - 8); 18436 if (STRLEN(s) + 8 >= IOSIZE) 18437 STRCPY(IObuff + IOSIZE - 4, "..."); 18438 vim_free(tofree); 18439 return vim_strsave(IObuff); 18440 } 18441 18442 /* 18443 * Get next function line. 18444 * Called by do_cmdline() to get the next line. 18445 * Returns allocated string, or NULL for end of function. 18446 */ 18447 /* ARGSUSED */ 18448 char_u * 18449 get_func_line(c, cookie, indent) 18450 int c; /* not used */ 18451 void *cookie; 18452 int indent; /* not used */ 18453 { 18454 funccall_T *fcp = (funccall_T *)cookie; 18455 ufunc_T *fp = fcp->func; 18456 char_u *retval; 18457 garray_T *gap; /* growarray with function lines */ 18458 18459 /* If breakpoints have been added/deleted need to check for it. */ 18460 if (fcp->dbg_tick != debug_tick) 18461 { 18462 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18463 sourcing_lnum); 18464 fcp->dbg_tick = debug_tick; 18465 } 18466 #ifdef FEAT_PROFILE 18467 if (do_profiling) 18468 func_line_end(cookie); 18469 #endif 18470 18471 gap = &fp->uf_lines; 18472 if ((fp->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18473 retval = NULL; 18474 else if (fcp->returned || fcp->linenr >= gap->ga_len) 18475 retval = NULL; 18476 else 18477 { 18478 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 18479 sourcing_lnum = fcp->linenr; 18480 #ifdef FEAT_PROFILE 18481 if (do_profiling) 18482 func_line_start(cookie); 18483 #endif 18484 } 18485 18486 /* Did we encounter a breakpoint? */ 18487 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 18488 { 18489 dbg_breakpoint(fp->uf_name, sourcing_lnum); 18490 /* Find next breakpoint. */ 18491 fcp->breakpoint = dbg_find_breakpoint(FALSE, fp->uf_name, 18492 sourcing_lnum); 18493 fcp->dbg_tick = debug_tick; 18494 } 18495 18496 return retval; 18497 } 18498 18499 #if defined(FEAT_PROFILE) || defined(PROTO) 18500 /* 18501 * Called when starting to read a function line. 18502 * "sourcing_lnum" must be correct! 18503 * When skipping lines it may not actually be executed, but we won't find out 18504 * until later and we need to store the time now. 18505 */ 18506 void 18507 func_line_start(cookie) 18508 void *cookie; 18509 { 18510 funccall_T *fcp = (funccall_T *)cookie; 18511 ufunc_T *fp = fcp->func; 18512 18513 if (fp->uf_profiling && sourcing_lnum >= 1 18514 && sourcing_lnum <= fp->uf_lines.ga_len) 18515 { 18516 fp->uf_tml_idx = sourcing_lnum - 1; 18517 fp->uf_tml_execed = FALSE; 18518 profile_start(&fp->uf_tml_start); 18519 profile_zero(&fp->uf_tml_children); 18520 profile_get_wait(&fp->uf_tml_wait); 18521 } 18522 } 18523 18524 /* 18525 * Called when actually executing a function line. 18526 */ 18527 void 18528 func_line_exec(cookie) 18529 void *cookie; 18530 { 18531 funccall_T *fcp = (funccall_T *)cookie; 18532 ufunc_T *fp = fcp->func; 18533 18534 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18535 fp->uf_tml_execed = TRUE; 18536 } 18537 18538 /* 18539 * Called when done with a function line. 18540 */ 18541 void 18542 func_line_end(cookie) 18543 void *cookie; 18544 { 18545 funccall_T *fcp = (funccall_T *)cookie; 18546 ufunc_T *fp = fcp->func; 18547 18548 if (fp->uf_profiling && fp->uf_tml_idx >= 0) 18549 { 18550 if (fp->uf_tml_execed) 18551 { 18552 ++fp->uf_tml_count[fp->uf_tml_idx]; 18553 profile_end(&fp->uf_tml_start); 18554 profile_sub_wait(&fp->uf_tml_wait, &fp->uf_tml_start); 18555 profile_add(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_start); 18556 profile_add(&fp->uf_tml_total[fp->uf_tml_idx], &fp->uf_tml_start); 18557 profile_sub(&fp->uf_tml_self[fp->uf_tml_idx], &fp->uf_tml_children); 18558 } 18559 fp->uf_tml_idx = -1; 18560 } 18561 } 18562 #endif 18563 18564 /* 18565 * Return TRUE if the currently active function should be ended, because a 18566 * return was encountered or an error occured. Used inside a ":while". 18567 */ 18568 int 18569 func_has_ended(cookie) 18570 void *cookie; 18571 { 18572 funccall_T *fcp = (funccall_T *)cookie; 18573 18574 /* Ignore the "abort" flag if the abortion behavior has been changed due to 18575 * an error inside a try conditional. */ 18576 return (((fcp->func->uf_flags & FC_ABORT) && did_emsg && !aborted_in_try()) 18577 || fcp->returned); 18578 } 18579 18580 /* 18581 * return TRUE if cookie indicates a function which "abort"s on errors. 18582 */ 18583 int 18584 func_has_abort(cookie) 18585 void *cookie; 18586 { 18587 return ((funccall_T *)cookie)->func->uf_flags & FC_ABORT; 18588 } 18589 18590 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 18591 typedef enum 18592 { 18593 VAR_FLAVOUR_DEFAULT, 18594 VAR_FLAVOUR_SESSION, 18595 VAR_FLAVOUR_VIMINFO 18596 } var_flavour_T; 18597 18598 static var_flavour_T var_flavour __ARGS((char_u *varname)); 18599 18600 static var_flavour_T 18601 var_flavour(varname) 18602 char_u *varname; 18603 { 18604 char_u *p = varname; 18605 18606 if (ASCII_ISUPPER(*p)) 18607 { 18608 while (*(++p)) 18609 if (ASCII_ISLOWER(*p)) 18610 return VAR_FLAVOUR_SESSION; 18611 return VAR_FLAVOUR_VIMINFO; 18612 } 18613 else 18614 return VAR_FLAVOUR_DEFAULT; 18615 } 18616 #endif 18617 18618 #if defined(FEAT_VIMINFO) || defined(PROTO) 18619 /* 18620 * Restore global vars that start with a capital from the viminfo file 18621 */ 18622 int 18623 read_viminfo_varlist(virp, writing) 18624 vir_T *virp; 18625 int writing; 18626 { 18627 char_u *tab; 18628 int is_string = FALSE; 18629 typval_T tv; 18630 18631 if (!writing && (find_viminfo_parameter('!') != NULL)) 18632 { 18633 tab = vim_strchr(virp->vir_line + 1, '\t'); 18634 if (tab != NULL) 18635 { 18636 *tab++ = '\0'; /* isolate the variable name */ 18637 if (*tab == 'S') /* string var */ 18638 is_string = TRUE; 18639 18640 tab = vim_strchr(tab, '\t'); 18641 if (tab != NULL) 18642 { 18643 if (is_string) 18644 { 18645 tv.v_type = VAR_STRING; 18646 tv.vval.v_string = viminfo_readstring(virp, 18647 (int)(tab - virp->vir_line + 1), TRUE); 18648 } 18649 else 18650 { 18651 tv.v_type = VAR_NUMBER; 18652 tv.vval.v_number = atol((char *)tab + 1); 18653 } 18654 set_var(virp->vir_line + 1, &tv, FALSE); 18655 if (is_string) 18656 vim_free(tv.vval.v_string); 18657 } 18658 } 18659 } 18660 18661 return viminfo_readline(virp); 18662 } 18663 18664 /* 18665 * Write global vars that start with a capital to the viminfo file 18666 */ 18667 void 18668 write_viminfo_varlist(fp) 18669 FILE *fp; 18670 { 18671 hashitem_T *hi; 18672 dictitem_T *this_var; 18673 int todo; 18674 char *s; 18675 char_u *p; 18676 char_u *tofree; 18677 char_u numbuf[NUMBUFLEN]; 18678 18679 if (find_viminfo_parameter('!') == NULL) 18680 return; 18681 18682 fprintf(fp, _("\n# global variables:\n")); 18683 18684 todo = globvarht.ht_used; 18685 for (hi = globvarht.ht_array; todo > 0; ++hi) 18686 { 18687 if (!HASHITEM_EMPTY(hi)) 18688 { 18689 --todo; 18690 this_var = HI2DI(hi); 18691 if (var_flavour(this_var->di_key) == VAR_FLAVOUR_VIMINFO) 18692 { 18693 switch (this_var->di_tv.v_type) 18694 { 18695 case VAR_STRING: s = "STR"; break; 18696 case VAR_NUMBER: s = "NUM"; break; 18697 default: continue; 18698 } 18699 fprintf(fp, "!%s\t%s\t", this_var->di_key, s); 18700 p = echo_string(&this_var->di_tv, &tofree, numbuf); 18701 if (p != NULL) 18702 viminfo_writestring(fp, p); 18703 vim_free(tofree); 18704 } 18705 } 18706 } 18707 } 18708 #endif 18709 18710 #if defined(FEAT_SESSION) || defined(PROTO) 18711 int 18712 store_session_globals(fd) 18713 FILE *fd; 18714 { 18715 hashitem_T *hi; 18716 dictitem_T *this_var; 18717 int todo; 18718 char_u *p, *t; 18719 18720 todo = globvarht.ht_used; 18721 for (hi = globvarht.ht_array; todo > 0; ++hi) 18722 { 18723 if (!HASHITEM_EMPTY(hi)) 18724 { 18725 --todo; 18726 this_var = HI2DI(hi); 18727 if ((this_var->di_tv.v_type == VAR_NUMBER 18728 || this_var->di_tv.v_type == VAR_STRING) 18729 && var_flavour(this_var->di_key) == VAR_FLAVOUR_SESSION) 18730 { 18731 /* Escape special characters with a backslash. Turn a LF and 18732 * CR into \n and \r. */ 18733 p = vim_strsave_escaped(get_tv_string(&this_var->di_tv), 18734 (char_u *)"\\\"\n\r"); 18735 if (p == NULL) /* out of memory */ 18736 break; 18737 for (t = p; *t != NUL; ++t) 18738 if (*t == '\n') 18739 *t = 'n'; 18740 else if (*t == '\r') 18741 *t = 'r'; 18742 if ((fprintf(fd, "let %s = %c%s%c", 18743 this_var->di_key, 18744 (this_var->di_tv.v_type == VAR_STRING) ? '"' 18745 : ' ', 18746 p, 18747 (this_var->di_tv.v_type == VAR_STRING) ? '"' 18748 : ' ') < 0) 18749 || put_eol(fd) == FAIL) 18750 { 18751 vim_free(p); 18752 return FAIL; 18753 } 18754 vim_free(p); 18755 } 18756 } 18757 } 18758 return OK; 18759 } 18760 #endif 18761 18762 /* 18763 * Display script name where an item was last set. 18764 * Should only be invoked when 'verbose' is non-zero. 18765 */ 18766 void 18767 last_set_msg(scriptID) 18768 scid_T scriptID; 18769 { 18770 if (scriptID != 0) 18771 { 18772 verbose_enter(); 18773 MSG_PUTS(_("\n\tLast set from ")); 18774 MSG_PUTS(get_scriptname(scriptID)); 18775 verbose_leave(); 18776 } 18777 } 18778 18779 #endif /* FEAT_EVAL */ 18780 18781 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 18782 18783 18784 #ifdef WIN3264 18785 /* 18786 * Functions for ":8" filename modifier: get 8.3 version of a filename. 18787 */ 18788 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 18789 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 18790 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 18791 18792 /* 18793 * Get the short pathname of a file. 18794 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 18795 */ 18796 static int 18797 get_short_pathname(fnamep, bufp, fnamelen) 18798 char_u **fnamep; 18799 char_u **bufp; 18800 int *fnamelen; 18801 { 18802 int l,len; 18803 char_u *newbuf; 18804 18805 len = *fnamelen; 18806 18807 l = GetShortPathName(*fnamep, *fnamep, len); 18808 if (l > len - 1) 18809 { 18810 /* If that doesn't work (not enough space), then save the string 18811 * and try again with a new buffer big enough 18812 */ 18813 newbuf = vim_strnsave(*fnamep, l); 18814 if (newbuf == NULL) 18815 return 0; 18816 18817 vim_free(*bufp); 18818 *fnamep = *bufp = newbuf; 18819 18820 l = GetShortPathName(*fnamep,*fnamep,l+1); 18821 18822 /* Really should always succeed, as the buffer is big enough */ 18823 } 18824 18825 *fnamelen = l; 18826 return 1; 18827 } 18828 18829 /* 18830 * Create a short path name. Returns the length of the buffer it needs. 18831 * Doesn't copy over the end of the buffer passed in. 18832 */ 18833 static int 18834 shortpath_for_invalid_fname(fname, bufp, fnamelen) 18835 char_u **fname; 18836 char_u **bufp; 18837 int *fnamelen; 18838 { 18839 char_u *s, *p, *pbuf2, *pbuf3; 18840 char_u ch; 18841 int len, len2, plen, slen; 18842 18843 /* Make a copy */ 18844 len2 = *fnamelen; 18845 pbuf2 = vim_strnsave(*fname, len2); 18846 pbuf3 = NULL; 18847 18848 s = pbuf2 + len2 - 1; /* Find the end */ 18849 slen = 1; 18850 plen = len2; 18851 18852 if (after_pathsep(pbuf2, s + 1)) 18853 { 18854 --s; 18855 ++slen; 18856 --plen; 18857 } 18858 18859 do 18860 { 18861 /* Go back one path-seperator */ 18862 while (s > pbuf2 && !after_pathsep(pbuf2, s + 1)) 18863 { 18864 --s; 18865 ++slen; 18866 --plen; 18867 } 18868 if (s <= pbuf2) 18869 break; 18870 18871 /* Remeber the character that is about to be blatted */ 18872 ch = *s; 18873 *s = 0; /* get_short_pathname requires a null-terminated string */ 18874 18875 /* Try it in situ */ 18876 p = pbuf2; 18877 if (!get_short_pathname(&p, &pbuf3, &plen)) 18878 { 18879 vim_free(pbuf2); 18880 return -1; 18881 } 18882 *s = ch; /* Preserve the string */ 18883 } while (plen == 0); 18884 18885 if (plen > 0) 18886 { 18887 /* Remeber the length of the new string. */ 18888 *fnamelen = len = plen + slen; 18889 vim_free(*bufp); 18890 if (len > len2) 18891 { 18892 /* If there's not enough space in the currently allocated string, 18893 * then copy it to a buffer big enough. 18894 */ 18895 *fname= *bufp = vim_strnsave(p, len); 18896 if (*fname == NULL) 18897 return -1; 18898 } 18899 else 18900 { 18901 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 18902 *fname = *bufp = pbuf2; 18903 if (p != pbuf2) 18904 strncpy(*fname, p, plen); 18905 pbuf2 = NULL; 18906 } 18907 /* Concat the next bit */ 18908 strncpy(*fname + plen, s, slen); 18909 (*fname)[len] = '\0'; 18910 } 18911 vim_free(pbuf3); 18912 vim_free(pbuf2); 18913 return 0; 18914 } 18915 18916 /* 18917 * Get a pathname for a partial path. 18918 */ 18919 static int 18920 shortpath_for_partial(fnamep, bufp, fnamelen) 18921 char_u **fnamep; 18922 char_u **bufp; 18923 int *fnamelen; 18924 { 18925 int sepcount, len, tflen; 18926 char_u *p; 18927 char_u *pbuf, *tfname; 18928 int hasTilde; 18929 18930 /* Count up the path seperators from the RHS.. so we know which part 18931 * of the path to return. 18932 */ 18933 sepcount = 0; 18934 for (p = *fnamep; p < *fnamep + *fnamelen; mb_ptr_adv(p)) 18935 if (vim_ispathsep(*p)) 18936 ++sepcount; 18937 18938 /* Need full path first (use expand_env() to remove a "~/") */ 18939 hasTilde = (**fnamep == '~'); 18940 if (hasTilde) 18941 pbuf = tfname = expand_env_save(*fnamep); 18942 else 18943 pbuf = tfname = FullName_save(*fnamep, FALSE); 18944 18945 len = tflen = STRLEN(tfname); 18946 18947 if (!get_short_pathname(&tfname, &pbuf, &len)) 18948 return -1; 18949 18950 if (len == 0) 18951 { 18952 /* Don't have a valid filename, so shorten the rest of the 18953 * path if we can. This CAN give us invalid 8.3 filenames, but 18954 * there's not a lot of point in guessing what it might be. 18955 */ 18956 len = tflen; 18957 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 18958 return -1; 18959 } 18960 18961 /* Count the paths backward to find the beginning of the desired string. */ 18962 for (p = tfname + len - 1; p >= tfname; --p) 18963 { 18964 #ifdef FEAT_MBYTE 18965 if (has_mbyte) 18966 p -= mb_head_off(tfname, p); 18967 #endif 18968 if (vim_ispathsep(*p)) 18969 { 18970 if (sepcount == 0 || (hasTilde && sepcount == 1)) 18971 break; 18972 else 18973 sepcount --; 18974 } 18975 } 18976 if (hasTilde) 18977 { 18978 --p; 18979 if (p >= tfname) 18980 *p = '~'; 18981 else 18982 return -1; 18983 } 18984 else 18985 ++p; 18986 18987 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 18988 vim_free(*bufp); 18989 *fnamelen = (int)STRLEN(p); 18990 *bufp = pbuf; 18991 *fnamep = p; 18992 18993 return 0; 18994 } 18995 #endif /* WIN3264 */ 18996 18997 /* 18998 * Adjust a filename, according to a string of modifiers. 18999 * *fnamep must be NUL terminated when called. When returning, the length is 19000 * determined by *fnamelen. 19001 * Returns valid flags. 19002 * When there is an error, *fnamep is set to NULL. 19003 */ 19004 int 19005 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 19006 char_u *src; /* string with modifiers */ 19007 int *usedlen; /* characters after src that are used */ 19008 char_u **fnamep; /* file name so far */ 19009 char_u **bufp; /* buffer for allocated file name or NULL */ 19010 int *fnamelen; /* length of fnamep */ 19011 { 19012 int valid = 0; 19013 char_u *tail; 19014 char_u *s, *p, *pbuf; 19015 char_u dirname[MAXPATHL]; 19016 int c; 19017 int has_fullname = 0; 19018 #ifdef WIN3264 19019 int has_shortname = 0; 19020 #endif 19021 19022 repeat: 19023 /* ":p" - full path/file_name */ 19024 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 19025 { 19026 has_fullname = 1; 19027 19028 valid |= VALID_PATH; 19029 *usedlen += 2; 19030 19031 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 19032 if ((*fnamep)[0] == '~' 19033 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 19034 && ((*fnamep)[1] == '/' 19035 # ifdef BACKSLASH_IN_FILENAME 19036 || (*fnamep)[1] == '\\' 19037 # endif 19038 || (*fnamep)[1] == NUL) 19039 19040 #endif 19041 ) 19042 { 19043 *fnamep = expand_env_save(*fnamep); 19044 vim_free(*bufp); /* free any allocated file name */ 19045 *bufp = *fnamep; 19046 if (*fnamep == NULL) 19047 return -1; 19048 } 19049 19050 /* When "/." or "/.." is used: force expansion to get rid of it. */ 19051 for (p = *fnamep; *p != NUL; mb_ptr_adv(p)) 19052 { 19053 if (vim_ispathsep(*p) 19054 && p[1] == '.' 19055 && (p[2] == NUL 19056 || vim_ispathsep(p[2]) 19057 || (p[2] == '.' 19058 && (p[3] == NUL || vim_ispathsep(p[3]))))) 19059 break; 19060 } 19061 19062 /* FullName_save() is slow, don't use it when not needed. */ 19063 if (*p != NUL || !vim_isAbsName(*fnamep)) 19064 { 19065 *fnamep = FullName_save(*fnamep, *p != NUL); 19066 vim_free(*bufp); /* free any allocated file name */ 19067 *bufp = *fnamep; 19068 if (*fnamep == NULL) 19069 return -1; 19070 } 19071 19072 /* Append a path separator to a directory. */ 19073 if (mch_isdir(*fnamep)) 19074 { 19075 /* Make room for one or two extra characters. */ 19076 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 19077 vim_free(*bufp); /* free any allocated file name */ 19078 *bufp = *fnamep; 19079 if (*fnamep == NULL) 19080 return -1; 19081 add_pathsep(*fnamep); 19082 } 19083 } 19084 19085 /* ":." - path relative to the current directory */ 19086 /* ":~" - path relative to the home directory */ 19087 /* ":8" - shortname path - postponed till after */ 19088 while (src[*usedlen] == ':' 19089 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 19090 { 19091 *usedlen += 2; 19092 if (c == '8') 19093 { 19094 #ifdef WIN3264 19095 has_shortname = 1; /* Postpone this. */ 19096 #endif 19097 continue; 19098 } 19099 pbuf = NULL; 19100 /* Need full path first (use expand_env() to remove a "~/") */ 19101 if (!has_fullname) 19102 { 19103 if (c == '.' && **fnamep == '~') 19104 p = pbuf = expand_env_save(*fnamep); 19105 else 19106 p = pbuf = FullName_save(*fnamep, FALSE); 19107 } 19108 else 19109 p = *fnamep; 19110 19111 has_fullname = 0; 19112 19113 if (p != NULL) 19114 { 19115 if (c == '.') 19116 { 19117 mch_dirname(dirname, MAXPATHL); 19118 s = shorten_fname(p, dirname); 19119 if (s != NULL) 19120 { 19121 *fnamep = s; 19122 if (pbuf != NULL) 19123 { 19124 vim_free(*bufp); /* free any allocated file name */ 19125 *bufp = pbuf; 19126 pbuf = NULL; 19127 } 19128 } 19129 } 19130 else 19131 { 19132 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 19133 /* Only replace it when it starts with '~' */ 19134 if (*dirname == '~') 19135 { 19136 s = vim_strsave(dirname); 19137 if (s != NULL) 19138 { 19139 *fnamep = s; 19140 vim_free(*bufp); 19141 *bufp = s; 19142 } 19143 } 19144 } 19145 vim_free(pbuf); 19146 } 19147 } 19148 19149 tail = gettail(*fnamep); 19150 *fnamelen = (int)STRLEN(*fnamep); 19151 19152 /* ":h" - head, remove "/file_name", can be repeated */ 19153 /* Don't remove the first "/" or "c:\" */ 19154 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 19155 { 19156 valid |= VALID_HEAD; 19157 *usedlen += 2; 19158 s = get_past_head(*fnamep); 19159 while (tail > s && after_pathsep(s, tail)) 19160 --tail; 19161 *fnamelen = (int)(tail - *fnamep); 19162 #ifdef VMS 19163 if (*fnamelen > 0) 19164 *fnamelen += 1; /* the path separator is part of the path */ 19165 #endif 19166 while (tail > s && !after_pathsep(s, tail)) 19167 mb_ptr_back(*fnamep, tail); 19168 } 19169 19170 /* ":8" - shortname */ 19171 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 19172 { 19173 *usedlen += 2; 19174 #ifdef WIN3264 19175 has_shortname = 1; 19176 #endif 19177 } 19178 19179 #ifdef WIN3264 19180 /* Check shortname after we have done 'heads' and before we do 'tails' 19181 */ 19182 if (has_shortname) 19183 { 19184 pbuf = NULL; 19185 /* Copy the string if it is shortened by :h */ 19186 if (*fnamelen < (int)STRLEN(*fnamep)) 19187 { 19188 p = vim_strnsave(*fnamep, *fnamelen); 19189 if (p == 0) 19190 return -1; 19191 vim_free(*bufp); 19192 *bufp = *fnamep = p; 19193 } 19194 19195 /* Split into two implementations - makes it easier. First is where 19196 * there isn't a full name already, second is where there is. 19197 */ 19198 if (!has_fullname && !vim_isAbsName(*fnamep)) 19199 { 19200 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 19201 return -1; 19202 } 19203 else 19204 { 19205 int l; 19206 19207 /* Simple case, already have the full-name 19208 * Nearly always shorter, so try first time. */ 19209 l = *fnamelen; 19210 if (!get_short_pathname(fnamep, bufp, &l)) 19211 return -1; 19212 19213 if (l == 0) 19214 { 19215 /* Couldn't find the filename.. search the paths. 19216 */ 19217 l = *fnamelen; 19218 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 19219 return -1; 19220 } 19221 *fnamelen = l; 19222 } 19223 } 19224 #endif /* WIN3264 */ 19225 19226 /* ":t" - tail, just the basename */ 19227 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 19228 { 19229 *usedlen += 2; 19230 *fnamelen -= (int)(tail - *fnamep); 19231 *fnamep = tail; 19232 } 19233 19234 /* ":e" - extension, can be repeated */ 19235 /* ":r" - root, without extension, can be repeated */ 19236 while (src[*usedlen] == ':' 19237 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 19238 { 19239 /* find a '.' in the tail: 19240 * - for second :e: before the current fname 19241 * - otherwise: The last '.' 19242 */ 19243 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 19244 s = *fnamep - 2; 19245 else 19246 s = *fnamep + *fnamelen - 1; 19247 for ( ; s > tail; --s) 19248 if (s[0] == '.') 19249 break; 19250 if (src[*usedlen + 1] == 'e') /* :e */ 19251 { 19252 if (s > tail) 19253 { 19254 *fnamelen += (int)(*fnamep - (s + 1)); 19255 *fnamep = s + 1; 19256 #ifdef VMS 19257 /* cut version from the extension */ 19258 s = *fnamep + *fnamelen - 1; 19259 for ( ; s > *fnamep; --s) 19260 if (s[0] == ';') 19261 break; 19262 if (s > *fnamep) 19263 *fnamelen = s - *fnamep; 19264 #endif 19265 } 19266 else if (*fnamep <= tail) 19267 *fnamelen = 0; 19268 } 19269 else /* :r */ 19270 { 19271 if (s > tail) /* remove one extension */ 19272 *fnamelen = (int)(s - *fnamep); 19273 } 19274 *usedlen += 2; 19275 } 19276 19277 /* ":s?pat?foo?" - substitute */ 19278 /* ":gs?pat?foo?" - global substitute */ 19279 if (src[*usedlen] == ':' 19280 && (src[*usedlen + 1] == 's' 19281 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 19282 { 19283 char_u *str; 19284 char_u *pat; 19285 char_u *sub; 19286 int sep; 19287 char_u *flags; 19288 int didit = FALSE; 19289 19290 flags = (char_u *)""; 19291 s = src + *usedlen + 2; 19292 if (src[*usedlen + 1] == 'g') 19293 { 19294 flags = (char_u *)"g"; 19295 ++s; 19296 } 19297 19298 sep = *s++; 19299 if (sep) 19300 { 19301 /* find end of pattern */ 19302 p = vim_strchr(s, sep); 19303 if (p != NULL) 19304 { 19305 pat = vim_strnsave(s, (int)(p - s)); 19306 if (pat != NULL) 19307 { 19308 s = p + 1; 19309 /* find end of substitution */ 19310 p = vim_strchr(s, sep); 19311 if (p != NULL) 19312 { 19313 sub = vim_strnsave(s, (int)(p - s)); 19314 str = vim_strnsave(*fnamep, *fnamelen); 19315 if (sub != NULL && str != NULL) 19316 { 19317 *usedlen = (int)(p + 1 - src); 19318 s = do_string_sub(str, pat, sub, flags); 19319 if (s != NULL) 19320 { 19321 *fnamep = s; 19322 *fnamelen = (int)STRLEN(s); 19323 vim_free(*bufp); 19324 *bufp = s; 19325 didit = TRUE; 19326 } 19327 } 19328 vim_free(sub); 19329 vim_free(str); 19330 } 19331 vim_free(pat); 19332 } 19333 } 19334 /* after using ":s", repeat all the modifiers */ 19335 if (didit) 19336 goto repeat; 19337 } 19338 } 19339 19340 return valid; 19341 } 19342 19343 /* 19344 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 19345 * "flags" can be "g" to do a global substitute. 19346 * Returns an allocated string, NULL for error. 19347 */ 19348 char_u * 19349 do_string_sub(str, pat, sub, flags) 19350 char_u *str; 19351 char_u *pat; 19352 char_u *sub; 19353 char_u *flags; 19354 { 19355 int sublen; 19356 regmatch_T regmatch; 19357 int i; 19358 int do_all; 19359 char_u *tail; 19360 garray_T ga; 19361 char_u *ret; 19362 char_u *save_cpo; 19363 19364 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 19365 save_cpo = p_cpo; 19366 p_cpo = (char_u *)""; 19367 19368 ga_init2(&ga, 1, 200); 19369 19370 do_all = (flags[0] == 'g'); 19371 19372 regmatch.rm_ic = p_ic; 19373 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 19374 if (regmatch.regprog != NULL) 19375 { 19376 tail = str; 19377 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 19378 { 19379 /* 19380 * Get some space for a temporary buffer to do the substitution 19381 * into. It will contain: 19382 * - The text up to where the match is. 19383 * - The substituted text. 19384 * - The text after the match. 19385 */ 19386 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 19387 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 19388 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 19389 { 19390 ga_clear(&ga); 19391 break; 19392 } 19393 19394 /* copy the text up to where the match is */ 19395 i = (int)(regmatch.startp[0] - tail); 19396 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 19397 /* add the substituted text */ 19398 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 19399 + ga.ga_len + i, TRUE, TRUE, FALSE); 19400 ga.ga_len += i + sublen - 1; 19401 /* avoid getting stuck on a match with an empty string */ 19402 if (tail == regmatch.endp[0]) 19403 { 19404 if (*tail == NUL) 19405 break; 19406 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 19407 ++ga.ga_len; 19408 } 19409 else 19410 { 19411 tail = regmatch.endp[0]; 19412 if (*tail == NUL) 19413 break; 19414 } 19415 if (!do_all) 19416 break; 19417 } 19418 19419 if (ga.ga_data != NULL) 19420 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 19421 19422 vim_free(regmatch.regprog); 19423 } 19424 19425 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 19426 ga_clear(&ga); 19427 p_cpo = save_cpo; 19428 19429 return ret; 19430 } 19431 19432 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 19433