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 #if SIZEOF_INT <= 3 /* use long if int is smaller than 32 bits */ 34 typedef long varnumber_T; 35 #else 36 typedef int varnumber_T; 37 #endif 38 39 /* 40 * Structure to hold an internal variable. 41 */ 42 typedef struct 43 { 44 char_u *var_name; /* name of variable */ 45 char var_type; /* VAR_NUMBER or VAR_STRING */ 46 union 47 { 48 varnumber_T var_number; /* number value */ 49 char_u *var_string; /* string value (Careful: can be NULL!) */ 50 } var_val; 51 } var; 52 53 #define VAR_UNKNOWN 0 54 #define VAR_NUMBER 1 55 #define VAR_STRING 2 56 57 typedef var * VAR; 58 59 /* 60 * All user-defined global variables are stored in "variables". 61 */ 62 garray_T variables = {0, 0, sizeof(var), 4, NULL}; 63 64 /* 65 * Array to hold an array with variables local to each sourced script. 66 */ 67 static garray_T ga_scripts = {0, 0, sizeof(garray_T), 4, NULL}; 68 #define SCRIPT_VARS(id) (((garray_T *)ga_scripts.ga_data)[(id) - 1]) 69 70 71 #define VAR_ENTRY(idx) (((VAR)(variables.ga_data))[idx]) 72 #define VAR_GAP_ENTRY(idx, gap) (((VAR)(gap->ga_data))[idx]) 73 #define BVAR_ENTRY(idx) (((VAR)(curbuf->b_vars.ga_data))[idx]) 74 #define WVAR_ENTRY(idx) (((VAR)(curwin->w_vars.ga_data))[idx]) 75 76 static int echo_attr = 0; /* attributes used for ":echo" */ 77 78 /* 79 * Structure to hold info for a user function. 80 */ 81 typedef struct ufunc ufunc_T; 82 83 struct ufunc 84 { 85 ufunc_T *next; /* next function in list */ 86 char_u *name; /* name of function; can start with <SNR>123_ 87 (<SNR> is K_SPECIAL KS_EXTRA KE_SNR) */ 88 int varargs; /* variable nr of arguments */ 89 int flags; 90 int calls; /* nr of active calls */ 91 garray_T args; /* arguments */ 92 garray_T lines; /* function lines */ 93 scid_T script_ID; /* ID of script where function was defined, 94 used for s: variables */ 95 }; 96 97 /* function flags */ 98 #define FC_ABORT 1 /* abort function on error */ 99 #define FC_RANGE 2 /* function accepts range */ 100 101 /* 102 * All user-defined functions are found in the forward-linked function list. 103 * The first function is pointed at by firstfunc. 104 */ 105 ufunc_T *firstfunc = NULL; 106 107 #define FUNCARG(fp, j) ((char_u **)(fp->args.ga_data))[j] 108 #define FUNCLINE(fp, j) ((char_u **)(fp->lines.ga_data))[j] 109 110 /* structure to hold info for a function that is currently being executed. */ 111 struct funccall 112 { 113 ufunc_T *func; /* function being called */ 114 int linenr; /* next line to be executed */ 115 int returned; /* ":return" used */ 116 int argcount; /* nr of arguments */ 117 VAR argvars; /* arguments */ 118 var a0_var; /* "a:0" variable */ 119 var firstline; /* "a:firstline" variable */ 120 var lastline; /* "a:lastline" variable */ 121 garray_T l_vars; /* local function variables */ 122 VAR retvar; /* return value variable */ 123 linenr_T breakpoint; /* next line with breakpoint or zero */ 124 int dbg_tick; /* debug_tick when breakpoint was set */ 125 int level; /* top nesting level of executed function */ 126 }; 127 128 /* 129 * Return the name of the executed function. 130 */ 131 char_u * 132 func_name(cookie) 133 void *cookie; 134 { 135 return ((struct funccall *)cookie)->func->name; 136 } 137 138 /* 139 * Return the address holding the next breakpoint line for a funccall cookie. 140 */ 141 linenr_T * 142 func_breakpoint(cookie) 143 void *cookie; 144 { 145 return &((struct funccall *)cookie)->breakpoint; 146 } 147 148 /* 149 * Return the address holding the debug tick for a funccall cookie. 150 */ 151 int * 152 func_dbg_tick(cookie) 153 void *cookie; 154 { 155 return &((struct funccall *)cookie)->dbg_tick; 156 } 157 158 /* 159 * Return the nesting level for a funccall cookie. 160 */ 161 int 162 func_level(cookie) 163 void *cookie; 164 { 165 return ((struct funccall *)cookie)->level; 166 } 167 168 /* pointer to funccal for currently active function */ 169 struct funccall *current_funccal = NULL; 170 171 /* 172 * Return TRUE when a function was ended by a ":return" command. 173 */ 174 int 175 current_func_returned() 176 { 177 return current_funccal->returned; 178 } 179 180 181 /* 182 * Array to hold the value of v: variables. 183 */ 184 #include "version.h" 185 186 /* values for flags: */ 187 #define VV_COMPAT 1 /* compatible, also used without "v:" */ 188 #define VV_RO 2 /* read-only */ 189 190 struct vimvar 191 { 192 char *name; /* name of variable, without v: */ 193 int len; /* length of name */ 194 char_u *val; /* current value (can also be a number!) */ 195 char type; /* VAR_NUMBER or VAR_STRING */ 196 char flags; /* VV_COMPAT and VV_RO */ 197 } vimvars[VV_LEN] = 198 { /* The order here must match the VV_ defines in vim.h! */ 199 {"count", sizeof("count") - 1, NULL, VAR_NUMBER, VV_COMPAT+VV_RO}, 200 {"count1", sizeof("count1") - 1, NULL, VAR_NUMBER, VV_RO}, 201 {"prevcount", sizeof("prevcount") - 1, NULL, VAR_NUMBER, VV_RO}, 202 {"errmsg", sizeof("errmsg") - 1, NULL, VAR_STRING, VV_COMPAT}, 203 {"warningmsg", sizeof("warningmsg") - 1, NULL, VAR_STRING, 0}, 204 {"statusmsg", sizeof("statusmsg") - 1, NULL, VAR_STRING, 0}, 205 {"shell_error", sizeof("shell_error") - 1, NULL, VAR_NUMBER, 206 VV_COMPAT+VV_RO}, 207 {"this_session", sizeof("this_session") - 1, NULL, VAR_STRING, VV_COMPAT}, 208 {"version", sizeof("version") - 1, (char_u *)VIM_VERSION_100, 209 VAR_NUMBER, VV_COMPAT+VV_RO}, 210 {"lnum", sizeof("lnum") - 1, NULL, VAR_NUMBER, VV_RO}, 211 {"termresponse", sizeof("termresponse") - 1, NULL, VAR_STRING, VV_RO}, 212 {"fname", sizeof("fname") - 1, NULL, VAR_STRING, VV_RO}, 213 {"lang", sizeof("lang") - 1, NULL, VAR_STRING, VV_RO}, 214 {"lc_time", sizeof("lc_time") - 1, NULL, VAR_STRING, VV_RO}, 215 {"ctype", sizeof("ctype") - 1, NULL, VAR_STRING, VV_RO}, 216 {"charconvert_from", sizeof("charconvert_from") - 1, NULL, VAR_STRING, VV_RO}, 217 {"charconvert_to", sizeof("charconvert_to") - 1, NULL, VAR_STRING, VV_RO}, 218 {"fname_in", sizeof("fname_in") - 1, NULL, VAR_STRING, VV_RO}, 219 {"fname_out", sizeof("fname_out") - 1, NULL, VAR_STRING, VV_RO}, 220 {"fname_new", sizeof("fname_new") - 1, NULL, VAR_STRING, VV_RO}, 221 {"fname_diff", sizeof("fname_diff") - 1, NULL, VAR_STRING, VV_RO}, 222 {"cmdarg", sizeof("cmdarg") - 1, NULL, VAR_STRING, VV_RO}, 223 {"foldstart", sizeof("foldstart") - 1, NULL, VAR_NUMBER, VV_RO}, 224 {"foldend", sizeof("foldend") - 1, NULL, VAR_NUMBER, VV_RO}, 225 {"folddashes", sizeof("folddashes") - 1, NULL, VAR_STRING, VV_RO}, 226 {"foldlevel", sizeof("foldlevel") - 1, NULL, VAR_NUMBER, VV_RO}, 227 {"progname", sizeof("progname") - 1, NULL, VAR_STRING, VV_RO}, 228 {"servername", sizeof("servername") - 1, NULL, VAR_STRING, VV_RO}, 229 {"dying", sizeof("dying") - 1, NULL, VAR_NUMBER, VV_RO}, 230 {"exception", sizeof("exception") - 1, NULL, VAR_STRING, VV_RO}, 231 {"throwpoint", sizeof("throwpoint") - 1, NULL, VAR_STRING, VV_RO}, 232 {"register", sizeof("register") - 1, NULL, VAR_STRING, VV_RO}, 233 {"cmdbang", sizeof("cmdbang") - 1, NULL, VAR_NUMBER, VV_RO}, 234 }; 235 236 static int eval0 __ARGS((char_u *arg, VAR retvar, char_u **nextcmd, int evaluate)); 237 static int eval1 __ARGS((char_u **arg, VAR retvar, int evaluate)); 238 static int eval2 __ARGS((char_u **arg, VAR retvar, int evaluate)); 239 static int eval3 __ARGS((char_u **arg, VAR retvar, int evaluate)); 240 static int eval4 __ARGS((char_u **arg, VAR retvar, int evaluate)); 241 static int eval5 __ARGS((char_u **arg, VAR retvar, int evaluate)); 242 static int eval6 __ARGS((char_u **arg, VAR retvar, int evaluate)); 243 static int eval7 __ARGS((char_u **arg, VAR retvar, int evaluate)); 244 static int get_option_var __ARGS((char_u **arg, VAR retvar, int evaluate)); 245 static int get_string_var __ARGS((char_u **arg, VAR retvar, int evaluate)); 246 static int get_lit_string_var __ARGS((char_u **arg, VAR retvar, int evaluate)); 247 static int get_env_var __ARGS((char_u **arg, VAR retvar, int evaluate)); 248 static int find_internal_func __ARGS((char_u *name)); 249 static int get_func_var __ARGS((char_u *name, int len, VAR retvar, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); 250 static int call_func __ARGS((char_u *name, int len, VAR retvar, int argcount, VAR argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); 251 static void f_append __ARGS((VAR argvars, VAR retvar)); 252 static void f_argc __ARGS((VAR argvars, VAR retvar)); 253 static void f_argidx __ARGS((VAR argvars, VAR retvar)); 254 static void f_argv __ARGS((VAR argvars, VAR retvar)); 255 static void f_browse __ARGS((VAR argvars, VAR retvar)); 256 static buf_T *find_buffer __ARGS((VAR avar)); 257 static void f_bufexists __ARGS((VAR argvars, VAR retvar)); 258 static void f_buflisted __ARGS((VAR argvars, VAR retvar)); 259 static void f_bufloaded __ARGS((VAR argvars, VAR retvar)); 260 static buf_T *get_buf_var __ARGS((VAR avar)); 261 static void f_bufname __ARGS((VAR argvars, VAR retvar)); 262 static void f_bufnr __ARGS((VAR argvars, VAR retvar)); 263 static void f_bufwinnr __ARGS((VAR argvars, VAR retvar)); 264 static void f_byte2line __ARGS((VAR argvars, VAR retvar)); 265 static void f_char2nr __ARGS((VAR argvars, VAR retvar)); 266 static void f_cindent __ARGS((VAR argvars, VAR retvar)); 267 static void f_col __ARGS((VAR argvars, VAR retvar)); 268 static void f_confirm __ARGS((VAR argvars, VAR retvar)); 269 static void f_cscope_connection __ARGS((VAR argvars, VAR retvar)); 270 static void f_cursor __ARGS((VAR argsvars, VAR retvar)); 271 static void f_delete __ARGS((VAR argvars, VAR retvar)); 272 static void f_did_filetype __ARGS((VAR argvars, VAR retvar)); 273 static void f_escape __ARGS((VAR argvars, VAR retvar)); 274 static void f_eventhandler __ARGS((VAR argvars, VAR retvar)); 275 static void f_executable __ARGS((VAR argvars, VAR retvar)); 276 static void f_exists __ARGS((VAR argvars, VAR retvar)); 277 static void f_expand __ARGS((VAR argvars, VAR retvar)); 278 static void f_filereadable __ARGS((VAR argvars, VAR retvar)); 279 static void f_filewritable __ARGS((VAR argvars, VAR retvar)); 280 static void f_fnamemodify __ARGS((VAR argvars, VAR retvar)); 281 static void f_foldclosed __ARGS((VAR argvars, VAR retvar)); 282 static void f_foldclosedend __ARGS((VAR argvars, VAR retvar)); 283 static void foldclosed_both __ARGS((VAR argvars, VAR retvar, int end)); 284 static void f_foldlevel __ARGS((VAR argvars, VAR retvar)); 285 static void f_foldtext __ARGS((VAR argvars, VAR retvar)); 286 static void f_foreground __ARGS((VAR argvars, VAR retvar)); 287 static void f_getbufvar __ARGS((VAR argvars, VAR retvar)); 288 static void f_getchar __ARGS((VAR argvars, VAR retvar)); 289 static void f_getcharmod __ARGS((VAR argvars, VAR retvar)); 290 static void f_getcmdline __ARGS((VAR argvars, VAR retvar)); 291 static void f_getcmdpos __ARGS((VAR argvars, VAR retvar)); 292 static void f_getcwd __ARGS((VAR argvars, VAR retvar)); 293 static void f_getfsize __ARGS((VAR argvars, VAR retvar)); 294 static void f_getftime __ARGS((VAR argvars, VAR retvar)); 295 static void f_getline __ARGS((VAR argvars, VAR retvar)); 296 static void f_getreg __ARGS((VAR argvars, VAR retvar)); 297 static void f_getregtype __ARGS((VAR argvars, VAR retvar)); 298 static void f_getwinposx __ARGS((VAR argvars, VAR retvar)); 299 static void f_getwinposy __ARGS((VAR argvars, VAR retvar)); 300 static void f_getwinvar __ARGS((VAR argvars, VAR retvar)); 301 static void f_glob __ARGS((VAR argvars, VAR retvar)); 302 static void f_globpath __ARGS((VAR argvars, VAR retvar)); 303 static void f_has __ARGS((VAR argvars, VAR retvar)); 304 static void f_hasmapto __ARGS((VAR argvars, VAR retvar)); 305 static void f_histadd __ARGS((VAR argvars, VAR retvar)); 306 static void f_histdel __ARGS((VAR argvars, VAR retvar)); 307 static void f_histget __ARGS((VAR argvars, VAR retvar)); 308 static void f_histnr __ARGS((VAR argvars, VAR retvar)); 309 static void f_hlexists __ARGS((VAR argvars, VAR retvar)); 310 static void f_hlID __ARGS((VAR argvars, VAR retvar)); 311 static void f_hostname __ARGS((VAR argvars, VAR retvar)); 312 static void f_iconv __ARGS((VAR argvars, VAR retvar)); 313 static void f_indent __ARGS((VAR argvars, VAR retvar)); 314 static void f_isdirectory __ARGS((VAR argvars, VAR retvar)); 315 static void f_input __ARGS((VAR argvars, VAR retvar)); 316 static void f_inputdialog __ARGS((VAR argvars, VAR retvar)); 317 static void f_inputrestore __ARGS((VAR argvars, VAR retvar)); 318 static void f_inputsave __ARGS((VAR argvars, VAR retvar)); 319 static void f_inputsecret __ARGS((VAR argvars, VAR retvar)); 320 static void f_last_buffer_nr __ARGS((VAR argvars, VAR retvar)); 321 static void f_libcall __ARGS((VAR argvars, VAR retvar)); 322 static void f_libcallnr __ARGS((VAR argvars, VAR retvar)); 323 static void libcall_common __ARGS((VAR argvars, VAR retvar, int type)); 324 static void f_line __ARGS((VAR argvars, VAR retvar)); 325 static void f_line2byte __ARGS((VAR argvars, VAR retvar)); 326 static void f_lispindent __ARGS((VAR argvars, VAR retvar)); 327 static void f_localtime __ARGS((VAR argvars, VAR retvar)); 328 static void f_maparg __ARGS((VAR argvars, VAR retvar)); 329 static void f_mapcheck __ARGS((VAR argvars, VAR retvar)); 330 static void get_maparg __ARGS((VAR argvars, VAR retvar, int exact)); 331 static void f_match __ARGS((VAR argvars, VAR retvar)); 332 static void f_matchend __ARGS((VAR argvars, VAR retvar)); 333 static void f_matchstr __ARGS((VAR argvars, VAR retvar)); 334 static void f_mode __ARGS((VAR argvars, VAR retvar)); 335 static void f_nextnonblank __ARGS((VAR argvars, VAR retvar)); 336 static void f_nr2char __ARGS((VAR argvars, VAR retvar)); 337 static void f_prevnonblank __ARGS((VAR argvars, VAR retvar)); 338 static void f_setbufvar __ARGS((VAR argvars, VAR retvar)); 339 static void f_setcmdpos __ARGS((VAR argvars, VAR retvar)); 340 static void f_setwinvar __ARGS((VAR argvars, VAR retvar)); 341 static void f_rename __ARGS((VAR argvars, VAR retvar)); 342 static void f_resolve __ARGS((VAR argvars, VAR retvar)); 343 static void f_search __ARGS((VAR argvars, VAR retvar)); 344 static void f_searchpair __ARGS((VAR argvars, VAR retvar)); 345 static int get_search_arg __ARGS((VAR varp, int *flagsp)); 346 static void f_remote_expr __ARGS((VAR argvars, VAR retvar)); 347 static void f_remote_foreground __ARGS((VAR argvars, VAR retvar)); 348 static void f_remote_peek __ARGS((VAR argvars, VAR retvar)); 349 static void f_remote_read __ARGS((VAR argvars, VAR retvar)); 350 static void f_remote_send __ARGS((VAR argvars, VAR retvar)); 351 static void f_server2client __ARGS((VAR argvars, VAR retvar)); 352 static void f_serverlist __ARGS((VAR argvars, VAR retvar)); 353 static void f_setline __ARGS((VAR argvars, VAR retvar)); 354 static void f_setreg __ARGS((VAR argvars, VAR retvar)); 355 static void f_simplify __ARGS((VAR argvars, VAR retvar)); 356 static void find_some_match __ARGS((VAR argvars, VAR retvar, int start)); 357 static void f_strftime __ARGS((VAR argvars, VAR retvar)); 358 static void f_stridx __ARGS((VAR argvars, VAR retvar)); 359 static void f_strlen __ARGS((VAR argvars, VAR retvar)); 360 static void f_strpart __ARGS((VAR argvars, VAR retvar)); 361 static void f_strridx __ARGS((VAR argvars, VAR retvar)); 362 static void f_strtrans __ARGS((VAR argvars, VAR retvar)); 363 static void f_synID __ARGS((VAR argvars, VAR retvar)); 364 static void f_synIDattr __ARGS((VAR argvars, VAR retvar)); 365 static void f_synIDtrans __ARGS((VAR argvars, VAR retvar)); 366 static void f_system __ARGS((VAR argvars, VAR retvar)); 367 static void f_submatch __ARGS((VAR argvars, VAR retvar)); 368 static void f_substitute __ARGS((VAR argvars, VAR retvar)); 369 static void f_tempname __ARGS((VAR argvars, VAR retvar)); 370 static void f_tolower __ARGS((VAR argvars, VAR retvar)); 371 static void f_toupper __ARGS((VAR argvars, VAR retvar)); 372 static void f_type __ARGS((VAR argvars, VAR retvar)); 373 static void f_virtcol __ARGS((VAR argvars, VAR retvar)); 374 static void f_visualmode __ARGS((VAR argvars, VAR retvar)); 375 static void f_winbufnr __ARGS((VAR argvars, VAR retvar)); 376 static void f_wincol __ARGS((VAR argvars, VAR retvar)); 377 static void f_winheight __ARGS((VAR argvars, VAR retvar)); 378 static void f_winline __ARGS((VAR argvars, VAR retvar)); 379 static void f_winnr __ARGS((VAR argvars, VAR retvar)); 380 static void f_winrestcmd __ARGS((VAR argvars, VAR retvar)); 381 static void f_winwidth __ARGS((VAR argvars, VAR retvar)); 382 static win_T *find_win_by_nr __ARGS((VAR vp)); 383 static pos_T *var2fpos __ARGS((VAR varp, int lnum)); 384 static int get_env_len __ARGS((char_u **arg)); 385 static int get_id_len __ARGS((char_u **arg)); 386 static int get_func_len __ARGS((char_u **arg, char_u **alias, int evaluate)); 387 static char_u *find_name_end __ARGS((char_u *arg, char_u **expr_start, char_u **expr_end)); 388 static int eval_isnamec __ARGS((int c)); 389 static int find_vim_var __ARGS((char_u *name, int len)); 390 static int get_var_var __ARGS((char_u *name, int len, VAR retvar)); 391 static VAR alloc_var __ARGS((void)); 392 static VAR alloc_string_var __ARGS((char_u *string)); 393 static void free_var __ARGS((VAR varp)); 394 static void clear_var __ARGS((VAR varp)); 395 static long get_var_number __ARGS((VAR varp)); 396 static linenr_T get_var_lnum __ARGS((VAR argvars)); 397 static char_u *get_var_string __ARGS((VAR varp)); 398 static char_u *get_var_string_buf __ARGS((VAR varp, char_u *buf)); 399 static VAR find_var __ARGS((char_u *name, int writing)); 400 static VAR find_var_in_ga __ARGS((garray_T *gap, char_u *varname)); 401 static garray_T *find_var_ga __ARGS((char_u *name, char_u **varname)); 402 static void var_free_one __ARGS((VAR v)); 403 static void list_one_var __ARGS((VAR v, char_u *prefix)); 404 static void list_vim_var __ARGS((int i)); 405 static void list_one_var_a __ARGS((char_u *prefix, char_u *name, int type, char_u *string)); 406 static void set_var __ARGS((char_u *name, VAR varp)); 407 static void copy_var __ARGS((VAR from, VAR to)); 408 static char_u *find_option_end __ARGS((char_u **arg, int *opt_flags)); 409 static char_u *trans_function_name __ARGS((char_u **pp, int skip, int internal)); 410 static int eval_fname_script __ARGS((char_u *p)); 411 static int eval_fname_sid __ARGS((char_u *p)); 412 static void list_func_head __ARGS((ufunc_T *fp, int indent)); 413 static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp)); 414 static ufunc_T *find_func __ARGS((char_u *name)); 415 static void call_user_func __ARGS((ufunc_T *fp, int argcount, VAR argvars, VAR retvar, linenr_T firstline, linenr_T lastline)); 416 417 /* Magic braces are always enabled, otherwise Vim scripts would not be 418 * portable. */ 419 #define FEAT_MAGIC_BRACES 420 421 #ifdef FEAT_MAGIC_BRACES 422 static char_u * make_expanded_name __ARGS((char_u *in_start, char_u *expr_start, char_u *expr_end, char_u *in_end)); 423 #endif 424 425 /* 426 * Set an internal variable to a string value. Creates the variable if it does 427 * not already exist. 428 */ 429 void 430 set_internal_string_var(name, value) 431 char_u *name; 432 char_u *value; 433 { 434 char_u *val; 435 VAR varp; 436 437 val = vim_strsave(value); 438 if (val != NULL) 439 { 440 varp = alloc_string_var(val); 441 if (varp != NULL) 442 { 443 set_var(name, varp); 444 free_var(varp); 445 } 446 } 447 } 448 449 # if defined(FEAT_MBYTE) || defined(PROTO) 450 int 451 eval_charconvert(enc_from, enc_to, fname_from, fname_to) 452 char_u *enc_from; 453 char_u *enc_to; 454 char_u *fname_from; 455 char_u *fname_to; 456 { 457 int err = FALSE; 458 459 set_vim_var_string(VV_CC_FROM, enc_from, -1); 460 set_vim_var_string(VV_CC_TO, enc_to, -1); 461 set_vim_var_string(VV_FNAME_IN, fname_from, -1); 462 set_vim_var_string(VV_FNAME_OUT, fname_to, -1); 463 if (eval_to_bool(p_ccv, &err, NULL, FALSE)) 464 err = TRUE; 465 set_vim_var_string(VV_CC_FROM, NULL, -1); 466 set_vim_var_string(VV_CC_TO, NULL, -1); 467 set_vim_var_string(VV_FNAME_IN, NULL, -1); 468 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 469 470 if (err) 471 return FAIL; 472 return OK; 473 } 474 # endif 475 476 # if defined(FEAT_POSTSCRIPT) || defined(PROTO) 477 int 478 eval_printexpr(fname, args) 479 char_u *fname; 480 char_u *args; 481 { 482 int err = FALSE; 483 484 set_vim_var_string(VV_FNAME_IN, fname, -1); 485 set_vim_var_string(VV_CMDARG, args, -1); 486 if (eval_to_bool(p_pexpr, &err, NULL, FALSE)) 487 err = TRUE; 488 set_vim_var_string(VV_FNAME_IN, NULL, -1); 489 set_vim_var_string(VV_CMDARG, NULL, -1); 490 491 if (err) 492 { 493 mch_remove(fname); 494 return FAIL; 495 } 496 return OK; 497 } 498 # endif 499 500 # if defined(FEAT_DIFF) || defined(PROTO) 501 void 502 eval_diff(origfile, newfile, outfile) 503 char_u *origfile; 504 char_u *newfile; 505 char_u *outfile; 506 { 507 int err = FALSE; 508 509 set_vim_var_string(VV_FNAME_IN, origfile, -1); 510 set_vim_var_string(VV_FNAME_NEW, newfile, -1); 511 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 512 (void)eval_to_bool(p_dex, &err, NULL, FALSE); 513 set_vim_var_string(VV_FNAME_IN, NULL, -1); 514 set_vim_var_string(VV_FNAME_NEW, NULL, -1); 515 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 516 } 517 518 void 519 eval_patch(origfile, difffile, outfile) 520 char_u *origfile; 521 char_u *difffile; 522 char_u *outfile; 523 { 524 int err; 525 526 set_vim_var_string(VV_FNAME_IN, origfile, -1); 527 set_vim_var_string(VV_FNAME_DIFF, difffile, -1); 528 set_vim_var_string(VV_FNAME_OUT, outfile, -1); 529 (void)eval_to_bool(p_pex, &err, NULL, FALSE); 530 set_vim_var_string(VV_FNAME_IN, NULL, -1); 531 set_vim_var_string(VV_FNAME_DIFF, NULL, -1); 532 set_vim_var_string(VV_FNAME_OUT, NULL, -1); 533 } 534 # endif 535 536 /* 537 * Top level evaluation function, returning a boolean. 538 * Sets "error" to TRUE if there was an error. 539 * Return TRUE or FALSE. 540 */ 541 int 542 eval_to_bool(arg, error, nextcmd, skip) 543 char_u *arg; 544 int *error; 545 char_u **nextcmd; 546 int skip; /* only parse, don't execute */ 547 { 548 var retvar; 549 int retval = FALSE; 550 551 if (skip) 552 ++emsg_skip; 553 if (eval0(arg, &retvar, nextcmd, !skip) == FAIL) 554 { 555 *error = TRUE; 556 } 557 else 558 { 559 *error = FALSE; 560 if (!skip) 561 { 562 retval = (get_var_number(&retvar) != 0); 563 clear_var(&retvar); 564 } 565 } 566 if (skip) 567 --emsg_skip; 568 569 return retval; 570 } 571 572 /* 573 * Top level evaluation function, returning a string. If "skip" is TRUE, 574 * only parsing to "nextcmd" is done, without reporting errors. Return 575 * pointer to allocated memory, or NULL for failure or when "skip" is TRUE. 576 */ 577 char_u * 578 eval_to_string_skip(arg, nextcmd, skip) 579 char_u *arg; 580 char_u **nextcmd; 581 int skip; /* only parse, don't execute */ 582 { 583 var retvar; 584 char_u *retval; 585 586 if (skip) 587 ++emsg_skip; 588 if (eval0(arg, &retvar, nextcmd, !skip) == FAIL || skip) 589 retval = NULL; 590 else 591 { 592 retval = vim_strsave(get_var_string(&retvar)); 593 clear_var(&retvar); 594 } 595 if (skip) 596 --emsg_skip; 597 598 return retval; 599 } 600 601 /* 602 * Skip over an expression at "*pp". 603 * Return FAIL for an error, OK otherwise. 604 */ 605 int 606 skip_expr(pp) 607 char_u **pp; 608 { 609 var retvar; 610 611 *pp = skipwhite(*pp); 612 return eval1(pp, &retvar, FALSE); 613 } 614 615 /* 616 * Top level evaluation function, returning a string. 617 * Return pointer to allocated memory, or NULL for failure. 618 */ 619 char_u * 620 eval_to_string(arg, nextcmd) 621 char_u *arg; 622 char_u **nextcmd; 623 { 624 var retvar; 625 char_u *retval; 626 627 if (eval0(arg, &retvar, nextcmd, TRUE) == FAIL) 628 retval = NULL; 629 else 630 { 631 retval = vim_strsave(get_var_string(&retvar)); 632 clear_var(&retvar); 633 } 634 635 return retval; 636 } 637 638 /* 639 * Call eval_to_string() with "sandbox" set and not using local variables. 640 */ 641 char_u * 642 eval_to_string_safe(arg, nextcmd) 643 char_u *arg; 644 char_u **nextcmd; 645 { 646 char_u *retval; 647 void *save_funccalp; 648 649 save_funccalp = save_funccal(); 650 ++sandbox; 651 retval = eval_to_string(arg, nextcmd); 652 --sandbox; 653 restore_funccal(save_funccalp); 654 return retval; 655 } 656 657 #if 0 /* not used */ 658 /* 659 * Top level evaluation function, returning a string. 660 * Advances "arg" to the first non-blank after the evaluated expression. 661 * Return pointer to allocated memory, or NULL for failure. 662 * Doesn't give error messages. 663 */ 664 char_u * 665 eval_arg_to_string(arg) 666 char_u **arg; 667 { 668 var retvar; 669 char_u *retval; 670 int ret; 671 672 ++emsg_off; 673 674 ret = eval1(arg, &retvar, TRUE); 675 if (ret == FAIL) 676 retval = NULL; 677 else 678 { 679 retval = vim_strsave(get_var_string(&retvar)); 680 clear_var(&retvar); 681 } 682 683 --emsg_off; 684 685 return retval; 686 } 687 #endif 688 689 /* 690 * Top level evaluation function, returning a number. 691 * Evaluates "expr" silently. 692 * Returns -1 for an error. 693 */ 694 int 695 eval_to_number(expr) 696 char_u *expr; 697 { 698 var retvar; 699 int retval; 700 char_u *p = expr; 701 702 ++emsg_off; 703 704 if (eval1(&p, &retvar, TRUE) == FAIL) 705 retval = -1; 706 else 707 { 708 retval = get_var_number(&retvar); 709 clear_var(&retvar); 710 } 711 --emsg_off; 712 713 return retval; 714 } 715 716 #if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO) 717 /* 718 * Call some vimL function and return the result as a string 719 * Uses argv[argc] for the function arguments. 720 */ 721 char_u * 722 call_vim_function(func, argc, argv, safe) 723 char_u *func; 724 int argc; 725 char_u **argv; 726 int safe; /* use the sandbox */ 727 { 728 char_u *retval = NULL; 729 var retvar; 730 VAR argvars; 731 long n; 732 int len; 733 int i; 734 int doesrange; 735 void *save_funccalp = NULL; 736 737 argvars = (VAR)alloc((unsigned)(argc * sizeof(var))); 738 if (argvars == NULL) 739 return NULL; 740 741 for (i = 0; i < argc; i++) 742 { 743 /* Recognize a number argument, the others must be strings. */ 744 vim_str2nr(argv[i], NULL, &len, TRUE, TRUE, &n, NULL); 745 if (len != 0 && len == (int)STRLEN(argv[i])) 746 { 747 argvars[i].var_type = VAR_NUMBER; 748 argvars[i].var_val.var_number = n; 749 } 750 else 751 { 752 argvars[i].var_type = VAR_STRING; 753 argvars[i].var_val.var_string = argv[i]; 754 } 755 } 756 757 if (safe) 758 { 759 save_funccalp = save_funccal(); 760 ++sandbox; 761 } 762 763 retvar.var_type = VAR_UNKNOWN; /* clear_var() uses this */ 764 if (call_func(func, (int)STRLEN(func), &retvar, argc, argvars, 765 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 766 &doesrange, TRUE) == OK) 767 retval = vim_strsave(get_var_string(&retvar)); 768 769 clear_var(&retvar); 770 vim_free(argvars); 771 772 if (safe) 773 { 774 --sandbox; 775 restore_funccal(save_funccalp); 776 } 777 return retval; 778 } 779 #endif 780 781 /* 782 * Save the current function call pointer, and set it to NULL. 783 * Used when executing autocommands and for ":source". 784 */ 785 void * 786 save_funccal() 787 { 788 struct funccall *fc; 789 790 fc = current_funccal; 791 current_funccal = NULL; 792 return (void *)fc; 793 } 794 795 void 796 restore_funccal(fc) 797 void *fc; 798 { 799 current_funccal = (struct funccall *)fc; 800 } 801 802 #ifdef FEAT_FOLDING 803 /* 804 * Evaluate 'foldexpr'. Returns the foldlevel, and any character preceding 805 * it in "*cp". Doesn't give error messages. 806 */ 807 int 808 eval_foldexpr(arg, cp) 809 char_u *arg; 810 int *cp; 811 { 812 var retvar; 813 int retval; 814 char_u *s; 815 816 ++emsg_off; 817 ++sandbox; 818 *cp = NUL; 819 if (eval0(arg, &retvar, NULL, TRUE) == FAIL) 820 retval = 0; 821 else 822 { 823 /* If the result is a number, just return the number. */ 824 if (retvar.var_type == VAR_NUMBER) 825 retval = retvar.var_val.var_number; 826 else if (retvar.var_type == VAR_UNKNOWN 827 || retvar.var_val.var_string == NULL) 828 retval = 0; 829 else 830 { 831 /* If the result is a string, check if there is a non-digit before 832 * the number. */ 833 s = retvar.var_val.var_string; 834 if (!VIM_ISDIGIT(*s) && *s != '-') 835 *cp = *s++; 836 retval = atol((char *)s); 837 } 838 clear_var(&retvar); 839 } 840 --emsg_off; 841 --sandbox; 842 843 return retval; 844 } 845 #endif 846 847 #ifdef FEAT_MAGIC_BRACES 848 /* 849 * Expands out the 'magic' {}'s in a variable/function name. 850 * Note that this can call itself recursively, to deal with 851 * constructs like foo{bar}{baz}{bam} 852 * The four pointer arguments point to "foo{expre}ss{ion}bar" 853 * "in_start" ^ 854 * "expr_start" ^ 855 * "expr_end" ^ 856 * "in_end" ^ 857 * 858 * Returns a new allocated string, which the caller must free. 859 * Returns NULL for failure. 860 */ 861 static char_u * 862 make_expanded_name(in_start, expr_start, expr_end, in_end) 863 char_u *in_start; 864 char_u *expr_start; 865 char_u *expr_end; 866 char_u *in_end; 867 { 868 char_u c1; 869 char_u *retval = NULL; 870 char_u *temp_result; 871 char_u *nextcmd = NULL; 872 873 if (expr_end == NULL || in_end == NULL) 874 return NULL; 875 *expr_start = NUL; 876 *expr_end = NUL; 877 c1 = *in_end; 878 *in_end = NUL; 879 880 temp_result = eval_to_string(expr_start + 1, &nextcmd); 881 if (temp_result != NULL && nextcmd == NULL) 882 { 883 retval = alloc((unsigned)(STRLEN(temp_result) + (expr_start - in_start) 884 + (in_end - expr_end) + 1)); 885 886 if (retval != NULL) 887 { 888 STRCPY(retval, in_start); 889 STRCAT(retval, temp_result); 890 STRCAT(retval, expr_end + 1); 891 } 892 } 893 vim_free(temp_result); 894 895 *in_end = c1; /* put char back for error messages */ 896 *expr_start = '{'; 897 *expr_end = '}'; 898 899 if (retval != NULL) 900 { 901 temp_result = find_name_end(retval, &expr_start, &expr_end); 902 if (expr_start != NULL) 903 { 904 /* Further expansion! */ 905 temp_result = make_expanded_name(retval, expr_start, 906 expr_end, temp_result); 907 vim_free(retval); 908 retval = temp_result; 909 } 910 } 911 912 return retval; 913 914 } 915 #endif /* FEAT_MAGIC_BRACES */ 916 917 /* 918 * ":let var = expr" assignment command. 919 * ":let var" list one variable value 920 * ":let" list all variable values 921 */ 922 void 923 ex_let(eap) 924 exarg_T *eap; 925 { 926 char_u *arg = eap->arg; 927 char_u *expr; 928 char_u *name; 929 VAR varp; 930 var retvar; 931 char_u *p; 932 int c1 = 0, c2; 933 int i; 934 char_u *expr_start; 935 char_u *expr_end; 936 char_u *name_end; 937 938 name_end = find_name_end(arg, &expr_start, &expr_end); 939 expr = vim_strchr(name_end, '='); 940 if (expr == NULL) 941 { 942 if (ends_excmd(*arg)) 943 { 944 if (!eap->skip) 945 { 946 /* 947 * List all variables. 948 */ 949 for (i = 0; i < variables.ga_len && !got_int; ++i) 950 if (VAR_ENTRY(i).var_name != NULL) 951 list_one_var(&VAR_ENTRY(i), (char_u *)""); 952 for (i = 0; i < curbuf->b_vars.ga_len && !got_int; ++i) 953 if (BVAR_ENTRY(i).var_name != NULL) 954 list_one_var(&BVAR_ENTRY(i), (char_u *)"b:"); 955 for (i = 0; i < curwin->w_vars.ga_len && !got_int; ++i) 956 if (WVAR_ENTRY(i).var_name != NULL) 957 list_one_var(&WVAR_ENTRY(i), (char_u *)"w:"); 958 for (i = 0; i < VV_LEN && !got_int; ++i) 959 if (vimvars[i].type == VAR_NUMBER || vimvars[i].val != NULL) 960 list_vim_var(i); 961 } 962 } 963 else 964 { 965 int error = FALSE; 966 967 /* 968 * List variables. 969 */ 970 while (!ends_excmd(*arg) && !got_int) 971 { 972 char_u *temp_string = NULL; 973 int arg_len; 974 975 /* Find the end of the name. */ 976 name_end = find_name_end(arg, &expr_start, &expr_end); 977 978 if (!vim_iswhite(*name_end) && !ends_excmd(*name_end)) 979 { 980 emsg_severe = TRUE; 981 EMSG(_(e_trailing)); 982 break; 983 } 984 if (!error && !eap->skip) 985 { 986 #ifdef FEAT_MAGIC_BRACES 987 if (expr_start != NULL) 988 { 989 temp_string = make_expanded_name(arg, expr_start, 990 expr_end, name_end); 991 if (temp_string == NULL) 992 { 993 /* 994 * Report an invalid expression in braces, unless 995 * the expression evaluation has been cancelled due 996 * to an aborting error, an interrupt, or an 997 * exception. 998 */ 999 if (!aborting()) 1000 { 1001 emsg_severe = TRUE; 1002 EMSG2(_(e_invarg2), arg); 1003 break; 1004 } 1005 error = TRUE; 1006 arg = skipwhite(name_end); 1007 continue; 1008 } 1009 arg = temp_string; 1010 arg_len = STRLEN(temp_string); 1011 } 1012 else 1013 #endif 1014 { 1015 c1 = *name_end; 1016 *name_end = NUL; 1017 arg_len = (int)(name_end - arg); 1018 } 1019 i = find_vim_var(arg, arg_len); 1020 if (i >= 0) 1021 list_vim_var(i); 1022 else if (STRCMP("b:changedtick", arg) == 0) 1023 { 1024 char_u numbuf[NUMBUFLEN]; 1025 1026 sprintf((char *)numbuf, "%ld", 1027 (long)curbuf->b_changedtick); 1028 list_one_var_a((char_u *)"b:", (char_u *)"changedtick", 1029 VAR_NUMBER, numbuf); 1030 } 1031 else 1032 { 1033 varp = find_var(arg, FALSE); 1034 if (varp == NULL) 1035 { 1036 /* Skip further arguments but do continue to 1037 * search for a trailing command. */ 1038 EMSG2(_("E106: Unknown variable: \"%s\""), arg); 1039 error = TRUE; 1040 } 1041 else 1042 { 1043 name = vim_strchr(arg, ':'); 1044 if (name != NULL) 1045 { 1046 /* "a:" vars have no name stored, use whole 1047 * arg */ 1048 if (arg[0] == 'a' && arg[1] == ':') 1049 c2 = NUL; 1050 else 1051 { 1052 c2 = *++name; 1053 *name = NUL; 1054 } 1055 list_one_var(varp, arg); 1056 if (c2 != NUL) 1057 *name = c2; 1058 } 1059 else 1060 list_one_var(varp, (char_u *)""); 1061 } 1062 } 1063 #ifdef FEAT_MAGIC_BRACES 1064 if (expr_start != NULL) 1065 vim_free(temp_string); 1066 else 1067 #endif 1068 *name_end = c1; 1069 } 1070 arg = skipwhite(name_end); 1071 } 1072 } 1073 eap->nextcmd = check_nextcmd(arg); 1074 } 1075 else 1076 { 1077 if (eap->skip) 1078 ++emsg_skip; 1079 i = eval0(expr + 1, &retvar, &eap->nextcmd, !eap->skip); 1080 if (eap->skip) 1081 { 1082 if (i != FAIL) 1083 clear_var(&retvar); 1084 --emsg_skip; 1085 } 1086 else if (i != FAIL) 1087 { 1088 /* 1089 * ":let $VAR = expr": Set environment variable. 1090 */ 1091 if (*arg == '$') 1092 { 1093 int len; 1094 int cc; 1095 1096 /* Find the end of the name. */ 1097 ++arg; 1098 name = arg; 1099 len = get_env_len(&arg); 1100 if (len == 0) 1101 EMSG2(_(e_invarg2), name - 1); 1102 else 1103 { 1104 if (*skipwhite(arg) != '=') 1105 EMSG(_(e_letunexp)); 1106 else 1107 { 1108 cc = name[len]; 1109 name[len] = NUL; 1110 p = get_var_string(&retvar); 1111 vim_setenv(name, p); 1112 if (STRICMP(name, "HOME") == 0) 1113 init_homedir(); 1114 else if (didset_vim && STRICMP(name, "VIM") == 0) 1115 didset_vim = FALSE; 1116 else if (didset_vimruntime 1117 && STRICMP(name, "VIMRUNTIME") == 0) 1118 didset_vimruntime = FALSE; 1119 name[len] = cc; 1120 } 1121 } 1122 } 1123 1124 /* 1125 * ":let &option = expr": Set option value. 1126 * ":let &l:option = expr": Set local option value. 1127 * ":let &g:option = expr": Set global option value. 1128 */ 1129 else if (*arg == '&') 1130 { 1131 int opt_flags; 1132 1133 /* 1134 * Find the end of the name; 1135 */ 1136 p = find_option_end(&arg, &opt_flags); 1137 if (p == NULL || *skipwhite(p) != '=') 1138 EMSG(_(e_letunexp)); 1139 else 1140 { 1141 c1 = *p; 1142 *p = NUL; 1143 set_option_value(arg, get_var_number(&retvar), 1144 get_var_string(&retvar), opt_flags); 1145 *p = c1; /* put back for error messages */ 1146 } 1147 } 1148 1149 /* 1150 * ":let @r = expr": Set register contents. 1151 */ 1152 else if (*arg == '@') 1153 { 1154 ++arg; 1155 if (*skipwhite(arg + 1) != '=') 1156 EMSG(_(e_letunexp)); 1157 else 1158 write_reg_contents(*arg == '@' ? '"' : *arg, 1159 get_var_string(&retvar), -1, FALSE); 1160 } 1161 1162 /* 1163 * ":let var = expr": Set internal variable. 1164 */ 1165 else if (eval_isnamec(*arg) && !VIM_ISDIGIT(*arg)) 1166 { 1167 /* Find the end of the name. */ 1168 p = find_name_end(arg, &expr_start, &expr_end); 1169 1170 if (*skipwhite(p) != '=') 1171 EMSG(_(e_letunexp)); 1172 else if (p - arg == 13 1173 && STRNCMP(arg, "b:changedtick", 13) == 0) 1174 EMSG2(_(e_readonlyvar), arg); 1175 #ifdef FEAT_MAGIC_BRACES 1176 else if (expr_start != NULL) 1177 { 1178 char_u *temp_string; 1179 1180 temp_string = make_expanded_name(arg, expr_start, 1181 expr_end, p); 1182 if (temp_string == NULL) 1183 { 1184 /* 1185 * Report an invalid expression in braces, unless the 1186 * expression evaluation has been cancelled due to an 1187 * aborting error, an interrupt, or an exception. 1188 */ 1189 if (!aborting()) 1190 EMSG2(_(e_invarg2), arg); 1191 } 1192 else 1193 { 1194 set_var(temp_string, &retvar); 1195 vim_free(temp_string); 1196 } 1197 } 1198 #endif 1199 else 1200 { 1201 c1 = *p; 1202 *p = NUL; 1203 set_var(arg, &retvar); 1204 *p = c1; /* put char back for error messages */ 1205 } 1206 } 1207 1208 else 1209 { 1210 EMSG2(_(e_invarg2), arg); 1211 } 1212 1213 clear_var(&retvar); 1214 } 1215 } 1216 } 1217 1218 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 1219 1220 void 1221 set_context_for_expression(xp, arg, cmdidx) 1222 expand_T *xp; 1223 char_u *arg; 1224 cmdidx_T cmdidx; 1225 { 1226 int got_eq = FALSE; 1227 int c; 1228 1229 xp->xp_context = cmdidx == CMD_let ? EXPAND_USER_VARS 1230 : cmdidx == CMD_call ? EXPAND_FUNCTIONS 1231 : EXPAND_EXPRESSION; 1232 while ((xp->xp_pattern = vim_strpbrk(arg, 1233 (char_u *)"\"'+-*/%.=!?~|&$([<>,#")) != NULL) 1234 { 1235 c = *xp->xp_pattern; 1236 if (c == '&') 1237 { 1238 c = xp->xp_pattern[1]; 1239 if (c == '&') 1240 { 1241 ++xp->xp_pattern; 1242 xp->xp_context = cmdidx != CMD_let || got_eq 1243 ? EXPAND_EXPRESSION : EXPAND_NOTHING; 1244 } 1245 else if (c != ' ') 1246 xp->xp_context = EXPAND_SETTINGS; 1247 } 1248 else if (c == '$') 1249 { 1250 /* environment variable */ 1251 xp->xp_context = EXPAND_ENV_VARS; 1252 } 1253 else if (c == '=') 1254 { 1255 got_eq = TRUE; 1256 xp->xp_context = EXPAND_EXPRESSION; 1257 } 1258 else if (c == '<' 1259 && xp->xp_context == EXPAND_FUNCTIONS 1260 && vim_strchr(xp->xp_pattern, '(') == NULL) 1261 { 1262 /* Function name can start with "<SNR>" */ 1263 break; 1264 } 1265 else if (cmdidx != CMD_let || got_eq) 1266 { 1267 if (c == '"') /* string */ 1268 { 1269 while ((c = *++xp->xp_pattern) != NUL && c != '"') 1270 if (c == '\\' && xp->xp_pattern[1] != NUL) 1271 ++xp->xp_pattern; 1272 xp->xp_context = EXPAND_NOTHING; 1273 } 1274 else if (c == '\'') /* literal string */ 1275 { 1276 while ((c = *++xp->xp_pattern) != NUL && c != '\'') 1277 /* skip */ ; 1278 xp->xp_context = EXPAND_NOTHING; 1279 } 1280 else if (c == '|') 1281 { 1282 if (xp->xp_pattern[1] == '|') 1283 { 1284 ++xp->xp_pattern; 1285 xp->xp_context = EXPAND_EXPRESSION; 1286 } 1287 else 1288 xp->xp_context = EXPAND_COMMANDS; 1289 } 1290 else 1291 xp->xp_context = EXPAND_EXPRESSION; 1292 } 1293 else 1294 xp->xp_context = EXPAND_NOTHING; 1295 arg = xp->xp_pattern; 1296 if (*arg != NUL) 1297 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) 1298 /* skip */ ; 1299 } 1300 xp->xp_pattern = arg; 1301 } 1302 1303 #endif /* FEAT_CMDL_COMPL */ 1304 1305 /* 1306 * ":1,25call func(arg1, arg2)" function call. 1307 */ 1308 void 1309 ex_call(eap) 1310 exarg_T *eap; 1311 { 1312 char_u *arg = eap->arg; 1313 char_u *startarg; 1314 char_u *alias; 1315 char_u *name; 1316 var retvar; 1317 int len; 1318 linenr_T lnum; 1319 int doesrange; 1320 int failed = FALSE; 1321 1322 name = arg; 1323 len = get_func_len(&arg, &alias, !eap->skip); 1324 if (len == 0) 1325 goto end; 1326 if (alias != NULL) 1327 name = alias; 1328 1329 startarg = arg; 1330 retvar.var_type = VAR_UNKNOWN; /* clear_var() uses this */ 1331 1332 if (*startarg != '(') 1333 { 1334 EMSG2(_("E107: Missing braces: %s"), name); 1335 goto end; 1336 } 1337 1338 /* 1339 * When skipping, evaluate the function once, to find the end of the 1340 * arguments. 1341 * When the function takes a range, this is discovered after the first 1342 * call, and the loop is broken. 1343 */ 1344 if (eap->skip) 1345 { 1346 ++emsg_skip; 1347 lnum = eap->line2; /* do it once, also with an invalid range */ 1348 } 1349 else 1350 lnum = eap->line1; 1351 for ( ; lnum <= eap->line2; ++lnum) 1352 { 1353 if (!eap->skip && eap->addr_count > 0) 1354 { 1355 curwin->w_cursor.lnum = lnum; 1356 curwin->w_cursor.col = 0; 1357 } 1358 arg = startarg; 1359 if (get_func_var(name, len, &retvar, &arg, 1360 eap->line1, eap->line2, &doesrange, !eap->skip) == FAIL) 1361 { 1362 failed = TRUE; 1363 break; 1364 } 1365 clear_var(&retvar); 1366 if (doesrange || eap->skip) 1367 break; 1368 /* Stop when immediately aborting on error, or when an interrupt 1369 * occurred or an exception was thrown but not caught. get_func_var() 1370 * returned OK, so that the check for trailing characters below is 1371 * executed. */ 1372 if (aborting()) 1373 break; 1374 } 1375 if (eap->skip) 1376 --emsg_skip; 1377 1378 if (!failed) 1379 { 1380 /* Check for trailing illegal characters and a following command. */ 1381 if (!ends_excmd(*arg)) 1382 { 1383 emsg_severe = TRUE; 1384 EMSG(_(e_trailing)); 1385 } 1386 else 1387 eap->nextcmd = check_nextcmd(arg); 1388 } 1389 1390 end: 1391 if (alias != NULL) 1392 vim_free(alias); 1393 } 1394 1395 /* 1396 * ":unlet[!] var1 ... " command. 1397 */ 1398 void 1399 ex_unlet(eap) 1400 exarg_T *eap; 1401 { 1402 char_u *arg = eap->arg; 1403 char_u *name_end; 1404 char_u cc; 1405 char_u *expr_start; 1406 char_u *expr_end; 1407 int error = FALSE; 1408 1409 do 1410 { 1411 /* Find the end of the name. */ 1412 name_end = find_name_end(arg, &expr_start, &expr_end); 1413 1414 if (!vim_iswhite(*name_end) && !ends_excmd(*name_end)) 1415 { 1416 emsg_severe = TRUE; 1417 EMSG(_(e_trailing)); 1418 break; 1419 } 1420 1421 if (!error && !eap->skip) 1422 { 1423 #ifdef FEAT_MAGIC_BRACES 1424 if (expr_start != NULL) 1425 { 1426 char_u *temp_string; 1427 1428 temp_string = make_expanded_name(arg, expr_start, 1429 expr_end, name_end); 1430 if (temp_string == NULL) 1431 { 1432 /* 1433 * Report an invalid expression in braces, unless the 1434 * expression evaluation has been cancelled due to an 1435 * aborting error, an interrupt, or an exception. 1436 */ 1437 if (!aborting()) 1438 { 1439 emsg_severe = TRUE; 1440 EMSG2(_(e_invarg2), arg); 1441 break; 1442 } 1443 error = TRUE; 1444 } 1445 else 1446 { 1447 if (do_unlet(temp_string) == FAIL && !eap->forceit) 1448 { 1449 EMSG2(_("E108: No such variable: \"%s\""), temp_string); 1450 error = TRUE; 1451 } 1452 vim_free(temp_string); 1453 } 1454 } 1455 else 1456 #endif 1457 { 1458 cc = *name_end; 1459 *name_end = NUL; 1460 1461 if (do_unlet(arg) == FAIL && !eap->forceit) 1462 { 1463 EMSG2(_("E108: No such variable: \"%s\""), arg); 1464 error = TRUE; 1465 } 1466 1467 *name_end = cc; 1468 } 1469 } 1470 arg = skipwhite(name_end); 1471 } while (!ends_excmd(*arg)); 1472 1473 eap->nextcmd = check_nextcmd(arg); 1474 } 1475 1476 /* 1477 * "unlet" a variable. Return OK if it existed, FAIL if not. 1478 */ 1479 int 1480 do_unlet(name) 1481 char_u *name; 1482 { 1483 VAR v; 1484 1485 v = find_var(name, TRUE); 1486 if (v != NULL) 1487 { 1488 var_free_one(v); 1489 return OK; 1490 } 1491 return FAIL; 1492 } 1493 1494 #if (defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)) || defined(PROTO) 1495 /* 1496 * Delete all "menutrans_" variables. 1497 */ 1498 void 1499 del_menutrans_vars() 1500 { 1501 int i; 1502 1503 for (i = 0; i < variables.ga_len; ++i) 1504 if (VAR_ENTRY(i).var_name != NULL 1505 && STRNCMP(VAR_ENTRY(i).var_name, "menutrans_", 10) == 0) 1506 var_free_one(&VAR_ENTRY(i)); 1507 } 1508 #endif 1509 1510 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 1511 1512 /* 1513 * Local string buffer for the next two functions to store a variable name 1514 * with its prefix. Allocated in cat_prefix_varname(), freed later in 1515 * get_user_var_name(). 1516 */ 1517 1518 static char_u *cat_prefix_varname __ARGS((int prefix, char_u *name)); 1519 1520 static char_u *varnamebuf = NULL; 1521 static int varnamebuflen = 0; 1522 1523 /* 1524 * Function to concatenate a prefix and a variable name. 1525 */ 1526 static char_u * 1527 cat_prefix_varname(prefix, name) 1528 int prefix; 1529 char_u *name; 1530 { 1531 int len; 1532 1533 len = (int)STRLEN(name) + 3; 1534 if (len > varnamebuflen) 1535 { 1536 vim_free(varnamebuf); 1537 len += 10; /* some additional space */ 1538 varnamebuf = alloc(len); 1539 if (varnamebuf == NULL) 1540 { 1541 varnamebuflen = 0; 1542 return NULL; 1543 } 1544 varnamebuflen = len; 1545 } 1546 *varnamebuf = prefix; 1547 varnamebuf[1] = ':'; 1548 STRCPY(varnamebuf + 2, name); 1549 return varnamebuf; 1550 } 1551 1552 /* 1553 * Function given to ExpandGeneric() to obtain the list of user defined 1554 * (global/buffer/window/built-in) variable names. 1555 */ 1556 /*ARGSUSED*/ 1557 char_u * 1558 get_user_var_name(xp, idx) 1559 expand_T *xp; 1560 int idx; 1561 { 1562 static int gidx; 1563 static int bidx; 1564 static int widx; 1565 static int vidx; 1566 char_u *name; 1567 1568 if (idx == 0) 1569 gidx = bidx = widx = vidx = 0; 1570 if (gidx < variables.ga_len) /* Global variables */ 1571 { 1572 while ((name = VAR_ENTRY(gidx++).var_name) == NULL 1573 && gidx < variables.ga_len) 1574 /* skip */; 1575 if (name != NULL) 1576 { 1577 if (STRNCMP("g:", xp->xp_pattern, 2) == 0) 1578 return cat_prefix_varname('g', name); 1579 else 1580 return name; 1581 } 1582 } 1583 if (bidx < curbuf->b_vars.ga_len) /* Current buffer variables */ 1584 { 1585 while ((name = BVAR_ENTRY(bidx++).var_name) == NULL 1586 && bidx < curbuf->b_vars.ga_len) 1587 /* skip */; 1588 if (name != NULL) 1589 return cat_prefix_varname('b', name); 1590 } 1591 if (bidx == curbuf->b_vars.ga_len) 1592 { 1593 ++bidx; 1594 return (char_u *)"b:changedtick"; 1595 } 1596 if (widx < curwin->w_vars.ga_len) /* Current window variables */ 1597 { 1598 while ((name = WVAR_ENTRY(widx++).var_name) == NULL 1599 && widx < curwin->w_vars.ga_len) 1600 /* skip */; 1601 if (name != NULL) 1602 return cat_prefix_varname('w', name); 1603 } 1604 if (vidx < VV_LEN) /* Built-in variables */ 1605 return cat_prefix_varname('v', (char_u *)vimvars[vidx++].name); 1606 1607 vim_free(varnamebuf); 1608 varnamebuf = NULL; 1609 varnamebuflen = 0; 1610 return NULL; 1611 } 1612 1613 #endif /* FEAT_CMDL_COMPL */ 1614 1615 /* 1616 * types for expressions. 1617 */ 1618 typedef enum 1619 { 1620 TYPE_UNKNOWN = 0 1621 , TYPE_EQUAL /* == */ 1622 , TYPE_NEQUAL /* != */ 1623 , TYPE_GREATER /* > */ 1624 , TYPE_GEQUAL /* >= */ 1625 , TYPE_SMALLER /* < */ 1626 , TYPE_SEQUAL /* <= */ 1627 , TYPE_MATCH /* =~ */ 1628 , TYPE_NOMATCH /* !~ */ 1629 } exptype_T; 1630 1631 /* 1632 * The "evaluate" argument: When FALSE, the argument is only parsed but not 1633 * executed. The function may return OK, but the retvar will be of type 1634 * VAR_UNKNOWN. The function still returns FAIL for a syntax error. 1635 */ 1636 1637 /* 1638 * Handle zero level expression. 1639 * This calls eval1() and handles error message and nextcmd. 1640 * Return OK or FAIL. 1641 */ 1642 static int 1643 eval0(arg, retvar, nextcmd, evaluate) 1644 char_u *arg; 1645 VAR retvar; 1646 char_u **nextcmd; 1647 int evaluate; 1648 { 1649 int ret; 1650 char_u *p; 1651 1652 p = skipwhite(arg); 1653 ret = eval1(&p, retvar, evaluate); 1654 if (ret == FAIL || !ends_excmd(*p)) 1655 { 1656 if (ret != FAIL) 1657 clear_var(retvar); 1658 /* 1659 * Report the invalid expression unless the expression evaluation has 1660 * been cancelled due to an aborting error, an interrupt, or an 1661 * exception. 1662 */ 1663 if (!aborting()) 1664 EMSG2(_(e_invexpr2), arg); 1665 ret = FAIL; 1666 } 1667 if (nextcmd != NULL) 1668 *nextcmd = check_nextcmd(p); 1669 1670 return ret; 1671 } 1672 1673 /* 1674 * Handle top level expression: 1675 * expr1 ? expr0 : expr0 1676 * 1677 * "arg" must point to the first non-white of the expression. 1678 * "arg" is advanced to the next non-white after the recognized expression. 1679 * 1680 * Return OK or FAIL. 1681 */ 1682 static int 1683 eval1(arg, retvar, evaluate) 1684 char_u **arg; 1685 VAR retvar; 1686 int evaluate; 1687 { 1688 int result; 1689 var var2; 1690 1691 /* 1692 * Get the first variable. 1693 */ 1694 if (eval2(arg, retvar, evaluate) == FAIL) 1695 return FAIL; 1696 1697 if ((*arg)[0] == '?') 1698 { 1699 result = FALSE; 1700 if (evaluate) 1701 { 1702 if (get_var_number(retvar) != 0) 1703 result = TRUE; 1704 clear_var(retvar); 1705 } 1706 1707 /* 1708 * Get the second variable. 1709 */ 1710 *arg = skipwhite(*arg + 1); 1711 if (eval1(arg, retvar, evaluate && result) == FAIL) /* recursive! */ 1712 return FAIL; 1713 1714 /* 1715 * Check for the ":". 1716 */ 1717 if ((*arg)[0] != ':') 1718 { 1719 EMSG(_("E109: Missing ':' after '?'")); 1720 if (evaluate && result) 1721 clear_var(retvar); 1722 return FAIL; 1723 } 1724 1725 /* 1726 * Get the third variable. 1727 */ 1728 *arg = skipwhite(*arg + 1); 1729 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ 1730 { 1731 if (evaluate && result) 1732 clear_var(retvar); 1733 return FAIL; 1734 } 1735 if (evaluate && !result) 1736 *retvar = var2; 1737 } 1738 1739 return OK; 1740 } 1741 1742 /* 1743 * Handle first level expression: 1744 * expr2 || expr2 || expr2 logical OR 1745 * 1746 * "arg" must point to the first non-white of the expression. 1747 * "arg" is advanced to the next non-white after the recognized expression. 1748 * 1749 * Return OK or FAIL. 1750 */ 1751 static int 1752 eval2(arg, retvar, evaluate) 1753 char_u **arg; 1754 VAR retvar; 1755 int evaluate; 1756 { 1757 var var2; 1758 long result; 1759 int first; 1760 1761 /* 1762 * Get the first variable. 1763 */ 1764 if (eval3(arg, retvar, evaluate) == FAIL) 1765 return FAIL; 1766 1767 /* 1768 * Repeat until there is no following "||". 1769 */ 1770 first = TRUE; 1771 result = FALSE; 1772 while ((*arg)[0] == '|' && (*arg)[1] == '|') 1773 { 1774 if (evaluate && first) 1775 { 1776 if (get_var_number(retvar) != 0) 1777 result = TRUE; 1778 clear_var(retvar); 1779 first = FALSE; 1780 } 1781 1782 /* 1783 * Get the second variable. 1784 */ 1785 *arg = skipwhite(*arg + 2); 1786 if (eval3(arg, &var2, evaluate && !result) == FAIL) 1787 return FAIL; 1788 1789 /* 1790 * Compute the result. 1791 */ 1792 if (evaluate && !result) 1793 { 1794 if (get_var_number(&var2) != 0) 1795 result = TRUE; 1796 clear_var(&var2); 1797 } 1798 if (evaluate) 1799 { 1800 retvar->var_type = VAR_NUMBER; 1801 retvar->var_val.var_number = result; 1802 } 1803 } 1804 1805 return OK; 1806 } 1807 1808 /* 1809 * Handle second level expression: 1810 * expr3 && expr3 && expr3 logical AND 1811 * 1812 * "arg" must point to the first non-white of the expression. 1813 * "arg" is advanced to the next non-white after the recognized expression. 1814 * 1815 * Return OK or FAIL. 1816 */ 1817 static int 1818 eval3(arg, retvar, evaluate) 1819 char_u **arg; 1820 VAR retvar; 1821 int evaluate; 1822 { 1823 var var2; 1824 long result; 1825 int first; 1826 1827 /* 1828 * Get the first variable. 1829 */ 1830 if (eval4(arg, retvar, evaluate) == FAIL) 1831 return FAIL; 1832 1833 /* 1834 * Repeat until there is no following "&&". 1835 */ 1836 first = TRUE; 1837 result = TRUE; 1838 while ((*arg)[0] == '&' && (*arg)[1] == '&') 1839 { 1840 if (evaluate && first) 1841 { 1842 if (get_var_number(retvar) == 0) 1843 result = FALSE; 1844 clear_var(retvar); 1845 first = FALSE; 1846 } 1847 1848 /* 1849 * Get the second variable. 1850 */ 1851 *arg = skipwhite(*arg + 2); 1852 if (eval4(arg, &var2, evaluate && result) == FAIL) 1853 return FAIL; 1854 1855 /* 1856 * Compute the result. 1857 */ 1858 if (evaluate && result) 1859 { 1860 if (get_var_number(&var2) == 0) 1861 result = FALSE; 1862 clear_var(&var2); 1863 } 1864 if (evaluate) 1865 { 1866 retvar->var_type = VAR_NUMBER; 1867 retvar->var_val.var_number = result; 1868 } 1869 } 1870 1871 return OK; 1872 } 1873 1874 /* 1875 * Handle third level expression: 1876 * var1 == var2 1877 * var1 =~ var2 1878 * var1 != var2 1879 * var1 !~ var2 1880 * var1 > var2 1881 * var1 >= var2 1882 * var1 < var2 1883 * var1 <= var2 1884 * 1885 * "arg" must point to the first non-white of the expression. 1886 * "arg" is advanced to the next non-white after the recognized expression. 1887 * 1888 * Return OK or FAIL. 1889 */ 1890 static int 1891 eval4(arg, retvar, evaluate) 1892 char_u **arg; 1893 VAR retvar; 1894 int evaluate; 1895 { 1896 var var2; 1897 char_u *p; 1898 int i; 1899 exptype_T type = TYPE_UNKNOWN; 1900 int len = 2; 1901 long n1, n2; 1902 char_u *s1, *s2; 1903 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 1904 regmatch_T regmatch; 1905 int ic; 1906 char_u *save_cpo; 1907 1908 /* 1909 * Get the first variable. 1910 */ 1911 if (eval5(arg, retvar, evaluate) == FAIL) 1912 return FAIL; 1913 1914 p = *arg; 1915 switch (p[0]) 1916 { 1917 case '=': if (p[1] == '=') 1918 type = TYPE_EQUAL; 1919 else if (p[1] == '~') 1920 type = TYPE_MATCH; 1921 break; 1922 case '!': if (p[1] == '=') 1923 type = TYPE_NEQUAL; 1924 else if (p[1] == '~') 1925 type = TYPE_NOMATCH; 1926 break; 1927 case '>': if (p[1] != '=') 1928 { 1929 type = TYPE_GREATER; 1930 len = 1; 1931 } 1932 else 1933 type = TYPE_GEQUAL; 1934 break; 1935 case '<': if (p[1] != '=') 1936 { 1937 type = TYPE_SMALLER; 1938 len = 1; 1939 } 1940 else 1941 type = TYPE_SEQUAL; 1942 break; 1943 } 1944 1945 /* 1946 * If there is a comparitive operator, use it. 1947 */ 1948 if (type != TYPE_UNKNOWN) 1949 { 1950 /* extra question mark appended: ignore case */ 1951 if (p[len] == '?') 1952 { 1953 ic = TRUE; 1954 ++len; 1955 } 1956 /* extra '#' appended: match case */ 1957 else if (p[len] == '#') 1958 { 1959 ic = FALSE; 1960 ++len; 1961 } 1962 /* nothing appened: use 'ignorecase' */ 1963 else 1964 ic = p_ic; 1965 1966 /* 1967 * Get the second variable. 1968 */ 1969 *arg = skipwhite(p + len); 1970 if (eval5(arg, &var2, evaluate) == FAIL) 1971 { 1972 clear_var(retvar); 1973 return FAIL; 1974 } 1975 1976 if (evaluate) 1977 { 1978 /* 1979 * If one of the two variables is a number, compare as a number. 1980 * When using "=~" or "!~", always compare as string. 1981 */ 1982 if ((retvar->var_type == VAR_NUMBER || var2.var_type == VAR_NUMBER) 1983 && type != TYPE_MATCH && type != TYPE_NOMATCH) 1984 { 1985 n1 = get_var_number(retvar); 1986 n2 = get_var_number(&var2); 1987 switch (type) 1988 { 1989 case TYPE_EQUAL: n1 = (n1 == n2); break; 1990 case TYPE_NEQUAL: n1 = (n1 != n2); break; 1991 case TYPE_GREATER: n1 = (n1 > n2); break; 1992 case TYPE_GEQUAL: n1 = (n1 >= n2); break; 1993 case TYPE_SMALLER: n1 = (n1 < n2); break; 1994 case TYPE_SEQUAL: n1 = (n1 <= n2); break; 1995 case TYPE_UNKNOWN: 1996 case TYPE_MATCH: 1997 case TYPE_NOMATCH: break; /* avoid gcc warning */ 1998 } 1999 } 2000 else 2001 { 2002 s1 = get_var_string_buf(retvar, buf1); 2003 s2 = get_var_string_buf(&var2, buf2); 2004 if (type != TYPE_MATCH && type != TYPE_NOMATCH) 2005 i = ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2); 2006 else 2007 i = 0; 2008 n1 = FALSE; 2009 switch (type) 2010 { 2011 case TYPE_EQUAL: n1 = (i == 0); break; 2012 case TYPE_NEQUAL: n1 = (i != 0); break; 2013 case TYPE_GREATER: n1 = (i > 0); break; 2014 case TYPE_GEQUAL: n1 = (i >= 0); break; 2015 case TYPE_SMALLER: n1 = (i < 0); break; 2016 case TYPE_SEQUAL: n1 = (i <= 0); break; 2017 2018 case TYPE_MATCH: 2019 case TYPE_NOMATCH: 2020 /* avoid 'l' flag in 'cpoptions' */ 2021 save_cpo = p_cpo; 2022 p_cpo = (char_u *)""; 2023 regmatch.regprog = vim_regcomp(s2, 2024 RE_MAGIC + RE_STRING); 2025 regmatch.rm_ic = ic; 2026 if (regmatch.regprog != NULL) 2027 { 2028 n1 = vim_regexec_nl(®match, s1, (colnr_T)0); 2029 vim_free(regmatch.regprog); 2030 if (type == TYPE_NOMATCH) 2031 n1 = !n1; 2032 } 2033 p_cpo = save_cpo; 2034 break; 2035 2036 case TYPE_UNKNOWN: break; /* avoid gcc warning */ 2037 } 2038 } 2039 clear_var(retvar); 2040 clear_var(&var2); 2041 retvar->var_type = VAR_NUMBER; 2042 retvar->var_val.var_number = n1; 2043 } 2044 } 2045 2046 return OK; 2047 } 2048 2049 /* 2050 * Handle fourth level expression: 2051 * + number addition 2052 * - number subtraction 2053 * . string concatenation 2054 * 2055 * "arg" must point to the first non-white of the expression. 2056 * "arg" is advanced to the next non-white after the recognized expression. 2057 * 2058 * Return OK or FAIL. 2059 */ 2060 static int 2061 eval5(arg, retvar, evaluate) 2062 char_u **arg; 2063 VAR retvar; 2064 int evaluate; 2065 { 2066 var var2; 2067 int op; 2068 long n1, n2; 2069 char_u *s1, *s2; 2070 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; 2071 char_u *p; 2072 2073 /* 2074 * Get the first variable. 2075 */ 2076 if (eval6(arg, retvar, evaluate) == FAIL) 2077 return FAIL; 2078 2079 /* 2080 * Repeat computing, until no '+', '-' or '.' is following. 2081 */ 2082 for (;;) 2083 { 2084 op = **arg; 2085 if (op != '+' && op != '-' && op != '.') 2086 break; 2087 2088 /* 2089 * Get the second variable. 2090 */ 2091 *arg = skipwhite(*arg + 1); 2092 if (eval6(arg, &var2, evaluate) == FAIL) 2093 { 2094 clear_var(retvar); 2095 return FAIL; 2096 } 2097 2098 if (evaluate) 2099 { 2100 /* 2101 * Compute the result. 2102 */ 2103 if (op == '.') 2104 { 2105 s1 = get_var_string_buf(retvar, buf1); 2106 s2 = get_var_string_buf(&var2, buf2); 2107 op = (int)STRLEN(s1); 2108 p = alloc((unsigned)(op + STRLEN(s2) + 1)); 2109 if (p != NULL) 2110 { 2111 STRCPY(p, s1); 2112 STRCPY(p + op, s2); 2113 } 2114 clear_var(retvar); 2115 retvar->var_type = VAR_STRING; 2116 retvar->var_val.var_string = p; 2117 } 2118 else 2119 { 2120 n1 = get_var_number(retvar); 2121 n2 = get_var_number(&var2); 2122 clear_var(retvar); 2123 if (op == '+') 2124 n1 = n1 + n2; 2125 else 2126 n1 = n1 - n2; 2127 retvar->var_type = VAR_NUMBER; 2128 retvar->var_val.var_number = n1; 2129 } 2130 clear_var(&var2); 2131 } 2132 } 2133 return OK; 2134 } 2135 2136 /* 2137 * Handle fifth level expression: 2138 * * number multiplication 2139 * / number division 2140 * % number modulo 2141 * 2142 * "arg" must point to the first non-white of the expression. 2143 * "arg" is advanced to the next non-white after the recognized expression. 2144 * 2145 * Return OK or FAIL. 2146 */ 2147 static int 2148 eval6(arg, retvar, evaluate) 2149 char_u **arg; 2150 VAR retvar; 2151 int evaluate; 2152 { 2153 var var2; 2154 int op; 2155 long n1, n2; 2156 2157 /* 2158 * Get the first variable. 2159 */ 2160 if (eval7(arg, retvar, evaluate) == FAIL) 2161 return FAIL; 2162 2163 /* 2164 * Repeat computing, until no '*', '/' or '%' is following. 2165 */ 2166 for (;;) 2167 { 2168 op = **arg; 2169 if (op != '*' && op != '/' && op != '%') 2170 break; 2171 2172 if (evaluate) 2173 { 2174 n1 = get_var_number(retvar); 2175 clear_var(retvar); 2176 } 2177 else 2178 n1 = 0; 2179 2180 /* 2181 * Get the second variable. 2182 */ 2183 *arg = skipwhite(*arg + 1); 2184 if (eval7(arg, &var2, evaluate) == FAIL) 2185 return FAIL; 2186 2187 if (evaluate) 2188 { 2189 n2 = get_var_number(&var2); 2190 clear_var(&var2); 2191 2192 /* 2193 * Compute the result. 2194 */ 2195 if (op == '*') 2196 n1 = n1 * n2; 2197 else if (op == '/') 2198 { 2199 if (n2 == 0) /* give an error message? */ 2200 n1 = 0x7fffffffL; 2201 else 2202 n1 = n1 / n2; 2203 } 2204 else 2205 { 2206 if (n2 == 0) /* give an error message? */ 2207 n1 = 0; 2208 else 2209 n1 = n1 % n2; 2210 } 2211 retvar->var_type = VAR_NUMBER; 2212 retvar->var_val.var_number = n1; 2213 } 2214 } 2215 2216 return OK; 2217 } 2218 2219 /* 2220 * Handle sixth level expression: 2221 * number number constant 2222 * "string" string contstant 2223 * 'string' literal string contstant 2224 * &option-name option value 2225 * @r register contents 2226 * identifier variable value 2227 * function() function call 2228 * $VAR environment variable 2229 * (expression) nested expression 2230 * 2231 * Also handle: 2232 * ! in front logical NOT 2233 * - in front unary minus 2234 * + in front unary plus (ignored) 2235 * trailing [] subscript in String 2236 * 2237 * "arg" must point to the first non-white of the expression. 2238 * "arg" is advanced to the next non-white after the recognized expression. 2239 * 2240 * Return OK or FAIL. 2241 */ 2242 static int 2243 eval7(arg, retvar, evaluate) 2244 char_u **arg; 2245 VAR retvar; 2246 int evaluate; 2247 { 2248 var var2; 2249 long n; 2250 int len; 2251 char_u *s; 2252 int val; 2253 char_u *start_leader, *end_leader; 2254 int ret = OK; 2255 char_u *alias; 2256 2257 /* 2258 * Initialise variable so that clear_var() can't mistake this for a string 2259 * and free a string that isn't there. 2260 */ 2261 retvar->var_type = VAR_UNKNOWN; 2262 2263 /* 2264 * Skip '!' and '-' characters. They are handled later. 2265 */ 2266 start_leader = *arg; 2267 while (**arg == '!' || **arg == '-' || **arg == '+') 2268 *arg = skipwhite(*arg + 1); 2269 end_leader = *arg; 2270 2271 switch (**arg) 2272 { 2273 /* 2274 * Number constant. 2275 */ 2276 case '0': 2277 case '1': 2278 case '2': 2279 case '3': 2280 case '4': 2281 case '5': 2282 case '6': 2283 case '7': 2284 case '8': 2285 case '9': 2286 vim_str2nr(*arg, NULL, &len, TRUE, TRUE, &n, NULL); 2287 *arg += len; 2288 if (evaluate) 2289 { 2290 retvar->var_type = VAR_NUMBER; 2291 retvar->var_val.var_number = n; 2292 } 2293 break; 2294 2295 /* 2296 * String constant: "string". 2297 */ 2298 case '"': ret = get_string_var(arg, retvar, evaluate); 2299 break; 2300 2301 /* 2302 * Literal string constant: 'string'. 2303 */ 2304 case '\'': ret = get_lit_string_var(arg, retvar, evaluate); 2305 break; 2306 2307 /* 2308 * Option value: &name 2309 */ 2310 case '&': ret = get_option_var(arg, retvar, evaluate); 2311 break; 2312 2313 /* 2314 * Environment variable: $VAR. 2315 */ 2316 case '$': ret = get_env_var(arg, retvar, evaluate); 2317 break; 2318 2319 /* 2320 * Register contents: @r. 2321 */ 2322 case '@': ++*arg; 2323 if (evaluate) 2324 { 2325 retvar->var_type = VAR_STRING; 2326 retvar->var_val.var_string = get_reg_contents(**arg, FALSE); 2327 } 2328 if (**arg != NUL) 2329 ++*arg; 2330 break; 2331 2332 /* 2333 * nested expression: (expression). 2334 */ 2335 case '(': *arg = skipwhite(*arg + 1); 2336 ret = eval1(arg, retvar, evaluate); /* recursive! */ 2337 if (**arg == ')') 2338 ++*arg; 2339 else if (ret == OK) 2340 { 2341 EMSG(_("E110: Missing ')'")); 2342 clear_var(retvar); 2343 ret = FAIL; 2344 } 2345 break; 2346 2347 /* 2348 * Must be a variable or function name then. 2349 */ 2350 default: s = *arg; 2351 len = get_func_len(arg, &alias, evaluate); 2352 if (alias != NULL) 2353 s = alias; 2354 2355 if (len == 0) 2356 ret = FAIL; 2357 else 2358 { 2359 if (**arg == '(') /* recursive! */ 2360 { 2361 ret = get_func_var(s, len, retvar, arg, 2362 curwin->w_cursor.lnum, curwin->w_cursor.lnum, 2363 &len, evaluate); 2364 /* Stop the expression evaluation when immediately 2365 * aborting on error, or when an interrupt occurred or 2366 * an exception was thrown but not caught. */ 2367 if (aborting()) 2368 { 2369 if (ret == OK) 2370 clear_var(retvar); 2371 ret = FAIL; 2372 } 2373 } 2374 else if (evaluate) 2375 ret = get_var_var(s, len, retvar); 2376 } 2377 2378 if (alias != NULL) 2379 vim_free(alias); 2380 2381 break; 2382 } 2383 *arg = skipwhite(*arg); 2384 2385 /* 2386 * Handle expr[expr] subscript. 2387 */ 2388 if (**arg == '[' && ret == OK) 2389 { 2390 /* 2391 * Get the variable from inside the []. 2392 */ 2393 *arg = skipwhite(*arg + 1); 2394 if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ 2395 { 2396 clear_var(retvar); 2397 return FAIL; 2398 } 2399 2400 /* Check for the ']'. */ 2401 if (**arg != ']') 2402 { 2403 EMSG(_("E111: Missing ']'")); 2404 clear_var(retvar); 2405 clear_var(&var2); 2406 return FAIL; 2407 } 2408 2409 if (evaluate) 2410 { 2411 n = get_var_number(&var2); 2412 clear_var(&var2); 2413 2414 /* 2415 * The resulting variable is a string of a single character. 2416 * If the index is too big or negative, the result is empty. 2417 */ 2418 s = get_var_string(retvar); 2419 if (n >= (long)STRLEN(s) || n < 0) 2420 s = NULL; 2421 else 2422 s = vim_strnsave(s + n, 1); 2423 clear_var(retvar); 2424 retvar->var_type = VAR_STRING; 2425 retvar->var_val.var_string = s; 2426 } 2427 *arg = skipwhite(*arg + 1); /* skip the ']' */ 2428 } 2429 2430 /* 2431 * Apply logical NOT and unary '-', from right to left, ignore '+'. 2432 */ 2433 if (ret == OK && evaluate && end_leader > start_leader) 2434 { 2435 val = get_var_number(retvar); 2436 while (end_leader > start_leader) 2437 { 2438 --end_leader; 2439 if (*end_leader == '!') 2440 val = !val; 2441 else if (*end_leader == '-') 2442 val = -val; 2443 } 2444 clear_var(retvar); 2445 retvar->var_type = VAR_NUMBER; 2446 retvar->var_val.var_number = val; 2447 } 2448 2449 return ret; 2450 } 2451 2452 /* 2453 * Get an option value. 2454 * "arg" points to the '&' or '+' before the option name. 2455 * "arg" is advanced to character after the option name. 2456 * Return OK or FAIL. 2457 */ 2458 static int 2459 get_option_var(arg, retvar, evaluate) 2460 char_u **arg; 2461 VAR retvar; /* when NULL, only check if option exists */ 2462 int evaluate; 2463 { 2464 char_u *option_end; 2465 long numval; 2466 char_u *stringval; 2467 int opt_type; 2468 int c; 2469 int working = (**arg == '+'); /* has("+option") */ 2470 int ret = OK; 2471 int opt_flags; 2472 2473 /* 2474 * Isolate the option name and find its value. 2475 */ 2476 option_end = find_option_end(arg, &opt_flags); 2477 if (option_end == NULL) 2478 { 2479 if (retvar != NULL) 2480 EMSG2(_("E112: Option name missing: %s"), *arg); 2481 return FAIL; 2482 } 2483 2484 if (!evaluate) 2485 { 2486 *arg = option_end; 2487 return OK; 2488 } 2489 2490 c = *option_end; 2491 *option_end = NUL; 2492 opt_type = get_option_value(*arg, &numval, 2493 retvar == NULL ? NULL : &stringval, opt_flags); 2494 2495 if (opt_type == -3) /* invalid name */ 2496 { 2497 if (retvar != NULL) 2498 EMSG2(_("E113: Unknown option: %s"), *arg); 2499 ret = FAIL; 2500 } 2501 else if (retvar != NULL) 2502 { 2503 if (opt_type == -2) /* hidden string option */ 2504 { 2505 retvar->var_type = VAR_STRING; 2506 retvar->var_val.var_string = NULL; 2507 } 2508 else if (opt_type == -1) /* hidden number option */ 2509 { 2510 retvar->var_type = VAR_NUMBER; 2511 retvar->var_val.var_number = 0; 2512 } 2513 else if (opt_type == 1) /* number option */ 2514 { 2515 retvar->var_type = VAR_NUMBER; 2516 retvar->var_val.var_number = numval; 2517 } 2518 else /* string option */ 2519 { 2520 retvar->var_type = VAR_STRING; 2521 retvar->var_val.var_string = stringval; 2522 } 2523 } 2524 else if (working && (opt_type == -2 || opt_type == -1)) 2525 ret = FAIL; 2526 2527 *option_end = c; /* put back for error messages */ 2528 *arg = option_end; 2529 2530 return ret; 2531 } 2532 2533 /* 2534 * Allocate a variable for a string constant. 2535 * Return OK or FAIL. 2536 */ 2537 static int 2538 get_string_var(arg, retvar, evaluate) 2539 char_u **arg; 2540 VAR retvar; 2541 int evaluate; 2542 { 2543 char_u *p; 2544 char_u *name; 2545 int i; 2546 int extra = 0; 2547 2548 /* 2549 * Find the end of the string, skipping backslashed characters. 2550 */ 2551 for (p = *arg + 1; *p && *p != '"'; ++p) 2552 { 2553 if (*p == '\\' && p[1] != NUL) 2554 { 2555 ++p; 2556 /* A "\<x>" form occupies at least 4 characters, and produces up 2557 * to 6 characters: reserve space for 2 extra */ 2558 if (*p == '<') 2559 extra += 2; 2560 } 2561 #ifdef FEAT_MBYTE 2562 if (has_mbyte) 2563 p += (*mb_ptr2len_check)(p) - 1; 2564 #endif 2565 } 2566 2567 if (*p != '"') 2568 { 2569 EMSG2(_("E114: Missing quote: %s"), *arg); 2570 return FAIL; 2571 } 2572 2573 /* If only parsing, set *arg and return here */ 2574 if (!evaluate) 2575 { 2576 *arg = p + 1; 2577 return OK; 2578 } 2579 2580 /* 2581 * Copy the string into allocated memory, handling backslashed 2582 * characters. 2583 */ 2584 name = alloc((unsigned)(p - *arg + extra)); 2585 if (name == NULL) 2586 return FAIL; 2587 2588 i = 0; 2589 for (p = *arg + 1; *p && *p != '"'; ++p) 2590 { 2591 if (*p == '\\') 2592 { 2593 switch (*++p) 2594 { 2595 case 'b': name[i++] = BS; break; 2596 case 'e': name[i++] = ESC; break; 2597 case 'f': name[i++] = FF; break; 2598 case 'n': name[i++] = NL; break; 2599 case 'r': name[i++] = CAR; break; 2600 case 't': name[i++] = TAB; break; 2601 2602 case 'X': /* hex: "\x1", "\x12" */ 2603 case 'x': 2604 case 'u': /* Unicode: "\u0023" */ 2605 case 'U': 2606 if (vim_isxdigit(p[1])) 2607 { 2608 int n, nr; 2609 int c = toupper(*p); 2610 2611 if (c == 'X') 2612 n = 2; 2613 else 2614 n = 4; 2615 nr = 0; 2616 while (--n >= 0 && vim_isxdigit(p[1])) 2617 { 2618 ++p; 2619 nr = (nr << 4) + hex2nr(*p); 2620 } 2621 #ifdef FEAT_MBYTE 2622 /* For "\u" store the number according to 2623 * 'encoding'. */ 2624 if (c != 'X') 2625 i += (*mb_char2bytes)(nr, name + i); 2626 else 2627 #endif 2628 name[i++] = nr; 2629 } 2630 else 2631 name[i++] = *p; 2632 break; 2633 2634 /* octal: "\1", "\12", "\123" */ 2635 case '0': 2636 case '1': 2637 case '2': 2638 case '3': 2639 case '4': 2640 case '5': 2641 case '6': 2642 case '7': name[i] = *p - '0'; 2643 if (p[1] >= '0' && p[1] <= '7') 2644 { 2645 ++p; 2646 name[i] = (name[i] << 3) + *p - '0'; 2647 if (p[1] >= '0' && p[1] <= '7') 2648 { 2649 ++p; 2650 name[i] = (name[i] << 3) + *p - '0'; 2651 } 2652 } 2653 ++i; 2654 break; 2655 2656 /* Special key, e.g.: "\<C-W>" */ 2657 case '<': extra = trans_special(&p, name + i, TRUE); 2658 if (extra != 0) 2659 { 2660 i += extra; 2661 --p; 2662 break; 2663 } 2664 /* FALLTHROUGH */ 2665 2666 default: name[i++] = *p; 2667 break; 2668 } 2669 } 2670 else 2671 name[i++] = *p; 2672 2673 #ifdef FEAT_MBYTE 2674 /* For a multi-byte character copy the bytes after the first one. */ 2675 if (has_mbyte) 2676 { 2677 int l = (*mb_ptr2len_check)(p); 2678 2679 while (--l > 0) 2680 name[i++] = *++p; 2681 } 2682 #endif 2683 } 2684 name[i] = NUL; 2685 *arg = p + 1; 2686 2687 retvar->var_type = VAR_STRING; 2688 retvar->var_val.var_string = name; 2689 2690 return OK; 2691 } 2692 2693 /* 2694 * Allocate a variable for an backtick-string constant. 2695 * Return OK or FAIL. 2696 */ 2697 static int 2698 get_lit_string_var(arg, retvar, evaluate) 2699 char_u **arg; 2700 VAR retvar; 2701 int evaluate; 2702 { 2703 char_u *p; 2704 char_u *name; 2705 2706 /* 2707 * Find the end of the string. 2708 */ 2709 p = vim_strchr(*arg + 1, '\''); 2710 if (p == NULL) 2711 { 2712 EMSG2(_("E115: Missing quote: %s"), *arg); 2713 return FAIL; 2714 } 2715 2716 if (evaluate) 2717 { 2718 /* 2719 * Copy the string into allocated memory. 2720 */ 2721 name = vim_strnsave(*arg + 1, (int)(p - (*arg + 1))); 2722 if (name == NULL) 2723 return FAIL; 2724 2725 retvar->var_type = VAR_STRING; 2726 retvar->var_val.var_string = name; 2727 } 2728 2729 *arg = p + 1; 2730 2731 return OK; 2732 } 2733 2734 /* 2735 * Get the value of an environment variable. 2736 * "arg" is pointing to the '$'. It is advanced to after the name. 2737 * If the environment variable was not set, silently assume it is empty. 2738 * Always return OK. 2739 */ 2740 static int 2741 get_env_var(arg, retvar, evaluate) 2742 char_u **arg; 2743 VAR retvar; 2744 int evaluate; 2745 { 2746 char_u *string = NULL; 2747 int len; 2748 int cc; 2749 char_u *name; 2750 2751 ++*arg; 2752 name = *arg; 2753 len = get_env_len(arg); 2754 if (evaluate) 2755 { 2756 if (len != 0) 2757 { 2758 cc = name[len]; 2759 name[len] = NUL; 2760 /* first try mch_getenv(), fast for normal environment vars */ 2761 string = mch_getenv(name); 2762 if (string != NULL && *string != NUL) 2763 string = vim_strsave(string); 2764 else 2765 { 2766 /* next try expanding things like $VIM and ${HOME} */ 2767 string = expand_env_save(name - 1); 2768 if (string != NULL && *string == '$') 2769 { 2770 vim_free(string); 2771 string = NULL; 2772 } 2773 } 2774 name[len] = cc; 2775 } 2776 retvar->var_type = VAR_STRING; 2777 retvar->var_val.var_string = string; 2778 } 2779 2780 return OK; 2781 } 2782 2783 /* 2784 * Array with names and number of arguments of all internal functions 2785 * MUST BE KEPT SORTED IN strcmp() ORDER FOR BINARY SEARCH! 2786 */ 2787 static struct fst 2788 { 2789 char *f_name; /* function name */ 2790 char f_min_argc; /* minimal number of arguments */ 2791 char f_max_argc; /* maximal number of arguments */ 2792 void (*f_func) __ARGS((VAR args, VAR rvar)); /* impl. function */ 2793 } functions[] = 2794 { 2795 {"append", 2, 2, f_append}, 2796 {"argc", 0, 0, f_argc}, 2797 {"argidx", 0, 0, f_argidx}, 2798 {"argv", 1, 1, f_argv}, 2799 {"browse", 4, 4, f_browse}, 2800 {"bufexists", 1, 1, f_bufexists}, 2801 {"buffer_exists", 1, 1, f_bufexists}, /* obsolete */ 2802 {"buffer_name", 1, 1, f_bufname}, /* obsolete */ 2803 {"buffer_number", 1, 1, f_bufnr}, /* obsolete */ 2804 {"buflisted", 1, 1, f_buflisted}, 2805 {"bufloaded", 1, 1, f_bufloaded}, 2806 {"bufname", 1, 1, f_bufname}, 2807 {"bufnr", 1, 1, f_bufnr}, 2808 {"bufwinnr", 1, 1, f_bufwinnr}, 2809 {"byte2line", 1, 1, f_byte2line}, 2810 {"char2nr", 1, 1, f_char2nr}, 2811 {"cindent", 1, 1, f_cindent}, 2812 {"col", 1, 1, f_col}, 2813 {"confirm", 1, 4, f_confirm}, 2814 {"cscope_connection",0,3, f_cscope_connection}, 2815 {"cursor", 2, 2, f_cursor}, 2816 {"delete", 1, 1, f_delete}, 2817 {"did_filetype", 0, 0, f_did_filetype}, 2818 {"escape", 2, 2, f_escape}, 2819 {"eventhandler", 0, 0, f_eventhandler}, 2820 {"executable", 1, 1, f_executable}, 2821 {"exists", 1, 1, f_exists}, 2822 {"expand", 1, 2, f_expand}, 2823 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ 2824 {"filereadable", 1, 1, f_filereadable}, 2825 {"filewritable", 1, 1, f_filewritable}, 2826 {"fnamemodify", 2, 2, f_fnamemodify}, 2827 {"foldclosed", 1, 1, f_foldclosed}, 2828 {"foldclosedend", 1, 1, f_foldclosedend}, 2829 {"foldlevel", 1, 1, f_foldlevel}, 2830 {"foldtext", 0, 0, f_foldtext}, 2831 {"foreground", 0, 0, f_foreground}, 2832 {"getbufvar", 2, 2, f_getbufvar}, 2833 {"getchar", 0, 1, f_getchar}, 2834 {"getcharmod", 0, 0, f_getcharmod}, 2835 {"getcmdline", 0, 0, f_getcmdline}, 2836 {"getcmdpos", 0, 0, f_getcmdpos}, 2837 {"getcwd", 0, 0, f_getcwd}, 2838 {"getfsize", 1, 1, f_getfsize}, 2839 {"getftime", 1, 1, f_getftime}, 2840 {"getline", 1, 1, f_getline}, 2841 {"getreg", 0, 1, f_getreg}, 2842 {"getregtype", 0, 1, f_getregtype}, 2843 {"getwinposx", 0, 0, f_getwinposx}, 2844 {"getwinposy", 0, 0, f_getwinposy}, 2845 {"getwinvar", 2, 2, f_getwinvar}, 2846 {"glob", 1, 1, f_glob}, 2847 {"globpath", 2, 2, f_globpath}, 2848 {"has", 1, 1, f_has}, 2849 {"hasmapto", 1, 2, f_hasmapto}, 2850 {"highlightID", 1, 1, f_hlID}, /* obsolete */ 2851 {"highlight_exists",1, 1, f_hlexists}, /* obsolete */ 2852 {"histadd", 2, 2, f_histadd}, 2853 {"histdel", 1, 2, f_histdel}, 2854 {"histget", 1, 2, f_histget}, 2855 {"histnr", 1, 1, f_histnr}, 2856 {"hlID", 1, 1, f_hlID}, 2857 {"hlexists", 1, 1, f_hlexists}, 2858 {"hostname", 0, 0, f_hostname}, 2859 {"iconv", 3, 3, f_iconv}, 2860 {"indent", 1, 1, f_indent}, 2861 {"input", 1, 2, f_input}, 2862 {"inputdialog", 1, 3, f_inputdialog}, 2863 {"inputrestore", 0, 0, f_inputrestore}, 2864 {"inputsave", 0, 0, f_inputsave}, 2865 {"inputsecret", 1, 2, f_inputsecret}, 2866 {"isdirectory", 1, 1, f_isdirectory}, 2867 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ 2868 {"libcall", 3, 3, f_libcall}, 2869 {"libcallnr", 3, 3, f_libcallnr}, 2870 {"line", 1, 1, f_line}, 2871 {"line2byte", 1, 1, f_line2byte}, 2872 {"lispindent", 1, 1, f_lispindent}, 2873 {"localtime", 0, 0, f_localtime}, 2874 {"maparg", 1, 2, f_maparg}, 2875 {"mapcheck", 1, 2, f_mapcheck}, 2876 {"match", 2, 3, f_match}, 2877 {"matchend", 2, 3, f_matchend}, 2878 {"matchstr", 2, 3, f_matchstr}, 2879 {"mode", 0, 0, f_mode}, 2880 {"nextnonblank", 1, 1, f_nextnonblank}, 2881 {"nr2char", 1, 1, f_nr2char}, 2882 {"prevnonblank", 1, 1, f_prevnonblank}, 2883 {"remote_expr", 2, 3, f_remote_expr}, 2884 {"remote_foreground", 1, 1, f_remote_foreground}, 2885 {"remote_peek", 1, 2, f_remote_peek}, 2886 {"remote_read", 1, 1, f_remote_read}, 2887 {"remote_send", 2, 3, f_remote_send}, 2888 {"rename", 2, 2, f_rename}, 2889 {"resolve", 1, 1, f_resolve}, 2890 {"search", 1, 2, f_search}, 2891 {"searchpair", 3, 5, f_searchpair}, 2892 {"server2client", 2, 2, f_server2client}, 2893 {"serverlist", 0, 0, f_serverlist}, 2894 {"setbufvar", 3, 3, f_setbufvar}, 2895 {"setcmdpos", 1, 1, f_setcmdpos}, 2896 {"setline", 2, 2, f_setline}, 2897 {"setreg", 2, 3, f_setreg}, 2898 {"setwinvar", 3, 3, f_setwinvar}, 2899 {"simplify", 1, 1, f_simplify}, 2900 #ifdef HAVE_STRFTIME 2901 {"strftime", 1, 2, f_strftime}, 2902 #endif 2903 {"stridx", 2, 2, f_stridx}, 2904 {"strlen", 1, 1, f_strlen}, 2905 {"strpart", 2, 3, f_strpart}, 2906 {"strridx", 2, 2, f_strridx}, 2907 {"strtrans", 1, 1, f_strtrans}, 2908 {"submatch", 1, 1, f_submatch}, 2909 {"substitute", 4, 4, f_substitute}, 2910 {"synID", 3, 3, f_synID}, 2911 {"synIDattr", 2, 3, f_synIDattr}, 2912 {"synIDtrans", 1, 1, f_synIDtrans}, 2913 {"system", 1, 1, f_system}, 2914 {"tempname", 0, 0, f_tempname}, 2915 {"tolower", 1, 1, f_tolower}, 2916 {"toupper", 1, 1, f_toupper}, 2917 {"type", 1, 1, f_type}, 2918 {"virtcol", 1, 1, f_virtcol}, 2919 {"visualmode", 0, 1, f_visualmode}, 2920 {"winbufnr", 1, 1, f_winbufnr}, 2921 {"wincol", 0, 0, f_wincol}, 2922 {"winheight", 1, 1, f_winheight}, 2923 {"winline", 0, 0, f_winline}, 2924 {"winnr", 0, 0, f_winnr}, 2925 {"winrestcmd", 0, 0, f_winrestcmd}, 2926 {"winwidth", 1, 1, f_winwidth}, 2927 }; 2928 2929 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 2930 2931 /* 2932 * Function given to ExpandGeneric() to obtain the list of internal 2933 * or user defined function names. 2934 */ 2935 char_u * 2936 get_function_name(xp, idx) 2937 expand_T *xp; 2938 int idx; 2939 { 2940 static int intidx = -1; 2941 char_u *name; 2942 2943 if (idx == 0) 2944 intidx = -1; 2945 if (intidx < 0) 2946 { 2947 name = get_user_func_name(xp, idx); 2948 if (name != NULL) 2949 return name; 2950 } 2951 if (++intidx < (int)(sizeof(functions) / sizeof(struct fst))) 2952 { 2953 STRCPY(IObuff, functions[intidx].f_name); 2954 STRCAT(IObuff, "("); 2955 if (functions[intidx].f_max_argc == 0) 2956 STRCAT(IObuff, ")"); 2957 return IObuff; 2958 } 2959 2960 return NULL; 2961 } 2962 2963 /* 2964 * Function given to ExpandGeneric() to obtain the list of internal or 2965 * user defined variable or function names. 2966 */ 2967 /*ARGSUSED*/ 2968 char_u * 2969 get_expr_name(xp, idx) 2970 expand_T *xp; 2971 int idx; 2972 { 2973 static int intidx = -1; 2974 char_u *name; 2975 2976 if (idx == 0) 2977 intidx = -1; 2978 if (intidx < 0) 2979 { 2980 name = get_function_name(xp, idx); 2981 if (name != NULL) 2982 return name; 2983 } 2984 return get_user_var_name(xp, ++intidx); 2985 } 2986 2987 #endif /* FEAT_CMDL_COMPL */ 2988 2989 /* 2990 * Find internal function in table above. 2991 * Return index, or -1 if not found 2992 */ 2993 static int 2994 find_internal_func(name) 2995 char_u *name; /* name of the function */ 2996 { 2997 int first = 0; 2998 int last = (int)(sizeof(functions) / sizeof(struct fst)) - 1; 2999 int cmp; 3000 int x; 3001 3002 /* 3003 * Find the function name in the table. Binary search. 3004 */ 3005 while (first <= last) 3006 { 3007 x = first + ((unsigned)(last - first) >> 1); 3008 cmp = STRCMP(name, functions[x].f_name); 3009 if (cmp < 0) 3010 last = x - 1; 3011 else if (cmp > 0) 3012 first = x + 1; 3013 else 3014 return x; 3015 } 3016 return -1; 3017 } 3018 3019 /* 3020 * Allocate a variable for the result of a function. 3021 * Return OK or FAIL. 3022 */ 3023 static int 3024 get_func_var(name, len, retvar, arg, firstline, lastline, doesrange, evaluate) 3025 char_u *name; /* name of the function */ 3026 int len; /* length of "name" */ 3027 VAR retvar; 3028 char_u **arg; /* argument, pointing to the '(' */ 3029 linenr_T firstline; /* first line of range */ 3030 linenr_T lastline; /* last line of range */ 3031 int *doesrange; /* return: function handled range */ 3032 int evaluate; 3033 { 3034 char_u *argp; 3035 int ret = OK; 3036 #define MAX_FUNC_ARGS 20 3037 var argvars[MAX_FUNC_ARGS]; /* vars for arguments */ 3038 int argcount = 0; /* number of arguments found */ 3039 3040 /* 3041 * Get the arguments. 3042 */ 3043 argp = *arg; 3044 while (argcount < MAX_FUNC_ARGS) 3045 { 3046 argp = skipwhite(argp + 1); /* skip the '(' or ',' */ 3047 if (*argp == ')' || *argp == ',' || *argp == NUL) 3048 break; 3049 argvars[argcount].var_name = NULL; /* the name is not stored */ 3050 if (eval1(&argp, &argvars[argcount], evaluate) == FAIL) 3051 { 3052 ret = FAIL; 3053 break; 3054 } 3055 ++argcount; 3056 if (*argp != ',') 3057 break; 3058 } 3059 if (*argp == ')') 3060 ++argp; 3061 else 3062 ret = FAIL; 3063 3064 if (ret == OK) 3065 ret = call_func(name, len, retvar, argcount, argvars, 3066 firstline, lastline, doesrange, evaluate); 3067 else if (!aborting()) 3068 EMSG2(_("E116: Invalid arguments for function %s"), name); 3069 3070 while (--argcount >= 0) 3071 clear_var(&argvars[argcount]); 3072 3073 *arg = skipwhite(argp); 3074 return ret; 3075 } 3076 3077 3078 /* 3079 * Call a function with its resolved parameters 3080 * Return OK or FAIL. 3081 */ 3082 static int 3083 call_func(name, len, retvar, argcount, argvars, firstline, lastline, 3084 doesrange, evaluate) 3085 char_u *name; /* name of the function */ 3086 int len; /* length of "name" */ 3087 VAR retvar; /* return value goes here */ 3088 int argcount; /* number of "argvars" */ 3089 VAR argvars; /* vars for arguments */ 3090 linenr_T firstline; /* first line of range */ 3091 linenr_T lastline; /* last line of range */ 3092 int *doesrange; /* return: function handled range */ 3093 int evaluate; 3094 { 3095 int ret = FAIL; 3096 static char *errors[] = 3097 {N_("E117: Unknown function: %s"), 3098 N_("E118: Too many arguments for function: %s"), 3099 N_("E119: Not enough arguments for function: %s"), 3100 N_("E120: Using <SID> not in a script context: %s"), 3101 }; 3102 #define ERROR_UNKNOWN 0 3103 #define ERROR_TOOMANY 1 3104 #define ERROR_TOOFEW 2 3105 #define ERROR_SCRIPT 3 3106 #define ERROR_NONE 4 3107 #define ERROR_OTHER 5 3108 int error = ERROR_NONE; 3109 int i; 3110 int llen; 3111 ufunc_T *fp; 3112 int cc; 3113 #define FLEN_FIXED 40 3114 char_u fname_buf[FLEN_FIXED + 1]; 3115 char_u *fname; 3116 3117 /* 3118 * In a script change <SID>name() and s:name() to K_SNR 123_name(). 3119 * Change <SNR>123_name() to K_SNR 123_name(). 3120 * Use fname_buf[] when it fits, otherwise allocate memory (slow). 3121 */ 3122 cc = name[len]; 3123 name[len] = NUL; 3124 llen = eval_fname_script(name); 3125 if (llen > 0) 3126 { 3127 fname_buf[0] = K_SPECIAL; 3128 fname_buf[1] = KS_EXTRA; 3129 fname_buf[2] = (int)KE_SNR; 3130 i = 3; 3131 if (eval_fname_sid(name)) /* "<SID>" or "s:" */ 3132 { 3133 if (current_SID <= 0) 3134 error = ERROR_SCRIPT; 3135 else 3136 { 3137 sprintf((char *)fname_buf + 3, "%ld_", (long)current_SID); 3138 i = (int)STRLEN(fname_buf); 3139 } 3140 } 3141 if (i + STRLEN(name + llen) < FLEN_FIXED) 3142 { 3143 STRCPY(fname_buf + i, name + llen); 3144 fname = fname_buf; 3145 } 3146 else 3147 { 3148 fname = alloc((unsigned)(i + STRLEN(name + llen) + 1)); 3149 if (fname == NULL) 3150 error = ERROR_OTHER; 3151 else 3152 { 3153 mch_memmove(fname, fname_buf, (size_t)i); 3154 STRCPY(fname + i, name + llen); 3155 } 3156 } 3157 } 3158 else 3159 fname = name; 3160 3161 *doesrange = FALSE; 3162 3163 3164 /* execute the function if no errors detected and executing */ 3165 if (evaluate && error == ERROR_NONE) 3166 { 3167 retvar->var_type = VAR_NUMBER; /* default is number retvar */ 3168 error = ERROR_UNKNOWN; 3169 3170 if (!ASCII_ISLOWER(fname[0])) 3171 { 3172 /* 3173 * User defined function. 3174 */ 3175 fp = find_func(fname); 3176 #ifdef FEAT_AUTOCMD 3177 if (fp == NULL && apply_autocmds(EVENT_FUNCUNDEFINED, 3178 fname, fname, TRUE, NULL) 3179 #ifdef FEAT_EVAL 3180 && !aborting() 3181 #endif 3182 ) 3183 { 3184 /* executed an autocommand, search for function again */ 3185 fp = find_func(fname); 3186 } 3187 #endif 3188 if (fp != NULL) 3189 { 3190 if (fp->flags & FC_RANGE) 3191 *doesrange = TRUE; 3192 if (argcount < fp->args.ga_len) 3193 error = ERROR_TOOFEW; 3194 else if (!fp->varargs && argcount > fp->args.ga_len) 3195 error = ERROR_TOOMANY; 3196 else 3197 { 3198 /* 3199 * Call the user function. 3200 * Save and restore search patterns, script variables and 3201 * redo buffer. 3202 */ 3203 save_search_patterns(); 3204 saveRedobuff(); 3205 ++fp->calls; 3206 call_user_func(fp, argcount, argvars, retvar, 3207 firstline, lastline); 3208 --fp->calls; 3209 restoreRedobuff(); 3210 restore_search_patterns(); 3211 error = ERROR_NONE; 3212 } 3213 } 3214 } 3215 else 3216 { 3217 /* 3218 * Find the function name in the table, call its implementation. 3219 */ 3220 i = find_internal_func(fname); 3221 if (i >= 0) 3222 { 3223 if (argcount < functions[i].f_min_argc) 3224 error = ERROR_TOOFEW; 3225 else if (argcount > functions[i].f_max_argc) 3226 error = ERROR_TOOMANY; 3227 else 3228 { 3229 argvars[argcount].var_type = VAR_UNKNOWN; 3230 functions[i].f_func(argvars, retvar); 3231 error = ERROR_NONE; 3232 } 3233 } 3234 } 3235 /* 3236 * The function call (or "FuncUndefined" autocommand sequence) might 3237 * have been aborted by an error, an interrupt, or an explicitly thrown 3238 * exception that has not been caught so far. This situation can be 3239 * tested for by calling aborting(). For an error in an internal 3240 * function or for the "E132" error in call_user_func(), however, the 3241 * throw point at which the "force_abort" flag (temporarily reset by 3242 * emsg()) is normally updated has not been reached yet. We need to 3243 * update that flag first to make aborting() reliable. 3244 */ 3245 update_force_abort(); 3246 } 3247 if (error == ERROR_NONE) 3248 ret = OK; 3249 3250 /* 3251 * Report an error unless the argument evaluation or function call has been 3252 * cancelled due to an aborting error, an interrupt, or an exception. 3253 */ 3254 if (error < ERROR_NONE && !aborting()) 3255 EMSG2((char_u *)_(errors[error]), name); 3256 3257 name[len] = cc; 3258 if (fname != name && fname != fname_buf) 3259 vim_free(fname); 3260 3261 return ret; 3262 } 3263 3264 /********************************************* 3265 * Implementation of the built-in functions 3266 */ 3267 3268 /* 3269 * "append(lnum, string)" function 3270 */ 3271 static void 3272 f_append(argvars, retvar) 3273 VAR argvars; 3274 VAR retvar; 3275 { 3276 long lnum; 3277 3278 lnum = get_var_lnum(argvars); 3279 retvar->var_val.var_number = 1; /* Default: Failed */ 3280 3281 if (lnum >= 0 3282 && lnum <= curbuf->b_ml.ml_line_count 3283 && u_save(lnum, lnum + 1) == OK) 3284 { 3285 ml_append(lnum, get_var_string(&argvars[1]), (colnr_T)0, FALSE); 3286 if (curwin->w_cursor.lnum > lnum) 3287 ++curwin->w_cursor.lnum; 3288 appended_lines_mark(lnum, 1L); 3289 retvar->var_val.var_number = 0; 3290 } 3291 } 3292 3293 /* 3294 * "argc()" function 3295 */ 3296 /* ARGSUSED */ 3297 static void 3298 f_argc(argvars, retvar) 3299 VAR argvars; 3300 VAR retvar; 3301 { 3302 retvar->var_val.var_number = ARGCOUNT; 3303 } 3304 3305 /* 3306 * "argidx()" function 3307 */ 3308 /* ARGSUSED */ 3309 static void 3310 f_argidx(argvars, retvar) 3311 VAR argvars; 3312 VAR retvar; 3313 { 3314 retvar->var_val.var_number = curwin->w_arg_idx; 3315 } 3316 3317 /* 3318 * "argv(nr)" function 3319 */ 3320 static void 3321 f_argv(argvars, retvar) 3322 VAR argvars; 3323 VAR retvar; 3324 { 3325 int idx; 3326 3327 idx = get_var_number(&argvars[0]); 3328 if (idx >= 0 && idx < ARGCOUNT) 3329 retvar->var_val.var_string = vim_strsave(alist_name(&ARGLIST[idx])); 3330 else 3331 retvar->var_val.var_string = NULL; 3332 retvar->var_type = VAR_STRING; 3333 } 3334 3335 /* 3336 * "browse(save, title, initdir, default)" function 3337 */ 3338 /* ARGSUSED */ 3339 static void 3340 f_browse(argvars, retvar) 3341 VAR argvars; 3342 VAR retvar; 3343 { 3344 #ifdef FEAT_BROWSE 3345 int save; 3346 char_u *title; 3347 char_u *initdir; 3348 char_u *defname; 3349 char_u buf[NUMBUFLEN]; 3350 char_u buf2[NUMBUFLEN]; 3351 3352 save = get_var_number(&argvars[0]); 3353 title = get_var_string(&argvars[1]); 3354 initdir = get_var_string_buf(&argvars[2], buf); 3355 defname = get_var_string_buf(&argvars[3], buf2); 3356 3357 retvar->var_val.var_string = 3358 do_browse(save, title, defname, NULL, initdir, NULL, curbuf); 3359 #else 3360 retvar->var_val.var_string = NULL; 3361 #endif 3362 retvar->var_type = VAR_STRING; 3363 } 3364 3365 /* 3366 * Find a buffer by number or exact name. 3367 */ 3368 static buf_T * 3369 find_buffer(avar) 3370 VAR avar; 3371 { 3372 buf_T *buf = NULL; 3373 char_u *name; 3374 3375 if (avar->var_type == VAR_NUMBER) 3376 buf = buflist_findnr((int)avar->var_val.var_number); 3377 else if (avar->var_val.var_string != NULL) 3378 { 3379 /* First make the name into a full path name */ 3380 name = FullName_save(avar->var_val.var_string, 3381 #ifdef UNIX 3382 TRUE /* force expansion, get rid of symbolic links */ 3383 #else 3384 FALSE 3385 #endif 3386 ); 3387 if (name != NULL) 3388 { 3389 buf = buflist_findname(name); 3390 vim_free(name); 3391 } 3392 if (buf == NULL) 3393 { 3394 /* No full path name match, try a match with a URL or a "nofile" 3395 * buffer, these don't use the full path. */ 3396 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 3397 if (buf->b_fname != NULL 3398 && (path_with_url(buf->b_fname) 3399 #ifdef FEAT_QUICKFIX 3400 || bt_nofile(buf) 3401 #endif 3402 ) 3403 && STRCMP(buf->b_fname, avar->var_val.var_string) == 0) 3404 break; 3405 } 3406 } 3407 return buf; 3408 } 3409 3410 /* 3411 * "bufexists(expr)" function 3412 */ 3413 static void 3414 f_bufexists(argvars, retvar) 3415 VAR argvars; 3416 VAR retvar; 3417 { 3418 retvar->var_val.var_number = (find_buffer(&argvars[0]) != NULL); 3419 } 3420 3421 /* 3422 * "buflisted(expr)" function 3423 */ 3424 static void 3425 f_buflisted(argvars, retvar) 3426 VAR argvars; 3427 VAR retvar; 3428 { 3429 buf_T *buf; 3430 3431 buf = find_buffer(&argvars[0]); 3432 retvar->var_val.var_number = (buf != NULL && buf->b_p_bl); 3433 } 3434 3435 /* 3436 * "bufloaded(expr)" function 3437 */ 3438 static void 3439 f_bufloaded(argvars, retvar) 3440 VAR argvars; 3441 VAR retvar; 3442 { 3443 buf_T *buf; 3444 3445 buf = find_buffer(&argvars[0]); 3446 retvar->var_val.var_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 3447 } 3448 3449 /* 3450 * Get buffer by number or pattern. 3451 */ 3452 static buf_T * 3453 get_buf_var(avar) 3454 VAR avar; 3455 { 3456 char_u *name = avar->var_val.var_string; 3457 int save_magic; 3458 char_u *save_cpo; 3459 buf_T *buf; 3460 3461 if (avar->var_type == VAR_NUMBER) 3462 return buflist_findnr((int)avar->var_val.var_number); 3463 if (name == NULL || *name == NUL) 3464 return curbuf; 3465 if (name[0] == '$' && name[1] == NUL) 3466 return lastbuf; 3467 3468 /* Ignore 'magic' and 'cpoptions' here to make scripts portable */ 3469 save_magic = p_magic; 3470 p_magic = TRUE; 3471 save_cpo = p_cpo; 3472 p_cpo = (char_u *)""; 3473 3474 buf = buflist_findnr(buflist_findpat(name, name + STRLEN(name), 3475 TRUE, FALSE)); 3476 3477 p_magic = save_magic; 3478 p_cpo = save_cpo; 3479 3480 /* If not found, try expanding the name, like done for bufexists(). */ 3481 if (buf == NULL) 3482 buf = find_buffer(avar); 3483 3484 return buf; 3485 } 3486 3487 /* 3488 * "bufname(expr)" function 3489 */ 3490 static void 3491 f_bufname(argvars, retvar) 3492 VAR argvars; 3493 VAR retvar; 3494 { 3495 buf_T *buf; 3496 3497 ++emsg_off; 3498 buf = get_buf_var(&argvars[0]); 3499 retvar->var_type = VAR_STRING; 3500 if (buf != NULL && buf->b_fname != NULL) 3501 retvar->var_val.var_string = vim_strsave(buf->b_fname); 3502 else 3503 retvar->var_val.var_string = NULL; 3504 --emsg_off; 3505 } 3506 3507 /* 3508 * "bufnr(expr)" function 3509 */ 3510 static void 3511 f_bufnr(argvars, retvar) 3512 VAR argvars; 3513 VAR retvar; 3514 { 3515 buf_T *buf; 3516 3517 ++emsg_off; 3518 buf = get_buf_var(&argvars[0]); 3519 if (buf != NULL) 3520 retvar->var_val.var_number = buf->b_fnum; 3521 else 3522 retvar->var_val.var_number = -1; 3523 --emsg_off; 3524 } 3525 3526 /* 3527 * "bufwinnr(nr)" function 3528 */ 3529 static void 3530 f_bufwinnr(argvars, retvar) 3531 VAR argvars; 3532 VAR retvar; 3533 { 3534 #ifdef FEAT_WINDOWS 3535 win_T *wp; 3536 int winnr = 0; 3537 #endif 3538 buf_T *buf; 3539 3540 ++emsg_off; 3541 buf = get_buf_var(&argvars[0]); 3542 #ifdef FEAT_WINDOWS 3543 for (wp = firstwin; wp; wp = wp->w_next) 3544 { 3545 ++winnr; 3546 if (wp->w_buffer == buf) 3547 break; 3548 } 3549 retvar->var_val.var_number = (wp != NULL ? winnr : -1); 3550 #else 3551 retvar->var_val.var_number = (curwin->w_buffer == buf ? 1 : -1); 3552 #endif 3553 --emsg_off; 3554 } 3555 3556 /* 3557 * "byte2line(byte)" function 3558 */ 3559 /*ARGSUSED*/ 3560 static void 3561 f_byte2line(argvars, retvar) 3562 VAR argvars; 3563 VAR retvar; 3564 { 3565 #ifndef FEAT_BYTEOFF 3566 retvar->var_val.var_number = -1; 3567 #else 3568 long boff = 0; 3569 3570 boff = get_var_number(&argvars[0]) - 1; 3571 if (boff < 0) 3572 retvar->var_val.var_number = -1; 3573 else 3574 retvar->var_val.var_number = ml_find_line_or_offset(curbuf, 3575 (linenr_T)0, &boff); 3576 #endif 3577 } 3578 3579 /* 3580 * "char2nr(string)" function 3581 */ 3582 static void 3583 f_char2nr(argvars, retvar) 3584 VAR argvars; 3585 VAR retvar; 3586 { 3587 #ifdef FEAT_MBYTE 3588 if (has_mbyte) 3589 retvar->var_val.var_number = 3590 (*mb_ptr2char)(get_var_string(&argvars[0])); 3591 else 3592 #endif 3593 retvar->var_val.var_number = get_var_string(&argvars[0])[0]; 3594 } 3595 3596 /* 3597 * "cindent(lnum)" function 3598 */ 3599 static void 3600 f_cindent(argvars, retvar) 3601 VAR argvars; 3602 VAR retvar; 3603 { 3604 #ifdef FEAT_CINDENT 3605 pos_T pos; 3606 linenr_T lnum; 3607 3608 pos = curwin->w_cursor; 3609 lnum = get_var_lnum(argvars); 3610 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 3611 { 3612 curwin->w_cursor.lnum = lnum; 3613 retvar->var_val.var_number = get_c_indent(); 3614 curwin->w_cursor = pos; 3615 } 3616 else 3617 #endif 3618 retvar->var_val.var_number = -1; 3619 } 3620 3621 /* 3622 * "col(string)" function 3623 */ 3624 static void 3625 f_col(argvars, retvar) 3626 VAR argvars; 3627 VAR retvar; 3628 { 3629 colnr_T col = 0; 3630 pos_T *fp; 3631 3632 fp = var2fpos(&argvars[0], FALSE); 3633 if (fp != NULL) 3634 { 3635 if (fp->col == MAXCOL) 3636 { 3637 /* '> can be MAXCOL, get the length of the line then */ 3638 if (fp->lnum <= curbuf->b_ml.ml_line_count) 3639 col = STRLEN(ml_get(fp->lnum)) + 1; 3640 else 3641 col = MAXCOL; 3642 } 3643 else 3644 { 3645 col = fp->col + 1; 3646 #ifdef FEAT_VIRTUALEDIT 3647 /* col(".") when the cursor is on the NUL at the end of the line 3648 * because of "coladd" can be seen as an extra column. */ 3649 if (virtual_active() && fp == &curwin->w_cursor) 3650 { 3651 char_u *p = ml_get_cursor(); 3652 3653 if (curwin->w_cursor.coladd >= (colnr_T)chartabsize(p, 3654 curwin->w_virtcol - curwin->w_cursor.coladd)) 3655 { 3656 # ifdef FEAT_MBYTE 3657 int l; 3658 3659 if (*p != NUL && p[(l = (*mb_ptr2len_check)(p))] == NUL) 3660 col += l; 3661 # else 3662 if (*p != NUL && p[1] == NUL) 3663 ++col; 3664 # endif 3665 } 3666 } 3667 #endif 3668 } 3669 } 3670 retvar->var_val.var_number = col; 3671 } 3672 3673 /* 3674 * "confirm(message, buttons[, default [, type]])" function 3675 */ 3676 /*ARGSUSED*/ 3677 static void 3678 f_confirm(argvars, retvar) 3679 VAR argvars; 3680 VAR retvar; 3681 { 3682 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) 3683 char_u *message; 3684 char_u *buttons = NULL; 3685 char_u buf[NUMBUFLEN]; 3686 char_u buf2[NUMBUFLEN]; 3687 int def = 1; 3688 int type = VIM_GENERIC; 3689 int c; 3690 3691 message = get_var_string(&argvars[0]); 3692 if (argvars[1].var_type != VAR_UNKNOWN) 3693 { 3694 buttons = get_var_string_buf(&argvars[1], buf); 3695 if (argvars[2].var_type != VAR_UNKNOWN) 3696 { 3697 def = get_var_number(&argvars[2]); 3698 if (argvars[3].var_type != VAR_UNKNOWN) 3699 { 3700 /* avoid that TOUPPER_ASC calls get_var_string_buf() twice */ 3701 c = *get_var_string_buf(&argvars[3], buf2); 3702 switch (TOUPPER_ASC(c)) 3703 { 3704 case 'E': type = VIM_ERROR; break; 3705 case 'Q': type = VIM_QUESTION; break; 3706 case 'I': type = VIM_INFO; break; 3707 case 'W': type = VIM_WARNING; break; 3708 case 'G': type = VIM_GENERIC; break; 3709 } 3710 } 3711 } 3712 } 3713 3714 if (buttons == NULL || *buttons == NUL) 3715 buttons = (char_u *)_("&Ok"); 3716 3717 retvar->var_val.var_number = do_dialog(type, NULL, message, buttons, 3718 def, NULL); 3719 #else 3720 retvar->var_val.var_number = 0; 3721 #endif 3722 } 3723 3724 3725 /* 3726 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function 3727 * 3728 * Checks the existence of a cscope connection. 3729 */ 3730 /*ARGSUSED*/ 3731 static void 3732 f_cscope_connection(argvars, retvar) 3733 VAR argvars; 3734 VAR retvar; 3735 { 3736 #ifdef FEAT_CSCOPE 3737 int num = 0; 3738 char_u *dbpath = NULL; 3739 char_u *prepend = NULL; 3740 char_u buf[NUMBUFLEN]; 3741 3742 if (argvars[0].var_type != VAR_UNKNOWN 3743 && argvars[1].var_type != VAR_UNKNOWN) 3744 { 3745 num = (int)get_var_number(&argvars[0]); 3746 dbpath = get_var_string(&argvars[1]); 3747 if (argvars[2].var_type != VAR_UNKNOWN) 3748 prepend = get_var_string_buf(&argvars[2], buf); 3749 } 3750 3751 retvar->var_val.var_number = cs_connection(num, dbpath, prepend); 3752 #else 3753 retvar->var_val.var_number = 0; 3754 #endif 3755 } 3756 3757 /* 3758 * "cursor(lnum, col)" function 3759 * 3760 * Moves the cursor to the specified line and column 3761 */ 3762 /*ARGSUSED*/ 3763 static void 3764 f_cursor(argvars, retvar) 3765 VAR argvars; 3766 VAR retvar; 3767 { 3768 long line, col; 3769 3770 line = get_var_lnum(argvars); 3771 if (line > 0) 3772 curwin->w_cursor.lnum = line; 3773 col = get_var_number(&argvars[1]); 3774 if (col > 0) 3775 curwin->w_cursor.col = col - 1; 3776 #ifdef FEAT_VIRTUALEDIT 3777 curwin->w_cursor.coladd = 0; 3778 #endif 3779 3780 /* Make sure the cursor is in a valid position. */ 3781 check_cursor(); 3782 #ifdef FEAT_MBYTE 3783 /* Correct cursor for multi-byte character. */ 3784 if (has_mbyte) 3785 mb_adjust_cursor(); 3786 #endif 3787 } 3788 3789 /* 3790 * "libcall()" function 3791 */ 3792 static void 3793 f_libcall(argvars, retvar) 3794 VAR argvars; 3795 VAR retvar; 3796 { 3797 libcall_common(argvars, retvar, VAR_STRING); 3798 } 3799 3800 /* 3801 * "libcallnr()" function 3802 */ 3803 static void 3804 f_libcallnr(argvars, retvar) 3805 VAR argvars; 3806 VAR retvar; 3807 { 3808 libcall_common(argvars, retvar, VAR_NUMBER); 3809 } 3810 3811 static void 3812 libcall_common(argvars, retvar, type) 3813 VAR argvars; 3814 VAR retvar; 3815 int type; 3816 { 3817 #ifdef FEAT_LIBCALL 3818 char_u *string_in; 3819 char_u **string_result; 3820 int nr_result; 3821 #endif 3822 3823 retvar->var_type = type; 3824 if (type == VAR_NUMBER) 3825 retvar->var_val.var_number = 0; 3826 else 3827 retvar->var_val.var_string = NULL; 3828 3829 if (check_restricted() || check_secure()) 3830 return; 3831 3832 #ifdef FEAT_LIBCALL 3833 /* The first two args must be strings, otherwise its meaningless */ 3834 if (argvars[0].var_type == VAR_STRING && argvars[1].var_type == VAR_STRING) 3835 { 3836 if (argvars[2].var_type == VAR_NUMBER) 3837 string_in = NULL; 3838 else 3839 string_in = argvars[2].var_val.var_string; 3840 if (type == VAR_NUMBER) 3841 string_result = NULL; 3842 else 3843 string_result = &retvar->var_val.var_string; 3844 if (mch_libcall(argvars[0].var_val.var_string, 3845 argvars[1].var_val.var_string, 3846 string_in, 3847 argvars[2].var_val.var_number, 3848 string_result, 3849 &nr_result) == OK 3850 && type == VAR_NUMBER) 3851 retvar->var_val.var_number = nr_result; 3852 } 3853 #endif 3854 } 3855 3856 /* 3857 * "delete()" function 3858 */ 3859 static void 3860 f_delete(argvars, retvar) 3861 VAR argvars; 3862 VAR retvar; 3863 { 3864 if (check_restricted() || check_secure()) 3865 retvar->var_val.var_number = -1; 3866 else 3867 retvar->var_val.var_number = mch_remove(get_var_string(&argvars[0])); 3868 } 3869 3870 /* 3871 * "did_filetype()" function 3872 */ 3873 /*ARGSUSED*/ 3874 static void 3875 f_did_filetype(argvars, retvar) 3876 VAR argvars; 3877 VAR retvar; 3878 { 3879 #ifdef FEAT_AUTOCMD 3880 retvar->var_val.var_number = did_filetype; 3881 #else 3882 retvar->var_val.var_number = 0; 3883 #endif 3884 } 3885 3886 /* 3887 * "escape({string}, {chars})" function 3888 */ 3889 static void 3890 f_escape(argvars, retvar) 3891 VAR argvars; 3892 VAR retvar; 3893 { 3894 char_u buf[NUMBUFLEN]; 3895 3896 retvar->var_val.var_string = 3897 vim_strsave_escaped(get_var_string(&argvars[0]), 3898 get_var_string_buf(&argvars[1], buf)); 3899 retvar->var_type = VAR_STRING; 3900 } 3901 3902 /* 3903 * "eventhandler()" function 3904 */ 3905 /*ARGSUSED*/ 3906 static void 3907 f_eventhandler(argvars, retvar) 3908 VAR argvars; 3909 VAR retvar; 3910 { 3911 retvar->var_val.var_number = vgetc_busy; 3912 } 3913 3914 /* 3915 * "executable()" function 3916 */ 3917 static void 3918 f_executable(argvars, retvar) 3919 VAR argvars; 3920 VAR retvar; 3921 { 3922 retvar->var_val.var_number = mch_can_exe(get_var_string(&argvars[0])); 3923 } 3924 3925 /* 3926 * "exists()" function 3927 */ 3928 static void 3929 f_exists(argvars, retvar) 3930 VAR argvars; 3931 VAR retvar; 3932 { 3933 char_u *p; 3934 char_u *name; 3935 int n = FALSE; 3936 int len = 0; 3937 3938 p = get_var_string(&argvars[0]); 3939 if (*p == '$') /* environment variable */ 3940 { 3941 /* first try "normal" environment variables (fast) */ 3942 if (mch_getenv(p + 1) != NULL) 3943 n = TRUE; 3944 else 3945 { 3946 /* try expanding things like $VIM and ${HOME} */ 3947 p = expand_env_save(p); 3948 if (p != NULL && *p != '$') 3949 n = TRUE; 3950 vim_free(p); 3951 } 3952 } 3953 else if (*p == '&' || *p == '+') /* option */ 3954 n = (get_option_var(&p, NULL, TRUE) == OK); 3955 else if (*p == '*') /* internal or user defined function */ 3956 { 3957 ++p; 3958 p = trans_function_name(&p, FALSE, TRUE); 3959 if (p != NULL) 3960 { 3961 if (ASCII_ISUPPER(*p) || p[0] == K_SPECIAL) 3962 n = (find_func(p) != NULL); 3963 else if (ASCII_ISLOWER(*p)) 3964 n = (find_internal_func(p) >= 0); 3965 vim_free(p); 3966 } 3967 } 3968 else if (*p == ':') 3969 { 3970 n = cmd_exists(p + 1); 3971 } 3972 else if (*p == '#') 3973 { 3974 #ifdef FEAT_AUTOCMD 3975 name = p + 1; 3976 p = vim_strchr(name, '#'); 3977 if (p != NULL) 3978 n = au_exists(name, p, p + 1); 3979 else 3980 n = au_exists(name, name + STRLEN(name), NULL); 3981 #endif 3982 } 3983 else /* internal variable */ 3984 { 3985 #ifdef FEAT_MAGIC_BRACES 3986 char_u *expr_start; 3987 char_u *expr_end; 3988 char_u *temp_string = NULL; 3989 char_u *s; 3990 #endif 3991 name = p; 3992 3993 #ifdef FEAT_MAGIC_BRACES 3994 /* Find the end of the name. */ 3995 s = find_name_end(name, &expr_start, &expr_end); 3996 if (expr_start != NULL) 3997 { 3998 temp_string = make_expanded_name(name, expr_start, expr_end, s); 3999 if (temp_string != NULL) 4000 { 4001 len = STRLEN(temp_string); 4002 name = temp_string; 4003 } 4004 } 4005 #endif 4006 if (len == 0) 4007 len = get_id_len(&p); 4008 if (len != 0) 4009 n = (get_var_var(name, len, NULL) == OK); 4010 4011 #ifdef FEAT_MAGIC_BRACES 4012 vim_free(temp_string); 4013 #endif 4014 } 4015 4016 retvar->var_val.var_number = n; 4017 } 4018 4019 /* 4020 * "expand()" function 4021 */ 4022 static void 4023 f_expand(argvars, retvar) 4024 VAR argvars; 4025 VAR retvar; 4026 { 4027 char_u *s; 4028 int len; 4029 char_u *errormsg; 4030 int flags = WILD_SILENT|WILD_USE_NL|WILD_LIST_NOTFOUND; 4031 expand_T xpc; 4032 4033 retvar->var_type = VAR_STRING; 4034 s = get_var_string(&argvars[0]); 4035 if (*s == '%' || *s == '#' || *s == '<') 4036 { 4037 ++emsg_off; 4038 retvar->var_val.var_string = eval_vars(s, &len, NULL, &errormsg, s); 4039 --emsg_off; 4040 } 4041 else 4042 { 4043 /* When the optional second argument is non-zero, don't remove matches 4044 * for 'suffixes' and 'wildignore' */ 4045 if (argvars[1].var_type != VAR_UNKNOWN && get_var_number(&argvars[1])) 4046 flags |= WILD_KEEP_ALL; 4047 ExpandInit(&xpc); 4048 xpc.xp_context = EXPAND_FILES; 4049 retvar->var_val.var_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); 4050 ExpandCleanup(&xpc); 4051 } 4052 } 4053 4054 /* 4055 * "filereadable()" function 4056 */ 4057 static void 4058 f_filereadable(argvars, retvar) 4059 VAR argvars; 4060 VAR retvar; 4061 { 4062 FILE *fd; 4063 char_u *p; 4064 int n; 4065 4066 p = get_var_string(&argvars[0]); 4067 if (*p && !mch_isdir(p) && (fd = mch_fopen((char *)p, "r")) != NULL) 4068 { 4069 n = TRUE; 4070 fclose(fd); 4071 } 4072 else 4073 n = FALSE; 4074 4075 retvar->var_val.var_number = n; 4076 } 4077 4078 /* 4079 * return 0 for not writable, 1 for writable file, 2 for a dir which we have 4080 * rights to write into. 4081 */ 4082 static void 4083 f_filewritable(argvars, retvar) 4084 VAR argvars; 4085 VAR retvar; 4086 { 4087 char_u *p; 4088 int retval = 0; 4089 #if defined(UNIX) || defined(VMS) 4090 int perm = 0; 4091 #endif 4092 4093 p = get_var_string(&argvars[0]); 4094 #if defined(UNIX) || defined(VMS) 4095 perm = mch_getperm(p); 4096 #endif 4097 #ifndef MACOS_CLASSIC /* TODO: get either mch_writable or mch_access */ 4098 if ( 4099 # ifdef WIN3264 4100 mch_writable(p) && 4101 # else 4102 # if defined(UNIX) || defined(VMS) 4103 (perm & 0222) && 4104 # endif 4105 # endif 4106 mch_access((char *)p, W_OK) == 0 4107 ) 4108 #endif 4109 { 4110 ++retval; 4111 if (mch_isdir(p)) 4112 ++retval; 4113 } 4114 retvar->var_val.var_number = retval; 4115 } 4116 4117 /* 4118 * "fnamemodify({fname}, {mods})" function 4119 */ 4120 static void 4121 f_fnamemodify(argvars, retvar) 4122 VAR argvars; 4123 VAR retvar; 4124 { 4125 char_u *fname; 4126 char_u *mods; 4127 int usedlen = 0; 4128 int len; 4129 char_u *fbuf = NULL; 4130 char_u buf[NUMBUFLEN]; 4131 4132 fname = get_var_string(&argvars[0]); 4133 mods = get_var_string_buf(&argvars[1], buf); 4134 len = (int)STRLEN(fname); 4135 4136 (void)modify_fname(mods, &usedlen, &fname, &fbuf, &len); 4137 4138 retvar->var_type = VAR_STRING; 4139 if (fname == NULL) 4140 retvar->var_val.var_string = NULL; 4141 else 4142 retvar->var_val.var_string = vim_strnsave(fname, len); 4143 vim_free(fbuf); 4144 } 4145 4146 /* 4147 * "foldclosed()" function 4148 */ 4149 static void 4150 f_foldclosed(argvars, retvar) 4151 VAR argvars; 4152 VAR retvar; 4153 { 4154 foldclosed_both(argvars, retvar, FALSE); 4155 } 4156 4157 /* 4158 * "foldclosedend()" function 4159 */ 4160 static void 4161 f_foldclosedend(argvars, retvar) 4162 VAR argvars; 4163 VAR retvar; 4164 { 4165 foldclosed_both(argvars, retvar, TRUE); 4166 } 4167 4168 /* 4169 * "foldclosed()" function 4170 */ 4171 static void 4172 foldclosed_both(argvars, retvar, end) 4173 VAR argvars; 4174 VAR retvar; 4175 int end; 4176 { 4177 #ifdef FEAT_FOLDING 4178 linenr_T lnum; 4179 linenr_T first, last; 4180 4181 lnum = get_var_lnum(argvars); 4182 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 4183 { 4184 if (hasFoldingWin(curwin, lnum, &first, &last, FALSE, NULL)) 4185 { 4186 if (end) 4187 retvar->var_val.var_number = (varnumber_T)last; 4188 else 4189 retvar->var_val.var_number = (varnumber_T)first; 4190 return; 4191 } 4192 } 4193 #endif 4194 retvar->var_val.var_number = -1; 4195 } 4196 4197 /* 4198 * "foldlevel()" function 4199 */ 4200 static void 4201 f_foldlevel(argvars, retvar) 4202 VAR argvars; 4203 VAR retvar; 4204 { 4205 #ifdef FEAT_FOLDING 4206 linenr_T lnum; 4207 4208 lnum = get_var_lnum(argvars); 4209 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 4210 retvar->var_val.var_number = foldLevel(lnum); 4211 else 4212 #endif 4213 retvar->var_val.var_number = 0; 4214 } 4215 4216 /* 4217 * "foldtext()" function 4218 */ 4219 /*ARGSUSED*/ 4220 static void 4221 f_foldtext(argvars, retvar) 4222 VAR argvars; 4223 VAR retvar; 4224 { 4225 #ifdef FEAT_FOLDING 4226 linenr_T lnum; 4227 char_u *s; 4228 char_u *r; 4229 int len; 4230 char *txt; 4231 #endif 4232 4233 retvar->var_type = VAR_STRING; 4234 retvar->var_val.var_string = NULL; 4235 #ifdef FEAT_FOLDING 4236 if ((linenr_T)vimvars[VV_FOLDSTART].val > 0 4237 && (linenr_T)vimvars[VV_FOLDEND].val <= curbuf->b_ml.ml_line_count 4238 && vimvars[VV_FOLDDASHES].val != NULL) 4239 { 4240 /* Find first non-empty line in the fold. */ 4241 lnum = (linenr_T)vimvars[VV_FOLDSTART].val; 4242 while (lnum < (linenr_T)vimvars[VV_FOLDEND].val) 4243 { 4244 if (!linewhite(lnum)) 4245 break; 4246 ++lnum; 4247 } 4248 4249 /* Find interesting text in this line. */ 4250 s = skipwhite(ml_get(lnum)); 4251 /* skip C comment-start */ 4252 if (s[0] == '/' && (s[1] == '*' || s[1] == '/')) 4253 s = skipwhite(s + 2); 4254 txt = _("+-%s%3ld lines: "); 4255 r = alloc((unsigned)(STRLEN(txt) 4256 + STRLEN(vimvars[VV_FOLDDASHES].val) /* for %s */ 4257 + 20 /* for %3ld */ 4258 + STRLEN(s))); /* concatenated */ 4259 if (r != NULL) 4260 { 4261 sprintf((char *)r, txt, vimvars[VV_FOLDDASHES].val, 4262 (long)((linenr_T)vimvars[VV_FOLDEND].val 4263 - (linenr_T)vimvars[VV_FOLDSTART].val + 1)); 4264 len = (int)STRLEN(r); 4265 STRCAT(r, s); 4266 /* remove 'foldmarker' and 'commentstring' */ 4267 foldtext_cleanup(r + len); 4268 retvar->var_val.var_string = r; 4269 } 4270 } 4271 #endif 4272 } 4273 4274 /* 4275 * "foreground()" function 4276 */ 4277 /*ARGSUSED*/ 4278 static void 4279 f_foreground(argvars, retvar) 4280 VAR argvars; 4281 VAR retvar; 4282 { 4283 retvar->var_val.var_number = 0; 4284 #ifdef FEAT_GUI 4285 if (gui.in_use) 4286 gui_mch_set_foreground(); 4287 #else 4288 # ifdef WIN32 4289 win32_set_foreground(); 4290 # endif 4291 #endif 4292 } 4293 4294 /* 4295 * "getchar()" function 4296 */ 4297 static void 4298 f_getchar(argvars, retvar) 4299 VAR argvars; 4300 VAR retvar; 4301 { 4302 varnumber_T n; 4303 4304 ++no_mapping; 4305 ++allow_keys; 4306 if (argvars[0].var_type == VAR_UNKNOWN) 4307 /* getchar(): blocking wait. */ 4308 n = safe_vgetc(); 4309 else if (get_var_number(&argvars[0]) == 1) 4310 /* getchar(1): only check if char avail */ 4311 n = vpeekc(); 4312 else if (vpeekc() == NUL) 4313 /* getchar(0) and no char avail: return zero */ 4314 n = 0; 4315 else 4316 /* getchar(0) and char avail: return char */ 4317 n = safe_vgetc(); 4318 --no_mapping; 4319 --allow_keys; 4320 4321 retvar->var_val.var_number = n; 4322 if (IS_SPECIAL(n) || mod_mask != 0) 4323 { 4324 char_u temp[10]; /* modifier: 3, mbyte-char: 6, NUL: 1 */ 4325 int i = 0; 4326 4327 /* Turn a special key into three bytes, plus modifier. */ 4328 if (mod_mask != 0) 4329 { 4330 temp[i++] = K_SPECIAL; 4331 temp[i++] = KS_MODIFIER; 4332 temp[i++] = mod_mask; 4333 } 4334 if (IS_SPECIAL(n)) 4335 { 4336 temp[i++] = K_SPECIAL; 4337 temp[i++] = K_SECOND(n); 4338 temp[i++] = K_THIRD(n); 4339 } 4340 #ifdef FEAT_MBYTE 4341 else if (has_mbyte) 4342 i += (*mb_char2bytes)(n, temp + i); 4343 #endif 4344 else 4345 temp[i++] = n; 4346 temp[i++] = NUL; 4347 retvar->var_type = VAR_STRING; 4348 retvar->var_val.var_string = vim_strsave(temp); 4349 } 4350 } 4351 4352 /* 4353 * "getcharmod()" function 4354 */ 4355 /*ARGSUSED*/ 4356 static void 4357 f_getcharmod(argvars, retvar) 4358 VAR argvars; 4359 VAR retvar; 4360 { 4361 retvar->var_val.var_number = mod_mask; 4362 } 4363 4364 /* 4365 * "getcmdline()" function 4366 */ 4367 /*ARGSUSED*/ 4368 static void 4369 f_getcmdline(argvars, retvar) 4370 VAR argvars; 4371 VAR retvar; 4372 { 4373 retvar->var_type = VAR_STRING; 4374 retvar->var_val.var_string = get_cmdline_str(); 4375 } 4376 4377 /* 4378 * "getcmdpos()" function 4379 */ 4380 /*ARGSUSED*/ 4381 static void 4382 f_getcmdpos(argvars, retvar) 4383 VAR argvars; 4384 VAR retvar; 4385 { 4386 retvar->var_val.var_number = get_cmdline_pos() + 1; 4387 } 4388 4389 /* 4390 * "getbufvar()" function 4391 */ 4392 static void 4393 f_getbufvar(argvars, retvar) 4394 VAR argvars; 4395 VAR retvar; 4396 { 4397 buf_T *buf; 4398 buf_T *save_curbuf; 4399 char_u *varname; 4400 VAR v; 4401 4402 ++emsg_off; 4403 buf = get_buf_var(&argvars[0]); 4404 varname = get_var_string(&argvars[1]); 4405 4406 retvar->var_type = VAR_STRING; 4407 retvar->var_val.var_string = NULL; 4408 4409 if (buf != NULL && varname != NULL) 4410 { 4411 if (*varname == '&') /* buffer-local-option */ 4412 { 4413 /* set curbuf to be our buf, temporarily */ 4414 save_curbuf = curbuf; 4415 curbuf = buf; 4416 4417 get_option_var(&varname, retvar, TRUE); 4418 4419 /* restore previous notion of curbuf */ 4420 curbuf = save_curbuf; 4421 } 4422 else 4423 { 4424 /* look up the variable */ 4425 v = find_var_in_ga(&buf->b_vars, varname); 4426 if (v != NULL) 4427 copy_var(v, retvar); 4428 } 4429 } 4430 4431 --emsg_off; 4432 } 4433 4434 /* 4435 * "getcwd()" function 4436 */ 4437 /*ARGSUSED*/ 4438 static void 4439 f_getcwd(argvars, retvar) 4440 VAR argvars; 4441 VAR retvar; 4442 { 4443 char_u cwd[MAXPATHL]; 4444 4445 retvar->var_type = VAR_STRING; 4446 if (mch_dirname(cwd, MAXPATHL) == FAIL) 4447 retvar->var_val.var_string = NULL; 4448 else 4449 { 4450 retvar->var_val.var_string = vim_strsave(cwd); 4451 #ifdef BACKSLASH_IN_FILENAME 4452 slash_adjust(retvar->var_val.var_string); 4453 #endif 4454 } 4455 } 4456 4457 /* 4458 * "getfsize({fname})" function 4459 */ 4460 static void 4461 f_getfsize(argvars, retvar) 4462 VAR argvars; 4463 VAR retvar; 4464 { 4465 char_u *fname; 4466 struct stat st; 4467 4468 fname = get_var_string(&argvars[0]); 4469 4470 retvar->var_type = VAR_NUMBER; 4471 4472 if (mch_stat((char *)fname, &st) >= 0) 4473 { 4474 if (mch_isdir(fname)) 4475 retvar->var_val.var_number = 0; 4476 else 4477 retvar->var_val.var_number = (varnumber_T)st.st_size; 4478 } 4479 else 4480 retvar->var_val.var_number = -1; 4481 } 4482 4483 /* 4484 * "getftime({fname})" function 4485 */ 4486 static void 4487 f_getftime(argvars, retvar) 4488 VAR argvars; 4489 VAR retvar; 4490 { 4491 char_u *fname; 4492 struct stat st; 4493 4494 fname = get_var_string(&argvars[0]); 4495 4496 if (mch_stat((char *)fname, &st) >= 0) 4497 retvar->var_val.var_number = (varnumber_T)st.st_mtime; 4498 else 4499 retvar->var_val.var_number = -1; 4500 } 4501 4502 /* 4503 * "getreg()" function 4504 */ 4505 static void 4506 f_getreg(argvars, retvar) 4507 VAR argvars; 4508 VAR retvar; 4509 { 4510 char_u *strregname; 4511 int regname; 4512 4513 if (argvars[0].var_type != VAR_UNKNOWN) 4514 strregname = get_var_string(&argvars[0]); 4515 else 4516 strregname = vimvars[VV_REG].val; 4517 regname = (strregname == NULL ? '"' : *strregname); 4518 if (regname == 0) 4519 regname = '"'; 4520 4521 retvar->var_type = VAR_STRING; 4522 retvar->var_val.var_string = get_reg_contents(regname, TRUE); 4523 } 4524 4525 /* 4526 * "getregtype()" function 4527 */ 4528 static void 4529 f_getregtype(argvars, retvar) 4530 VAR argvars; 4531 VAR retvar; 4532 { 4533 char_u *strregname; 4534 int regname; 4535 char_u buf[NUMBUFLEN + 2]; 4536 long reglen = 0; 4537 4538 if (argvars[0].var_type != VAR_UNKNOWN) 4539 strregname = get_var_string(&argvars[0]); 4540 else 4541 /* Default to v:register */ 4542 strregname = vimvars[VV_REG].val; 4543 4544 regname = (strregname == NULL ? '"' : *strregname); 4545 if (regname == 0) 4546 regname = '"'; 4547 4548 buf[0] = NUL; 4549 buf[1] = NUL; 4550 switch (get_reg_type(regname, ®len)) 4551 { 4552 case MLINE: buf[0] = 'V'; break; 4553 case MCHAR: buf[0] = 'v'; break; 4554 #ifdef FEAT_VISUAL 4555 case MBLOCK: 4556 buf[0] = Ctrl_V; 4557 sprintf((char *)buf + 1, "%ld", reglen + 1); 4558 break; 4559 #endif 4560 } 4561 retvar->var_type = VAR_STRING; 4562 retvar->var_val.var_string = vim_strsave(buf); 4563 } 4564 4565 /* 4566 * "getline(lnum)" function 4567 */ 4568 static void 4569 f_getline(argvars, retvar) 4570 VAR argvars; 4571 VAR retvar; 4572 { 4573 linenr_T lnum; 4574 char_u *p; 4575 4576 lnum = get_var_lnum(argvars); 4577 4578 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 4579 p = ml_get(lnum); 4580 else 4581 p = (char_u *)""; 4582 4583 retvar->var_type = VAR_STRING; 4584 retvar->var_val.var_string = vim_strsave(p); 4585 } 4586 4587 /* 4588 * "getwinposx()" function 4589 */ 4590 /*ARGSUSED*/ 4591 static void 4592 f_getwinposx(argvars, retvar) 4593 VAR argvars; 4594 VAR retvar; 4595 { 4596 retvar->var_val.var_number = -1; 4597 #ifdef FEAT_GUI 4598 if (gui.in_use) 4599 { 4600 int x, y; 4601 4602 if (gui_mch_get_winpos(&x, &y) == OK) 4603 retvar->var_val.var_number = x; 4604 } 4605 #endif 4606 } 4607 4608 /* 4609 * "getwinposy()" function 4610 */ 4611 /*ARGSUSED*/ 4612 static void 4613 f_getwinposy(argvars, retvar) 4614 VAR argvars; 4615 VAR retvar; 4616 { 4617 retvar->var_val.var_number = -1; 4618 #ifdef FEAT_GUI 4619 if (gui.in_use) 4620 { 4621 int x, y; 4622 4623 if (gui_mch_get_winpos(&x, &y) == OK) 4624 retvar->var_val.var_number = y; 4625 } 4626 #endif 4627 } 4628 4629 /* 4630 * "getwinvar()" function 4631 */ 4632 static void 4633 f_getwinvar(argvars, retvar) 4634 VAR argvars; 4635 VAR retvar; 4636 { 4637 win_T *win, *oldcurwin; 4638 char_u *varname; 4639 VAR v; 4640 4641 ++emsg_off; 4642 win = find_win_by_nr(&argvars[0]); 4643 varname = get_var_string(&argvars[1]); 4644 4645 retvar->var_type = VAR_STRING; 4646 retvar->var_val.var_string = NULL; 4647 4648 if (win != NULL && varname != NULL) 4649 { 4650 if (*varname == '&') /* window-local-option */ 4651 { 4652 /* set curwin to be our win, temporarily */ 4653 oldcurwin = curwin; 4654 curwin = win; 4655 4656 get_option_var(&varname, retvar , 1); 4657 4658 /* restore previous notion of curwin */ 4659 curwin = oldcurwin; 4660 } 4661 else 4662 { 4663 /* look up the variable */ 4664 v = find_var_in_ga(&win->w_vars, varname); 4665 if (v != NULL) 4666 copy_var(v, retvar); 4667 } 4668 } 4669 4670 --emsg_off; 4671 } 4672 4673 /* 4674 * "glob()" function 4675 */ 4676 static void 4677 f_glob(argvars, retvar) 4678 VAR argvars; 4679 VAR retvar; 4680 { 4681 expand_T xpc; 4682 4683 ExpandInit(&xpc); 4684 xpc.xp_context = EXPAND_FILES; 4685 retvar->var_type = VAR_STRING; 4686 retvar->var_val.var_string = ExpandOne(&xpc, get_var_string(&argvars[0]), 4687 NULL, WILD_USE_NL|WILD_SILENT, WILD_ALL); 4688 ExpandCleanup(&xpc); 4689 } 4690 4691 /* 4692 * "globpath()" function 4693 */ 4694 static void 4695 f_globpath(argvars, retvar) 4696 VAR argvars; 4697 VAR retvar; 4698 { 4699 char_u buf1[NUMBUFLEN]; 4700 4701 retvar->var_type = VAR_STRING; 4702 retvar->var_val.var_string = globpath(get_var_string(&argvars[0]), 4703 get_var_string_buf(&argvars[1], buf1)); 4704 } 4705 4706 /* 4707 * "has()" function 4708 */ 4709 static void 4710 f_has(argvars, retvar) 4711 VAR argvars; 4712 VAR retvar; 4713 { 4714 int i; 4715 char_u *name; 4716 int n = FALSE; 4717 static char *(has_list[]) = 4718 { 4719 #ifdef AMIGA 4720 "amiga", 4721 # ifdef FEAT_ARP 4722 "arp", 4723 # endif 4724 #endif 4725 #ifdef __BEOS__ 4726 "beos", 4727 #endif 4728 #ifdef MSDOS 4729 # ifdef DJGPP 4730 "dos32", 4731 # else 4732 "dos16", 4733 # endif 4734 #endif 4735 #ifdef MACOS /* TODO: Should we add MACOS_CLASSIC, MACOS_X? (Dany) */ 4736 "mac", 4737 #endif 4738 #if defined(MACOS_X_UNIX) 4739 "macunix", 4740 #endif 4741 #ifdef OS2 4742 "os2", 4743 #endif 4744 #ifdef __QNX__ 4745 "qnx", 4746 #endif 4747 #ifdef RISCOS 4748 "riscos", 4749 #endif 4750 #ifdef UNIX 4751 "unix", 4752 #endif 4753 #ifdef VMS 4754 "vms", 4755 #endif 4756 #ifdef WIN16 4757 "win16", 4758 #endif 4759 #ifdef WIN32 4760 "win32", 4761 #endif 4762 #if defined(UNIX) && (defined(__CYGWIN32__) || defined(__CYGWIN__)) 4763 "win32unix", 4764 #endif 4765 #ifdef WIN64 4766 "win64", 4767 #endif 4768 #ifdef EBCDIC 4769 "ebcdic", 4770 #endif 4771 #ifndef CASE_INSENSITIVE_FILENAME 4772 "fname_case", 4773 #endif 4774 #ifdef FEAT_ARABIC 4775 "arabic", 4776 #endif 4777 #ifdef FEAT_AUTOCMD 4778 "autocmd", 4779 #endif 4780 #ifdef FEAT_BEVAL 4781 "balloon_eval", 4782 #endif 4783 #if defined(SOME_BUILTIN_TCAPS) || defined(ALL_BUILTIN_TCAPS) 4784 "builtin_terms", 4785 # ifdef ALL_BUILTIN_TCAPS 4786 "all_builtin_terms", 4787 # endif 4788 #endif 4789 #ifdef FEAT_BYTEOFF 4790 "byte_offset", 4791 #endif 4792 #ifdef FEAT_CINDENT 4793 "cindent", 4794 #endif 4795 #ifdef FEAT_CLIENTSERVER 4796 "clientserver", 4797 #endif 4798 #ifdef FEAT_CLIPBOARD 4799 "clipboard", 4800 #endif 4801 #ifdef FEAT_CMDL_COMPL 4802 "cmdline_compl", 4803 #endif 4804 #ifdef FEAT_CMDHIST 4805 "cmdline_hist", 4806 #endif 4807 #ifdef FEAT_COMMENTS 4808 "comments", 4809 #endif 4810 #ifdef FEAT_CRYPT 4811 "cryptv", 4812 #endif 4813 #ifdef FEAT_CSCOPE 4814 "cscope", 4815 #endif 4816 #ifdef DEBUG 4817 "debug", 4818 #endif 4819 #ifdef FEAT_CON_DIALOG 4820 "dialog_con", 4821 #endif 4822 #ifdef FEAT_GUI_DIALOG 4823 "dialog_gui", 4824 #endif 4825 #ifdef FEAT_DIFF 4826 "diff", 4827 #endif 4828 #ifdef FEAT_DIGRAPHS 4829 "digraphs", 4830 #endif 4831 #ifdef FEAT_DND 4832 "dnd", 4833 #endif 4834 #ifdef FEAT_EMACS_TAGS 4835 "emacs_tags", 4836 #endif 4837 "eval", /* always present, of course! */ 4838 #ifdef FEAT_EX_EXTRA 4839 "ex_extra", 4840 #endif 4841 #ifdef FEAT_SEARCH_EXTRA 4842 "extra_search", 4843 #endif 4844 #ifdef FEAT_FKMAP 4845 "farsi", 4846 #endif 4847 #ifdef FEAT_SEARCHPATH 4848 "file_in_path", 4849 #endif 4850 #ifdef FEAT_FIND_ID 4851 "find_in_path", 4852 #endif 4853 #ifdef FEAT_FOLDING 4854 "folding", 4855 #endif 4856 #ifdef FEAT_FOOTER 4857 "footer", 4858 #endif 4859 #if !defined(USE_SYSTEM) && defined(UNIX) 4860 "fork", 4861 #endif 4862 #ifdef FEAT_GETTEXT 4863 "gettext", 4864 #endif 4865 #ifdef FEAT_GUI 4866 "gui", 4867 #endif 4868 #ifdef FEAT_GUI_ATHENA 4869 # ifdef FEAT_GUI_NEXTAW 4870 "gui_neXtaw", 4871 # else 4872 "gui_athena", 4873 # endif 4874 #endif 4875 #ifdef FEAT_GUI_BEOS 4876 "gui_beos", 4877 #endif 4878 #ifdef FEAT_GUI_GTK 4879 "gui_gtk", 4880 # ifdef HAVE_GTK2 4881 "gui_gtk2", 4882 # endif 4883 #endif 4884 #ifdef FEAT_GUI_MAC 4885 "gui_mac", 4886 #endif 4887 #ifdef FEAT_GUI_MOTIF 4888 "gui_motif", 4889 #endif 4890 #ifdef FEAT_GUI_PHOTON 4891 "gui_photon", 4892 #endif 4893 #ifdef FEAT_GUI_W16 4894 "gui_win16", 4895 #endif 4896 #ifdef FEAT_GUI_W32 4897 "gui_win32", 4898 #endif 4899 #ifdef FEAT_HANGULIN 4900 "hangul_input", 4901 #endif 4902 #if defined(HAVE_ICONV_H) && defined(USE_ICONV) 4903 "iconv", 4904 #endif 4905 #ifdef FEAT_INS_EXPAND 4906 "insert_expand", 4907 #endif 4908 #ifdef FEAT_JUMPLIST 4909 "jumplist", 4910 #endif 4911 #ifdef FEAT_KEYMAP 4912 "keymap", 4913 #endif 4914 #ifdef FEAT_LANGMAP 4915 "langmap", 4916 #endif 4917 #ifdef FEAT_LIBCALL 4918 "libcall", 4919 #endif 4920 #ifdef FEAT_LINEBREAK 4921 "linebreak", 4922 #endif 4923 #ifdef FEAT_LISP 4924 "lispindent", 4925 #endif 4926 #ifdef FEAT_LISTCMDS 4927 "listcmds", 4928 #endif 4929 #ifdef FEAT_LOCALMAP 4930 "localmap", 4931 #endif 4932 #ifdef FEAT_MENU 4933 "menu", 4934 #endif 4935 #ifdef FEAT_SESSION 4936 "mksession", 4937 #endif 4938 #ifdef FEAT_MODIFY_FNAME 4939 "modify_fname", 4940 #endif 4941 #ifdef FEAT_MOUSE 4942 "mouse", 4943 #endif 4944 #ifdef FEAT_MOUSESHAPE 4945 "mouseshape", 4946 #endif 4947 #if defined(UNIX) || defined(VMS) 4948 # ifdef FEAT_MOUSE_DEC 4949 "mouse_dec", 4950 # endif 4951 # ifdef FEAT_MOUSE_GPM 4952 "mouse_gpm", 4953 # endif 4954 # ifdef FEAT_MOUSE_JSB 4955 "mouse_jsbterm", 4956 # endif 4957 # ifdef FEAT_MOUSE_NET 4958 "mouse_netterm", 4959 # endif 4960 # ifdef FEAT_MOUSE_PTERM 4961 "mouse_pterm", 4962 # endif 4963 # ifdef FEAT_MOUSE_XTERM 4964 "mouse_xterm", 4965 # endif 4966 #endif 4967 #ifdef FEAT_MBYTE 4968 "multi_byte", 4969 #endif 4970 #ifdef FEAT_MBYTE_IME 4971 "multi_byte_ime", 4972 #endif 4973 #ifdef FEAT_MULTI_LANG 4974 "multi_lang", 4975 #endif 4976 #ifdef FEAT_OLE 4977 "ole", 4978 #endif 4979 #ifdef FEAT_OSFILETYPE 4980 "osfiletype", 4981 #endif 4982 #ifdef FEAT_PATH_EXTRA 4983 "path_extra", 4984 #endif 4985 #ifdef FEAT_PERL 4986 #ifndef DYNAMIC_PERL 4987 "perl", 4988 #endif 4989 #endif 4990 #ifdef FEAT_PYTHON 4991 #ifndef DYNAMIC_PYTHON 4992 "python", 4993 #endif 4994 #endif 4995 #ifdef FEAT_POSTSCRIPT 4996 "postscript", 4997 #endif 4998 #ifdef FEAT_PRINTER 4999 "printer", 5000 #endif 5001 #ifdef FEAT_QUICKFIX 5002 "quickfix", 5003 #endif 5004 #ifdef FEAT_RIGHTLEFT 5005 "rightleft", 5006 #endif 5007 #if defined(FEAT_RUBY) && !defined(DYNAMIC_RUBY) 5008 "ruby", 5009 #endif 5010 #ifdef FEAT_SCROLLBIND 5011 "scrollbind", 5012 #endif 5013 #ifdef FEAT_CMDL_INFO 5014 "showcmd", 5015 "cmdline_info", 5016 #endif 5017 #ifdef FEAT_SIGNS 5018 "signs", 5019 #endif 5020 #ifdef FEAT_SMARTINDENT 5021 "smartindent", 5022 #endif 5023 #ifdef FEAT_SNIFF 5024 "sniff", 5025 #endif 5026 #ifdef FEAT_STL_OPT 5027 "statusline", 5028 #endif 5029 #ifdef FEAT_SUN_WORKSHOP 5030 "sun_workshop", 5031 #endif 5032 #ifdef FEAT_NETBEANS_INTG 5033 "netbeans_intg", 5034 #endif 5035 #ifdef FEAT_SYN_HL 5036 "syntax", 5037 #endif 5038 #if defined(USE_SYSTEM) || !defined(UNIX) 5039 "system", 5040 #endif 5041 #ifdef FEAT_TAG_BINS 5042 "tag_binary", 5043 #endif 5044 #ifdef FEAT_TAG_OLDSTATIC 5045 "tag_old_static", 5046 #endif 5047 #ifdef FEAT_TAG_ANYWHITE 5048 "tag_any_white", 5049 #endif 5050 #ifdef FEAT_TCL 5051 # ifndef DYNAMIC_TCL 5052 "tcl", 5053 # endif 5054 #endif 5055 #ifdef TERMINFO 5056 "terminfo", 5057 #endif 5058 #ifdef FEAT_TERMRESPONSE 5059 "termresponse", 5060 #endif 5061 #ifdef FEAT_TEXTOBJ 5062 "textobjects", 5063 #endif 5064 #ifdef HAVE_TGETENT 5065 "tgetent", 5066 #endif 5067 #ifdef FEAT_TITLE 5068 "title", 5069 #endif 5070 #ifdef FEAT_TOOLBAR 5071 "toolbar", 5072 #endif 5073 #ifdef FEAT_USR_CMDS 5074 "user-commands", /* was accidentally included in 5.4 */ 5075 "user_commands", 5076 #endif 5077 #ifdef FEAT_VIMINFO 5078 "viminfo", 5079 #endif 5080 #ifdef FEAT_VERTSPLIT 5081 "vertsplit", 5082 #endif 5083 #ifdef FEAT_VIRTUALEDIT 5084 "virtualedit", 5085 #endif 5086 #ifdef FEAT_VISUAL 5087 "visual", 5088 #endif 5089 #ifdef FEAT_VISUALEXTRA 5090 "visualextra", 5091 #endif 5092 #ifdef FEAT_VREPLACE 5093 "vreplace", 5094 #endif 5095 #ifdef FEAT_WILDIGN 5096 "wildignore", 5097 #endif 5098 #ifdef FEAT_WILDMENU 5099 "wildmenu", 5100 #endif 5101 #ifdef FEAT_WINDOWS 5102 "windows", 5103 #endif 5104 #ifdef FEAT_WAK 5105 "winaltkeys", 5106 #endif 5107 #ifdef FEAT_WRITEBACKUP 5108 "writebackup", 5109 #endif 5110 #ifdef FEAT_XIM 5111 "xim", 5112 #endif 5113 #ifdef FEAT_XFONTSET 5114 "xfontset", 5115 #endif 5116 #ifdef USE_XSMP 5117 "xsmp", 5118 #endif 5119 #ifdef USE_XSMP_INTERACT 5120 "xsmp_interact", 5121 #endif 5122 #ifdef FEAT_XCLIPBOARD 5123 "xterm_clipboard", 5124 #endif 5125 #ifdef FEAT_XTERM_SAVE 5126 "xterm_save", 5127 #endif 5128 #if defined(UNIX) && defined(FEAT_X11) 5129 "X11", 5130 #endif 5131 NULL 5132 }; 5133 5134 name = get_var_string(&argvars[0]); 5135 for (i = 0; has_list[i] != NULL; ++i) 5136 if (STRICMP(name, has_list[i]) == 0) 5137 { 5138 n = TRUE; 5139 break; 5140 } 5141 5142 if (n == FALSE) 5143 { 5144 if (STRNICMP(name, "patch", 5) == 0) 5145 n = has_patch(atoi((char *)name + 5)); 5146 else if (STRICMP(name, "vim_starting") == 0) 5147 n = (starting != 0); 5148 #ifdef DYNAMIC_TCL 5149 else if (STRICMP(name, "tcl") == 0) 5150 n = tcl_enabled(FALSE); 5151 #endif 5152 #if defined(USE_ICONV) && defined(DYNAMIC_ICONV) 5153 else if (STRICMP(name, "iconv") == 0) 5154 n = iconv_enabled(FALSE); 5155 #endif 5156 #ifdef DYNAMIC_RUBY 5157 else if (STRICMP(name, "ruby") == 0) 5158 n = ruby_enabled(FALSE); 5159 #endif 5160 #ifdef DYNAMIC_PYTHON 5161 else if (STRICMP(name, "python") == 0) 5162 n = python_enabled(FALSE); 5163 #endif 5164 #ifdef DYNAMIC_PERL 5165 else if (STRICMP(name, "perl") == 0) 5166 n = perl_enabled(FALSE); 5167 #endif 5168 #ifdef FEAT_GUI 5169 else if (STRICMP(name, "gui_running") == 0) 5170 n = (gui.in_use || gui.starting); 5171 # ifdef FEAT_GUI_W32 5172 else if (STRICMP(name, "gui_win32s") == 0) 5173 n = gui_is_win32s(); 5174 # endif 5175 # ifdef FEAT_BROWSE 5176 else if (STRICMP(name, "browse") == 0) 5177 n = gui.in_use; /* gui_mch_browse() works when GUI is running */ 5178 # endif 5179 #endif 5180 #ifdef FEAT_SYN_HL 5181 else if (STRICMP(name, "syntax_items") == 0) 5182 n = syntax_present(curbuf); 5183 #endif 5184 #if defined(WIN3264) 5185 else if (STRICMP(name, "win95") == 0) 5186 n = mch_windows95(); 5187 #endif 5188 } 5189 5190 retvar->var_val.var_number = n; 5191 } 5192 5193 /* 5194 * "hasmapto()" function 5195 */ 5196 static void 5197 f_hasmapto(argvars, retvar) 5198 VAR argvars; 5199 VAR retvar; 5200 { 5201 char_u *name; 5202 char_u *mode; 5203 char_u buf[NUMBUFLEN]; 5204 5205 name = get_var_string(&argvars[0]); 5206 if (argvars[1].var_type == VAR_UNKNOWN) 5207 mode = (char_u *)"nvo"; 5208 else 5209 mode = get_var_string_buf(&argvars[1], buf); 5210 5211 if (map_to_exists(name, mode)) 5212 retvar->var_val.var_number = TRUE; 5213 else 5214 retvar->var_val.var_number = FALSE; 5215 } 5216 5217 /* 5218 * "histadd()" function 5219 */ 5220 /*ARGSUSED*/ 5221 static void 5222 f_histadd(argvars, retvar) 5223 VAR argvars; 5224 VAR retvar; 5225 { 5226 #ifdef FEAT_CMDHIST 5227 int histype; 5228 char_u *str; 5229 char_u buf[NUMBUFLEN]; 5230 #endif 5231 5232 retvar->var_val.var_number = FALSE; 5233 if (check_restricted() || check_secure()) 5234 return; 5235 #ifdef FEAT_CMDHIST 5236 histype = get_histtype(get_var_string(&argvars[0])); 5237 if (histype >= 0) 5238 { 5239 str = get_var_string_buf(&argvars[1], buf); 5240 if (*str != NUL) 5241 { 5242 add_to_history(histype, str, FALSE, NUL); 5243 retvar->var_val.var_number = TRUE; 5244 return; 5245 } 5246 } 5247 #endif 5248 } 5249 5250 /* 5251 * "histdel()" function 5252 */ 5253 /*ARGSUSED*/ 5254 static void 5255 f_histdel(argvars, retvar) 5256 VAR argvars; 5257 VAR retvar; 5258 { 5259 #ifdef FEAT_CMDHIST 5260 int n; 5261 char_u buf[NUMBUFLEN]; 5262 5263 if (argvars[1].var_type == VAR_UNKNOWN) 5264 /* only one argument: clear entire history */ 5265 n = clr_history(get_histtype(get_var_string(&argvars[0]))); 5266 else if (argvars[1].var_type == VAR_NUMBER) 5267 /* index given: remove that entry */ 5268 n = del_history_idx(get_histtype(get_var_string(&argvars[0])), 5269 (int)get_var_number(&argvars[1])); 5270 else 5271 /* string given: remove all matching entries */ 5272 n = del_history_entry(get_histtype(get_var_string(&argvars[0])), 5273 get_var_string_buf(&argvars[1], buf)); 5274 retvar->var_val.var_number = n; 5275 #else 5276 retvar->var_val.var_number = 0; 5277 #endif 5278 } 5279 5280 /* 5281 * "histget()" function 5282 */ 5283 /*ARGSUSED*/ 5284 static void 5285 f_histget(argvars, retvar) 5286 VAR argvars; 5287 VAR retvar; 5288 { 5289 #ifdef FEAT_CMDHIST 5290 int type; 5291 int idx; 5292 5293 type = get_histtype(get_var_string(&argvars[0])); 5294 if (argvars[1].var_type == VAR_UNKNOWN) 5295 idx = get_history_idx(type); 5296 else 5297 idx = (int)get_var_number(&argvars[1]); 5298 retvar->var_val.var_string = vim_strsave(get_history_entry(type, idx)); 5299 #else 5300 retvar->var_val.var_string = NULL; 5301 #endif 5302 retvar->var_type = VAR_STRING; 5303 } 5304 5305 /* 5306 * "histnr()" function 5307 */ 5308 /*ARGSUSED*/ 5309 static void 5310 f_histnr(argvars, retvar) 5311 VAR argvars; 5312 VAR retvar; 5313 { 5314 int i; 5315 5316 #ifdef FEAT_CMDHIST 5317 i = get_histtype(get_var_string(&argvars[0])); 5318 if (i >= HIST_CMD && i < HIST_COUNT) 5319 i = get_history_idx(i); 5320 else 5321 #endif 5322 i = -1; 5323 retvar->var_val.var_number = i; 5324 } 5325 5326 /* 5327 * "highlight_exists()" function 5328 */ 5329 static void 5330 f_hlexists(argvars, retvar) 5331 VAR argvars; 5332 VAR retvar; 5333 { 5334 retvar->var_val.var_number = highlight_exists(get_var_string(&argvars[0])); 5335 } 5336 5337 /* 5338 * "highlightID(name)" function 5339 */ 5340 static void 5341 f_hlID(argvars, retvar) 5342 VAR argvars; 5343 VAR retvar; 5344 { 5345 retvar->var_val.var_number = syn_name2id(get_var_string(&argvars[0])); 5346 } 5347 5348 /* 5349 * "hostname()" function 5350 */ 5351 /*ARGSUSED*/ 5352 static void 5353 f_hostname(argvars, retvar) 5354 VAR argvars; 5355 VAR retvar; 5356 { 5357 char_u hostname[256]; 5358 5359 mch_get_host_name(hostname, 256); 5360 retvar->var_type = VAR_STRING; 5361 retvar->var_val.var_string = vim_strsave(hostname); 5362 } 5363 5364 /* 5365 * iconv() function 5366 */ 5367 /*ARGSUSED*/ 5368 static void 5369 f_iconv(argvars, retvar) 5370 VAR argvars; 5371 VAR retvar; 5372 { 5373 #ifdef FEAT_MBYTE 5374 char_u buf1[NUMBUFLEN]; 5375 char_u buf2[NUMBUFLEN]; 5376 char_u *from, *to, *str; 5377 vimconv_T vimconv; 5378 #endif 5379 5380 retvar->var_type = VAR_STRING; 5381 retvar->var_val.var_string = NULL; 5382 5383 #ifdef FEAT_MBYTE 5384 str = get_var_string(&argvars[0]); 5385 from = enc_canonize(enc_skip(get_var_string_buf(&argvars[1], buf1))); 5386 to = enc_canonize(enc_skip(get_var_string_buf(&argvars[2], buf2))); 5387 vimconv.vc_type = CONV_NONE; 5388 convert_setup(&vimconv, from, to); 5389 5390 /* If the encodings are equal, no conversion needed. */ 5391 if (vimconv.vc_type == CONV_NONE) 5392 retvar->var_val.var_string = vim_strsave(str); 5393 else 5394 retvar->var_val.var_string = string_convert(&vimconv, str, NULL); 5395 5396 convert_setup(&vimconv, NULL, NULL); 5397 vim_free(from); 5398 vim_free(to); 5399 #endif 5400 } 5401 5402 /* 5403 * "indent()" function 5404 */ 5405 static void 5406 f_indent(argvars, retvar) 5407 VAR argvars; 5408 VAR retvar; 5409 { 5410 linenr_T lnum; 5411 5412 lnum = get_var_lnum(argvars); 5413 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 5414 retvar->var_val.var_number = get_indent_lnum(lnum); 5415 else 5416 retvar->var_val.var_number = -1; 5417 } 5418 5419 static int inputsecret_flag = 0; 5420 5421 /* 5422 * "input()" function 5423 * Also handles inputsecret() when inputsecret is set. 5424 */ 5425 static void 5426 f_input(argvars, retvar) 5427 VAR argvars; 5428 VAR retvar; 5429 { 5430 char_u *prompt = get_var_string(&argvars[0]); 5431 char_u *p = NULL; 5432 int c; 5433 char_u buf[NUMBUFLEN]; 5434 int cmd_silent_save = cmd_silent; 5435 5436 retvar->var_type = VAR_STRING; 5437 5438 #ifdef NO_CONSOLE_INPUT 5439 /* While starting up, there is no place to enter text. */ 5440 if (no_console_input()) 5441 { 5442 retvar->var_val.var_string = NULL; 5443 return; 5444 } 5445 #endif 5446 5447 cmd_silent = FALSE; /* Want to see the prompt. */ 5448 if (prompt != NULL) 5449 { 5450 /* Only the part of the message after the last NL is considered as 5451 * prompt for the command line */ 5452 p = vim_strrchr(prompt, '\n'); 5453 if (p == NULL) 5454 p = prompt; 5455 else 5456 { 5457 ++p; 5458 c = *p; 5459 *p = NUL; 5460 msg_start(); 5461 msg_clr_eos(); 5462 msg_puts_attr(prompt, echo_attr); 5463 msg_didout = FALSE; 5464 msg_starthere(); 5465 *p = c; 5466 } 5467 cmdline_row = msg_row; 5468 } 5469 5470 if (argvars[1].var_type != VAR_UNKNOWN) 5471 stuffReadbuffSpec(get_var_string_buf(&argvars[1], buf)); 5472 5473 retvar->var_val.var_string = 5474 getcmdline_prompt(inputsecret_flag ? NUL : '@', p, echo_attr); 5475 5476 /* since the user typed this, no need to wait for return */ 5477 need_wait_return = FALSE; 5478 msg_didout = FALSE; 5479 cmd_silent = cmd_silent_save; 5480 } 5481 5482 /* 5483 * "inputdialog()" function 5484 */ 5485 static void 5486 f_inputdialog(argvars, retvar) 5487 VAR argvars; 5488 VAR retvar; 5489 { 5490 #if defined(FEAT_GUI_TEXTDIALOG) 5491 /* Use a GUI dialog if the GUI is running and 'c' is not in 'guioptions' */ 5492 if (gui.in_use && vim_strchr(p_go, GO_CONDIALOG) == NULL) 5493 { 5494 char_u *message; 5495 char_u buf[NUMBUFLEN]; 5496 5497 message = get_var_string(&argvars[0]); 5498 if (argvars[1].var_type != VAR_UNKNOWN) 5499 { 5500 STRNCPY(IObuff, get_var_string_buf(&argvars[1], buf), IOSIZE); 5501 IObuff[IOSIZE - 1] = NUL; 5502 } 5503 else 5504 IObuff[0] = NUL; 5505 if (do_dialog(VIM_QUESTION, NULL, message, (char_u *)_("&OK\n&Cancel"), 5506 1, IObuff) == 1) 5507 retvar->var_val.var_string = vim_strsave(IObuff); 5508 else 5509 { 5510 if (argvars[1].var_type != VAR_UNKNOWN 5511 && argvars[2].var_type != VAR_UNKNOWN) 5512 retvar->var_val.var_string = vim_strsave( 5513 get_var_string_buf(&argvars[2], buf)); 5514 else 5515 retvar->var_val.var_string = NULL; 5516 } 5517 retvar->var_type = VAR_STRING; 5518 } 5519 else 5520 #endif 5521 f_input(argvars, retvar); 5522 } 5523 5524 static garray_T ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL}; 5525 5526 /* 5527 * "inputrestore()" function 5528 */ 5529 /*ARGSUSED*/ 5530 static void 5531 f_inputrestore(argvars, retvar) 5532 VAR argvars; 5533 VAR retvar; 5534 { 5535 if (ga_userinput.ga_len > 0) 5536 { 5537 --ga_userinput.ga_len; 5538 ++ga_userinput.ga_room; 5539 restore_typeahead((tasave_T *)(ga_userinput.ga_data) 5540 + ga_userinput.ga_len); 5541 retvar->var_val.var_number = 0; /* OK */ 5542 } 5543 else if (p_verbose > 1) 5544 { 5545 msg((char_u *)_("called inputrestore() more often than inputsave()")); 5546 retvar->var_val.var_number = 1; /* Failed */ 5547 } 5548 } 5549 5550 /* 5551 * "inputsave()" function 5552 */ 5553 /*ARGSUSED*/ 5554 static void 5555 f_inputsave(argvars, retvar) 5556 VAR argvars; 5557 VAR retvar; 5558 { 5559 /* Add an entry to the stack of typehead storage. */ 5560 if (ga_grow(&ga_userinput, 1) == OK) 5561 { 5562 save_typeahead((tasave_T *)(ga_userinput.ga_data) 5563 + ga_userinput.ga_len); 5564 ++ga_userinput.ga_len; 5565 --ga_userinput.ga_room; 5566 retvar->var_val.var_number = 0; /* OK */ 5567 } 5568 else 5569 retvar->var_val.var_number = 1; /* Failed */ 5570 } 5571 5572 /* 5573 * "inputsecret()" function 5574 */ 5575 static void 5576 f_inputsecret(argvars, retvar) 5577 VAR argvars; 5578 VAR retvar; 5579 { 5580 ++cmdline_star; 5581 ++inputsecret_flag; 5582 f_input(argvars, retvar); 5583 --cmdline_star; 5584 --inputsecret_flag; 5585 } 5586 5587 /* 5588 * "isdirectory()" function 5589 */ 5590 static void 5591 f_isdirectory(argvars, retvar) 5592 VAR argvars; 5593 VAR retvar; 5594 { 5595 retvar->var_val.var_number = mch_isdir(get_var_string(&argvars[0])); 5596 } 5597 5598 /* 5599 * "last_buffer_nr()" function. 5600 */ 5601 /*ARGSUSED*/ 5602 static void 5603 f_last_buffer_nr(argvars, retvar) 5604 VAR argvars; 5605 VAR retvar; 5606 { 5607 int n = 0; 5608 buf_T *buf; 5609 5610 for (buf = firstbuf; buf != NULL; buf = buf->b_next) 5611 if (n < buf->b_fnum) 5612 n = buf->b_fnum; 5613 5614 retvar->var_val.var_number = n; 5615 } 5616 5617 /* 5618 * "line(string)" function 5619 */ 5620 static void 5621 f_line(argvars, retvar) 5622 VAR argvars; 5623 VAR retvar; 5624 { 5625 linenr_T lnum = 0; 5626 pos_T *fp; 5627 5628 fp = var2fpos(&argvars[0], TRUE); 5629 if (fp != NULL) 5630 lnum = fp->lnum; 5631 retvar->var_val.var_number = lnum; 5632 } 5633 5634 /* 5635 * "line2byte(lnum)" function 5636 */ 5637 /*ARGSUSED*/ 5638 static void 5639 f_line2byte(argvars, retvar) 5640 VAR argvars; 5641 VAR retvar; 5642 { 5643 #ifndef FEAT_BYTEOFF 5644 retvar->var_val.var_number = -1; 5645 #else 5646 linenr_T lnum; 5647 5648 lnum = get_var_lnum(argvars); 5649 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count + 1) 5650 retvar->var_val.var_number = -1; 5651 else 5652 retvar->var_val.var_number = ml_find_line_or_offset(curbuf, lnum, NULL); 5653 if (retvar->var_val.var_number >= 0) 5654 ++retvar->var_val.var_number; 5655 #endif 5656 } 5657 5658 /* 5659 * "lispindent(lnum)" function 5660 */ 5661 static void 5662 f_lispindent(argvars, retvar) 5663 VAR argvars; 5664 VAR retvar; 5665 { 5666 #ifdef FEAT_LISP 5667 pos_T pos; 5668 linenr_T lnum; 5669 5670 pos = curwin->w_cursor; 5671 lnum = get_var_lnum(argvars); 5672 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count) 5673 { 5674 curwin->w_cursor.lnum = lnum; 5675 retvar->var_val.var_number = get_lisp_indent(); 5676 curwin->w_cursor = pos; 5677 } 5678 else 5679 #endif 5680 retvar->var_val.var_number = -1; 5681 } 5682 5683 /* 5684 * "localtime()" function 5685 */ 5686 /*ARGSUSED*/ 5687 static void 5688 f_localtime(argvars, retvar) 5689 VAR argvars; 5690 VAR retvar; 5691 { 5692 retvar->var_val.var_number = (varnumber_T)time(NULL); 5693 } 5694 5695 /* 5696 * "maparg()" function 5697 */ 5698 static void 5699 f_maparg(argvars, retvar) 5700 VAR argvars; 5701 VAR retvar; 5702 { 5703 get_maparg(argvars, retvar, TRUE); 5704 } 5705 5706 /* 5707 * "mapcheck()" function 5708 */ 5709 static void 5710 f_mapcheck(argvars, retvar) 5711 VAR argvars; 5712 VAR retvar; 5713 { 5714 get_maparg(argvars, retvar, FALSE); 5715 } 5716 5717 static void 5718 get_maparg(argvars, retvar, exact) 5719 VAR argvars; 5720 VAR retvar; 5721 int exact; 5722 { 5723 char_u *keys; 5724 char_u *which; 5725 char_u buf[NUMBUFLEN]; 5726 char_u *keys_buf = NULL; 5727 char_u *rhs; 5728 int mode; 5729 garray_T ga; 5730 5731 /* return empty string for failure */ 5732 retvar->var_type = VAR_STRING; 5733 retvar->var_val.var_string = NULL; 5734 5735 keys = get_var_string(&argvars[0]); 5736 if (*keys == NUL) 5737 return; 5738 5739 if (argvars[1].var_type != VAR_UNKNOWN) 5740 which = get_var_string_buf(&argvars[1], buf); 5741 else 5742 which = (char_u *)""; 5743 mode = get_map_mode(&which, 0); 5744 5745 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE); 5746 rhs = check_map(keys, mode, exact); 5747 vim_free(keys_buf); 5748 if (rhs != NULL) 5749 { 5750 ga_init(&ga); 5751 ga.ga_itemsize = 1; 5752 ga.ga_growsize = 40; 5753 5754 while (*rhs != NUL) 5755 ga_concat(&ga, str2special(&rhs, FALSE)); 5756 5757 ga_append(&ga, NUL); 5758 retvar->var_val.var_string = (char_u *)ga.ga_data; 5759 } 5760 } 5761 5762 /* 5763 * "match()" function 5764 */ 5765 static void 5766 f_match(argvars, retvar) 5767 VAR argvars; 5768 VAR retvar; 5769 { 5770 find_some_match(argvars, retvar, 1); 5771 } 5772 5773 /* 5774 * "matchend()" function 5775 */ 5776 static void 5777 f_matchend(argvars, retvar) 5778 VAR argvars; 5779 VAR retvar; 5780 { 5781 find_some_match(argvars, retvar, 0); 5782 } 5783 5784 /* 5785 * "matchstr()" function 5786 */ 5787 static void 5788 f_matchstr(argvars, retvar) 5789 VAR argvars; 5790 VAR retvar; 5791 { 5792 find_some_match(argvars, retvar, 2); 5793 } 5794 5795 static void 5796 find_some_match(argvars, retvar, type) 5797 VAR argvars; 5798 VAR retvar; 5799 int type; 5800 { 5801 char_u *str; 5802 char_u *pat; 5803 regmatch_T regmatch; 5804 char_u patbuf[NUMBUFLEN]; 5805 char_u *save_cpo; 5806 long start = 0; 5807 5808 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 5809 save_cpo = p_cpo; 5810 p_cpo = (char_u *)""; 5811 5812 str = get_var_string(&argvars[0]); 5813 pat = get_var_string_buf(&argvars[1], patbuf); 5814 5815 if (type == 2) 5816 { 5817 retvar->var_type = VAR_STRING; 5818 retvar->var_val.var_string = NULL; 5819 } 5820 else 5821 retvar->var_val.var_number = -1; 5822 5823 if (argvars[2].var_type != VAR_UNKNOWN) 5824 { 5825 start = get_var_number(&argvars[2]); 5826 if (start < 0) 5827 start = 0; 5828 if (start > (long)STRLEN(str)) 5829 goto theend; 5830 str += start; 5831 } 5832 5833 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 5834 if (regmatch.regprog != NULL) 5835 { 5836 regmatch.rm_ic = p_ic; 5837 if (vim_regexec_nl(®match, str, (colnr_T)0)) 5838 { 5839 if (type == 2) 5840 retvar->var_val.var_string = vim_strnsave(regmatch.startp[0], 5841 (int)(regmatch.endp[0] - regmatch.startp[0])); 5842 else 5843 { 5844 if (type != 0) 5845 retvar->var_val.var_number = 5846 (varnumber_T)(regmatch.startp[0] - str); 5847 else 5848 retvar->var_val.var_number = 5849 (varnumber_T)(regmatch.endp[0] - str); 5850 retvar->var_val.var_number += start; 5851 } 5852 } 5853 vim_free(regmatch.regprog); 5854 } 5855 5856 theend: 5857 p_cpo = save_cpo; 5858 } 5859 5860 /* 5861 * "mode()" function 5862 */ 5863 /*ARGSUSED*/ 5864 static void 5865 f_mode(argvars, retvar) 5866 VAR argvars; 5867 VAR retvar; 5868 { 5869 char_u buf[2]; 5870 5871 #ifdef FEAT_VISUAL 5872 if (VIsual_active) 5873 { 5874 if (VIsual_select) 5875 buf[0] = VIsual_mode + 's' - 'v'; 5876 else 5877 buf[0] = VIsual_mode; 5878 } 5879 else 5880 #endif 5881 if (State == HITRETURN || State == ASKMORE || State == SETWSIZE) 5882 buf[0] = 'r'; 5883 else if (State & INSERT) 5884 { 5885 if (State & REPLACE_FLAG) 5886 buf[0] = 'R'; 5887 else 5888 buf[0] = 'i'; 5889 } 5890 else if (State & CMDLINE) 5891 buf[0] = 'c'; 5892 else 5893 buf[0] = 'n'; 5894 5895 buf[1] = NUL; 5896 retvar->var_val.var_string = vim_strsave(buf); 5897 retvar->var_type = VAR_STRING; 5898 } 5899 5900 /* 5901 * "nr2char()" function 5902 */ 5903 static void 5904 f_nr2char(argvars, retvar) 5905 VAR argvars; 5906 VAR retvar; 5907 { 5908 char_u buf[NUMBUFLEN]; 5909 5910 #ifdef FEAT_MBYTE 5911 if (has_mbyte) 5912 buf[(*mb_char2bytes)((int)get_var_number(&argvars[0]), buf)] = NUL; 5913 else 5914 #endif 5915 { 5916 buf[0] = (char_u)get_var_number(&argvars[0]); 5917 buf[1] = NUL; 5918 } 5919 retvar->var_type = VAR_STRING; 5920 retvar->var_val.var_string = vim_strsave(buf); 5921 } 5922 5923 /* 5924 * "rename({from}, {to})" function 5925 */ 5926 static void 5927 f_rename(argvars, retvar) 5928 VAR argvars; 5929 VAR retvar; 5930 { 5931 char_u buf[NUMBUFLEN]; 5932 5933 if (check_restricted() || check_secure()) 5934 retvar->var_val.var_number = -1; 5935 else 5936 retvar->var_val.var_number = vim_rename(get_var_string(&argvars[0]), 5937 get_var_string_buf(&argvars[1], buf)); 5938 } 5939 5940 /* 5941 * "resolve()" function 5942 */ 5943 static void 5944 f_resolve(argvars, retvar) 5945 VAR argvars; 5946 VAR retvar; 5947 { 5948 char_u *p; 5949 5950 p = get_var_string(&argvars[0]); 5951 #ifdef FEAT_SHORTCUT 5952 { 5953 char_u *v = NULL; 5954 5955 v = mch_resolve_shortcut(p); 5956 if (v != NULL) 5957 retvar->var_val.var_string = v; 5958 else 5959 retvar->var_val.var_string = vim_strsave(p); 5960 } 5961 #else 5962 # ifdef HAVE_READLINK 5963 { 5964 char_u buf[MAXPATHL + 1]; 5965 char_u *cpy; 5966 int len; 5967 char_u *remain = NULL; 5968 char_u *q; 5969 int is_relative_to_current = FALSE; 5970 int has_trailing_pathsep = FALSE; 5971 int limit = 100; 5972 5973 p = vim_strsave(p); 5974 5975 if (p[0] == '.' && (vim_ispathsep(p[1]) 5976 || (p[1] == '.' && (vim_ispathsep(p[2]))))) 5977 is_relative_to_current = TRUE; 5978 5979 len = STRLEN(p); 5980 if (len > 0 && vim_ispathsep(p[len-1])) 5981 has_trailing_pathsep = TRUE; 5982 5983 q = getnextcomp(p); 5984 if (*q != NUL) 5985 { 5986 /* Separate the first path component in "p", and keep the 5987 * remainder (beginning with the path separator). */ 5988 remain = vim_strsave(q - 1); 5989 q[-1] = NUL; 5990 } 5991 5992 for (;;) 5993 { 5994 for (;;) 5995 { 5996 len = readlink((char *)p, (char *)buf, MAXPATHL); 5997 if (len <= 0) 5998 break; 5999 buf[len] = NUL; 6000 6001 if (limit-- == 0) 6002 { 6003 vim_free(p); 6004 vim_free(remain); 6005 EMSG(_("E655: Too many symbolic links (cycle?)")); 6006 retvar->var_val.var_string = NULL; 6007 goto fail; 6008 } 6009 6010 /* Ensure that the result will have a trailing path separator 6011 * if the argument has one. */ 6012 if (remain == NULL && has_trailing_pathsep) 6013 add_pathsep(buf); 6014 6015 /* Separate the first path component in the link value and 6016 * concatenate the remainders. */ 6017 q = getnextcomp(vim_ispathsep(*buf) ? buf + 1 : buf); 6018 if (*q != NUL) 6019 { 6020 if (remain == NULL) 6021 remain = vim_strsave(q - 1); 6022 else 6023 { 6024 cpy = vim_strnsave(q-1, STRLEN(q-1)+STRLEN(remain)); 6025 if (cpy != NULL) 6026 { 6027 STRCAT(cpy, remain); 6028 vim_free(remain); 6029 remain = cpy; 6030 } 6031 } 6032 q[-1] = NUL; 6033 } 6034 6035 q = gettail(p); 6036 if (q > p && *q == NUL) 6037 { 6038 /* Ignore trailing path separator. */ 6039 q[-1] = NUL; 6040 q = gettail(p); 6041 } 6042 if (q > p && !mch_isFullName(buf)) 6043 { 6044 /* symlink is relative to directory of argument */ 6045 cpy = alloc((unsigned)(STRLEN(p) + STRLEN(buf) + 1)); 6046 if (cpy != NULL) 6047 { 6048 STRCPY(cpy, p); 6049 STRCPY(gettail(cpy), buf); 6050 vim_free(p); 6051 p = cpy; 6052 } 6053 } 6054 else 6055 { 6056 vim_free(p); 6057 p = vim_strsave(buf); 6058 } 6059 } 6060 6061 if (remain == NULL) 6062 break; 6063 6064 /* Append the first path component of "remain" to "p". */ 6065 q = getnextcomp(remain + 1); 6066 len = q - remain - (*q != NUL); 6067 cpy = vim_strnsave(p, STRLEN(p) + len); 6068 if (cpy != NULL) 6069 { 6070 STRNCAT(cpy, remain, len); 6071 vim_free(p); 6072 p = cpy; 6073 } 6074 /* Shorten "remain". */ 6075 if (*q != NUL) 6076 STRCPY(remain, q - 1); 6077 else 6078 { 6079 vim_free(remain); 6080 remain = NULL; 6081 } 6082 } 6083 6084 /* If the result is a relative path name, make it explicitly relative to 6085 * the current directory if and only if the argument had this form. */ 6086 if (!vim_ispathsep(*p)) 6087 { 6088 if (is_relative_to_current 6089 && *p != NUL 6090 && !(p[0] == '.' 6091 && (p[1] == NUL 6092 || vim_ispathsep(p[1]) 6093 || (p[1] == '.' 6094 && (p[2] == NUL 6095 || vim_ispathsep(p[2])))))) 6096 { 6097 /* Prepend "./". */ 6098 cpy = vim_strnsave((char_u *)"./", 2 + STRLEN(p)); 6099 if (cpy != NULL) 6100 { 6101 STRCAT(cpy, p); 6102 vim_free(p); 6103 p = cpy; 6104 } 6105 } 6106 else if (!is_relative_to_current) 6107 { 6108 /* Strip leading "./". */ 6109 q = p; 6110 while (q[0] == '.' && vim_ispathsep(q[1])) 6111 q += 2; 6112 if (q > p) 6113 mch_memmove(p, p + 2, STRLEN(p + 2) + (size_t)1); 6114 } 6115 } 6116 6117 /* Ensure that the result will have no trailing path separator 6118 * if the argument had none. But keep "/" or "//". */ 6119 if (!has_trailing_pathsep) 6120 { 6121 q = p + STRLEN(p); 6122 while ((q > p + 2 || (q == p + 2 && !vim_ispathsep(*p))) 6123 && vim_ispathsep(q[-1])) 6124 --q; 6125 *q = NUL; 6126 } 6127 6128 retvar->var_val.var_string = p; 6129 } 6130 # else 6131 retvar->var_val.var_string = vim_strsave(p); 6132 # endif 6133 #endif 6134 6135 simplify_filename(retvar->var_val.var_string); 6136 6137 #ifdef HAVE_READLINK 6138 fail: 6139 #endif 6140 retvar->var_type = VAR_STRING; 6141 } 6142 6143 /* 6144 * "simplify()" function 6145 */ 6146 static void 6147 f_simplify(argvars, retvar) 6148 VAR argvars; 6149 VAR retvar; 6150 { 6151 char_u *p; 6152 6153 p = get_var_string(&argvars[0]); 6154 retvar->var_val.var_string = vim_strsave(p); 6155 simplify_filename(retvar->var_val.var_string); /* simplify in place */ 6156 retvar->var_type = VAR_STRING; 6157 } 6158 6159 /* 6160 * "search()" function 6161 */ 6162 static void 6163 f_search(argvars, retvar) 6164 VAR argvars; 6165 VAR retvar; 6166 { 6167 char_u *pat; 6168 pos_T pos; 6169 int save_p_ws = p_ws; 6170 int dir; 6171 6172 pat = get_var_string(&argvars[0]); 6173 dir = get_search_arg(&argvars[1], NULL); /* may set p_ws */ 6174 6175 pos = curwin->w_cursor; 6176 if (searchit(curwin, curbuf, &pos, dir, pat, 1L, 6177 SEARCH_KEEP, RE_SEARCH) != FAIL) 6178 { 6179 retvar->var_val.var_number = pos.lnum; 6180 curwin->w_cursor = pos; 6181 /* "/$" will put the cursor after the end of the line, may need to 6182 * correct that here */ 6183 check_cursor(); 6184 } 6185 else 6186 retvar->var_val.var_number = 0; 6187 p_ws = save_p_ws; 6188 } 6189 6190 #define SP_NOMOVE 1 /* don't move cursor */ 6191 #define SP_REPEAT 2 /* repeat to find outer pair */ 6192 #define SP_RETCOUNT 4 /* return matchcount */ 6193 6194 /* 6195 * "searchpair()" function 6196 */ 6197 static void 6198 f_searchpair(argvars, retvar) 6199 VAR argvars; 6200 VAR retvar; 6201 { 6202 char_u *spat, *mpat, *epat; 6203 char_u *skip; 6204 char_u *pat, *pat2, *pat3; 6205 pos_T pos; 6206 pos_T firstpos; 6207 pos_T save_cursor; 6208 pos_T save_pos; 6209 int save_p_ws = p_ws; 6210 char_u *save_cpo; 6211 int dir; 6212 int flags = 0; 6213 char_u nbuf1[NUMBUFLEN]; 6214 char_u nbuf2[NUMBUFLEN]; 6215 char_u nbuf3[NUMBUFLEN]; 6216 int n; 6217 int r; 6218 int nest = 1; 6219 int err; 6220 6221 retvar->var_val.var_number = 0; /* default: FAIL */ 6222 6223 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ 6224 save_cpo = p_cpo; 6225 p_cpo = (char_u *)""; 6226 6227 /* Get the three pattern arguments: start, middle, end. */ 6228 spat = get_var_string(&argvars[0]); 6229 mpat = get_var_string_buf(&argvars[1], nbuf1); 6230 epat = get_var_string_buf(&argvars[2], nbuf2); 6231 6232 /* Make two search patterns: start/end (pat2, for in nested pairs) and 6233 * start/middle/end (pat3, for the top pair). */ 6234 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15)); 6235 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23)); 6236 if (pat2 == NULL || pat3 == NULL) 6237 goto theend; 6238 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat); 6239 if (*mpat == NUL) 6240 STRCPY(pat3, pat2); 6241 else 6242 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)", 6243 spat, epat, mpat); 6244 6245 /* Handle the optional fourth argument: flags */ 6246 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */ 6247 6248 /* Optional fifth argument: skip expresion */ 6249 if (argvars[3].var_type == VAR_UNKNOWN 6250 || argvars[4].var_type == VAR_UNKNOWN) 6251 skip = (char_u *)""; 6252 else 6253 skip = get_var_string_buf(&argvars[4], nbuf3); 6254 6255 save_cursor = curwin->w_cursor; 6256 pos = curwin->w_cursor; 6257 firstpos.lnum = 0; 6258 pat = pat3; 6259 for (;;) 6260 { 6261 n = searchit(curwin, curbuf, &pos, dir, pat, 1L, 6262 SEARCH_KEEP, RE_SEARCH); 6263 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos))) 6264 /* didn't find it or found the first match again: FAIL */ 6265 break; 6266 6267 if (firstpos.lnum == 0) 6268 firstpos = pos; 6269 6270 /* If the skip pattern matches, ignore this match. */ 6271 if (*skip != NUL) 6272 { 6273 save_pos = curwin->w_cursor; 6274 curwin->w_cursor = pos; 6275 r = eval_to_bool(skip, &err, NULL, FALSE); 6276 curwin->w_cursor = save_pos; 6277 if (err) 6278 { 6279 /* Evaluating {skip} caused an error, break here. */ 6280 curwin->w_cursor = save_cursor; 6281 retvar->var_val.var_number = -1; 6282 break; 6283 } 6284 if (r) 6285 continue; 6286 } 6287 6288 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2)) 6289 { 6290 /* Found end when searching backwards or start when searching 6291 * forward: nested pair. */ 6292 ++nest; 6293 pat = pat2; /* nested, don't search for middle */ 6294 } 6295 else 6296 { 6297 /* Found end when searching forward or start when searching 6298 * backward: end of (nested) pair; or found middle in outer pair. */ 6299 if (--nest == 1) 6300 pat = pat3; /* outer level, search for middle */ 6301 } 6302 6303 if (nest == 0) 6304 { 6305 /* Found the match: return matchcount or line number. */ 6306 if (flags & SP_RETCOUNT) 6307 ++retvar->var_val.var_number; 6308 else 6309 retvar->var_val.var_number = pos.lnum; 6310 curwin->w_cursor = pos; 6311 if (!(flags & SP_REPEAT)) 6312 break; 6313 nest = 1; /* search for next unmatched */ 6314 } 6315 } 6316 6317 /* If 'n' flag is used or search failed: restore cursor position. */ 6318 if ((flags & SP_NOMOVE) || retvar->var_val.var_number == 0) 6319 curwin->w_cursor = save_cursor; 6320 6321 theend: 6322 vim_free(pat2); 6323 vim_free(pat3); 6324 p_ws = save_p_ws; 6325 p_cpo = save_cpo; 6326 } 6327 6328 static int 6329 get_search_arg(varp, flagsp) 6330 VAR varp; 6331 int *flagsp; 6332 { 6333 int dir = FORWARD; 6334 char_u *flags; 6335 char_u nbuf[NUMBUFLEN]; 6336 6337 if (varp->var_type != VAR_UNKNOWN) 6338 { 6339 flags = get_var_string_buf(varp, nbuf); 6340 if (vim_strchr(flags, 'b') != NULL) 6341 dir = BACKWARD; 6342 if (vim_strchr(flags, 'w') != NULL) 6343 p_ws = TRUE; 6344 if (vim_strchr(flags, 'W') != NULL) 6345 p_ws = FALSE; 6346 if (flagsp != NULL) 6347 { 6348 if (vim_strchr(flags, 'n') != NULL) 6349 *flagsp |= SP_NOMOVE; 6350 if (vim_strchr(flags, 'r') != NULL) 6351 *flagsp |= SP_REPEAT; 6352 if (vim_strchr(flags, 'm') != NULL) 6353 *flagsp |= SP_RETCOUNT; 6354 } 6355 } 6356 return dir; 6357 } 6358 6359 /* 6360 * "setbufvar()" function 6361 */ 6362 /*ARGSUSED*/ 6363 static void 6364 f_setbufvar(argvars, retvar) 6365 VAR argvars; 6366 VAR retvar; 6367 { 6368 buf_T *buf; 6369 #ifdef FEAT_AUTOCMD 6370 aco_save_T aco; 6371 #else 6372 buf_T *save_curbuf; 6373 #endif 6374 char_u *varname, *bufvarname; 6375 VAR varp; 6376 char_u nbuf[NUMBUFLEN]; 6377 6378 if (check_restricted() || check_secure()) 6379 return; 6380 ++emsg_off; 6381 buf = get_buf_var(&argvars[0]); 6382 varname = get_var_string(&argvars[1]); 6383 varp = &argvars[2]; 6384 6385 if (buf != NULL && varname != NULL && varp != NULL) 6386 { 6387 /* set curbuf to be our buf, temporarily */ 6388 #ifdef FEAT_AUTOCMD 6389 aucmd_prepbuf(&aco, buf); 6390 #else 6391 save_curbuf = curbuf; 6392 curbuf = buf; 6393 #endif 6394 6395 if (*varname == '&') 6396 { 6397 ++varname; 6398 set_option_value(varname, get_var_number(varp), 6399 get_var_string_buf(varp, nbuf), OPT_LOCAL); 6400 } 6401 else 6402 { 6403 bufvarname = alloc((unsigned)STRLEN(varname) + 3); 6404 if (bufvarname != NULL) 6405 { 6406 STRCPY(bufvarname, "b:"); 6407 STRCPY(bufvarname + 2, varname); 6408 set_var(bufvarname, varp); 6409 vim_free(bufvarname); 6410 } 6411 } 6412 6413 /* reset notion of buffer */ 6414 #ifdef FEAT_AUTOCMD 6415 aucmd_restbuf(&aco); 6416 #else 6417 curbuf = save_curbuf; 6418 #endif 6419 } 6420 --emsg_off; 6421 } 6422 6423 /* 6424 * "setcmdpos()" function 6425 */ 6426 static void 6427 f_setcmdpos(argvars, retvar) 6428 VAR argvars; 6429 VAR retvar; 6430 { 6431 retvar->var_val.var_number = set_cmdline_pos( 6432 (int)get_var_number(&argvars[0]) - 1); 6433 } 6434 6435 /* 6436 * "setline()" function 6437 */ 6438 static void 6439 f_setline(argvars, retvar) 6440 VAR argvars; 6441 VAR retvar; 6442 { 6443 linenr_T lnum; 6444 char_u *line; 6445 6446 lnum = get_var_lnum(argvars); 6447 line = get_var_string(&argvars[1]); 6448 retvar->var_val.var_number = 1; /* FAIL is default */ 6449 6450 if (lnum >= 1 6451 && lnum <= curbuf->b_ml.ml_line_count 6452 && u_savesub(lnum) == OK 6453 && ml_replace(lnum, line, TRUE) == OK) 6454 { 6455 changed_bytes(lnum, 0); 6456 check_cursor_col(); 6457 retvar->var_val.var_number = 0; 6458 } 6459 } 6460 6461 /* 6462 * "setreg()" function 6463 */ 6464 static void 6465 f_setreg(argvars, retvar) 6466 VAR argvars; 6467 VAR retvar; 6468 { 6469 int regname; 6470 char_u *strregname; 6471 char_u *stropt; 6472 int append; 6473 char_u yank_type; 6474 long block_len; 6475 6476 block_len = -1; 6477 yank_type = MAUTO; 6478 append = FALSE; 6479 6480 strregname = get_var_string(argvars); 6481 retvar->var_val.var_number = 1; /* FAIL is default */ 6482 6483 regname = (strregname == NULL ? '"' : *strregname); 6484 if (regname == 0 || regname == '@') 6485 regname = '"'; 6486 else if (regname == '=') 6487 return; 6488 6489 if (argvars[2].var_type != VAR_UNKNOWN) 6490 { 6491 for (stropt = get_var_string(&argvars[2]); *stropt != NUL; ++stropt) 6492 switch (*stropt) 6493 { 6494 case 'a': case 'A': /* append */ 6495 append = TRUE; 6496 break; 6497 case 'v': case 'c': /* character-wise selection */ 6498 yank_type = MCHAR; 6499 break; 6500 case 'V': case 'l': /* line-wise selection */ 6501 yank_type = MLINE; 6502 break; 6503 #ifdef FEAT_VISUAL 6504 case 'b': case Ctrl_V: /* block-wise selection */ 6505 yank_type = MBLOCK; 6506 if (VIM_ISDIGIT(stropt[1])) 6507 { 6508 ++stropt; 6509 block_len = getdigits(&stropt) - 1; 6510 --stropt; 6511 } 6512 break; 6513 #endif 6514 } 6515 } 6516 6517 write_reg_contents_ex(regname, get_var_string(&argvars[1]), -1, 6518 append, yank_type, block_len); 6519 retvar->var_val.var_number = 0; 6520 } 6521 6522 6523 /* 6524 * "setwinvar(expr)" function 6525 */ 6526 /*ARGSUSED*/ 6527 static void 6528 f_setwinvar(argvars, retvar) 6529 VAR argvars; 6530 VAR retvar; 6531 { 6532 win_T *win; 6533 #ifdef FEAT_WINDOWS 6534 win_T *save_curwin; 6535 #endif 6536 char_u *varname, *winvarname; 6537 VAR varp; 6538 char_u nbuf[NUMBUFLEN]; 6539 6540 if (check_restricted() || check_secure()) 6541 return; 6542 ++emsg_off; 6543 win = find_win_by_nr(&argvars[0]); 6544 varname = get_var_string(&argvars[1]); 6545 varp = &argvars[2]; 6546 6547 if (win != NULL && varname != NULL && varp != NULL) 6548 { 6549 #ifdef FEAT_WINDOWS 6550 /* set curwin to be our win, temporarily */ 6551 save_curwin = curwin; 6552 curwin = win; 6553 curbuf = curwin->w_buffer; 6554 #endif 6555 6556 if (*varname == '&') 6557 { 6558 ++varname; 6559 set_option_value(varname, get_var_number(varp), 6560 get_var_string_buf(varp, nbuf), OPT_LOCAL); 6561 } 6562 else 6563 { 6564 winvarname = alloc((unsigned)STRLEN(varname) + 3); 6565 if (winvarname != NULL) 6566 { 6567 STRCPY(winvarname, "w:"); 6568 STRCPY(winvarname + 2, varname); 6569 set_var(winvarname, varp); 6570 vim_free(winvarname); 6571 } 6572 } 6573 6574 #ifdef FEAT_WINDOWS 6575 /* Restore current window, if it's still valid (autocomands can make 6576 * it invalid). */ 6577 if (win_valid(save_curwin)) 6578 { 6579 curwin = save_curwin; 6580 curbuf = curwin->w_buffer; 6581 } 6582 #endif 6583 } 6584 --emsg_off; 6585 } 6586 6587 /* 6588 * "nextnonblank()" function 6589 */ 6590 static void 6591 f_nextnonblank(argvars, retvar) 6592 VAR argvars; 6593 VAR retvar; 6594 { 6595 linenr_T lnum; 6596 6597 for (lnum = get_var_lnum(argvars); ; ++lnum) 6598 { 6599 if (lnum > curbuf->b_ml.ml_line_count) 6600 { 6601 lnum = 0; 6602 break; 6603 } 6604 if (*skipwhite(ml_get(lnum)) != NUL) 6605 break; 6606 } 6607 retvar->var_val.var_number = lnum; 6608 } 6609 6610 /* 6611 * "prevnonblank()" function 6612 */ 6613 static void 6614 f_prevnonblank(argvars, retvar) 6615 VAR argvars; 6616 VAR retvar; 6617 { 6618 linenr_T lnum; 6619 6620 lnum = get_var_lnum(argvars); 6621 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 6622 lnum = 0; 6623 else 6624 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 6625 --lnum; 6626 retvar->var_val.var_number = lnum; 6627 } 6628 6629 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11) 6630 static void make_connection __ARGS((void)); 6631 static int check_connection __ARGS((void)); 6632 6633 static void 6634 make_connection() 6635 { 6636 if (X_DISPLAY == NULL 6637 # ifdef FEAT_GUI 6638 && !gui.in_use 6639 # endif 6640 ) 6641 { 6642 x_force_connect = TRUE; 6643 setup_term_clip(); 6644 x_force_connect = FALSE; 6645 } 6646 } 6647 6648 static int 6649 check_connection() 6650 { 6651 make_connection(); 6652 if (X_DISPLAY == NULL) 6653 { 6654 EMSG(_("E240: No connection to Vim server")); 6655 return FAIL; 6656 } 6657 return OK; 6658 } 6659 #endif 6660 6661 /*ARGSUSED*/ 6662 static void 6663 f_serverlist(argvars, retvar) 6664 VAR argvars; 6665 VAR retvar; 6666 { 6667 char_u *r = NULL; 6668 6669 #ifdef FEAT_CLIENTSERVER 6670 # ifdef WIN32 6671 r = serverGetVimNames(); 6672 # else 6673 make_connection(); 6674 if (X_DISPLAY != NULL) 6675 r = serverGetVimNames(X_DISPLAY); 6676 # endif 6677 #endif 6678 retvar->var_type = VAR_STRING; 6679 retvar->var_val.var_string = r; 6680 } 6681 6682 /*ARGSUSED*/ 6683 static void 6684 f_remote_peek(argvars, retvar) 6685 VAR argvars; 6686 VAR retvar; 6687 { 6688 #ifdef FEAT_CLIENTSERVER 6689 var v; 6690 char_u *s = NULL; 6691 # ifdef WIN32 6692 int n = 0; 6693 # endif 6694 6695 if (check_restricted() || check_secure()) 6696 { 6697 retvar->var_val.var_number = -1; 6698 return; 6699 } 6700 # ifdef WIN32 6701 sscanf(get_var_string(&argvars[0]), "%x", &n); 6702 if (n == 0) 6703 retvar->var_val.var_number = -1; 6704 else 6705 { 6706 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 6707 retvar->var_val.var_number = (s != NULL); 6708 } 6709 # else 6710 retvar->var_val.var_number = 0; 6711 if (check_connection() == FAIL) 6712 return; 6713 6714 retvar->var_val.var_number = serverPeekReply(X_DISPLAY, 6715 serverStrToWin(get_var_string(&argvars[0])), &s); 6716 # endif 6717 6718 if (argvars[1].var_type != VAR_UNKNOWN && retvar->var_val.var_number > 0) 6719 { 6720 v.var_type = VAR_STRING; 6721 v.var_val.var_string = vim_strsave(s); 6722 set_var(get_var_string(&argvars[1]), &v); 6723 } 6724 #else 6725 retvar->var_val.var_number = -1; 6726 #endif 6727 } 6728 6729 /*ARGSUSED*/ 6730 static void 6731 f_remote_read(argvars, retvar) 6732 VAR argvars; 6733 VAR retvar; 6734 { 6735 char_u *r = NULL; 6736 6737 #ifdef FEAT_CLIENTSERVER 6738 if (!check_restricted() && !check_secure()) 6739 { 6740 # ifdef WIN32 6741 /* The server's HWND is encoded in the 'id' parameter */ 6742 int n = 0; 6743 6744 sscanf(get_var_string(&argvars[0]), "%x", &n); 6745 if (n != 0) 6746 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE); 6747 if (r == NULL) 6748 # else 6749 if (check_connection() == FAIL || serverReadReply(X_DISPLAY, 6750 serverStrToWin(get_var_string(&argvars[0])), &r, FALSE) < 0) 6751 # endif 6752 EMSG(_("E277: Unable to read a server reply")); 6753 } 6754 #endif 6755 retvar->var_type = VAR_STRING; 6756 retvar->var_val.var_string = r; 6757 } 6758 6759 /*ARGSUSED*/ 6760 static void 6761 f_server2client(argvars, retvar) 6762 VAR argvars; 6763 VAR retvar; 6764 { 6765 #ifdef FEAT_CLIENTSERVER 6766 char_u buf[NUMBUFLEN]; 6767 char_u *server = get_var_string(&argvars[0]); 6768 char_u *reply = get_var_string_buf(&argvars[1], buf); 6769 6770 retvar->var_val.var_number = -1; 6771 if (check_restricted() || check_secure()) 6772 return; 6773 # ifdef FEAT_X11 6774 if (check_connection() == FAIL) 6775 return; 6776 # endif 6777 6778 if (serverSendReply(server, reply) < 0) 6779 { 6780 EMSG(_("E258: Unable to send to client")); 6781 return; 6782 } 6783 retvar->var_val.var_number = 0; 6784 #else 6785 retvar->var_val.var_number = -1; 6786 #endif 6787 } 6788 6789 #ifdef FEAT_CLIENTSERVER 6790 static void remote_common __ARGS((VAR argvars, VAR retvar, int expr)); 6791 6792 static void 6793 remote_common(argvars, retvar, expr) 6794 VAR argvars; 6795 VAR retvar; 6796 int expr; 6797 { 6798 char_u *server_name; 6799 char_u *keys; 6800 char_u *r = NULL; 6801 char_u buf[NUMBUFLEN]; 6802 # ifdef WIN32 6803 HWND w; 6804 # else 6805 Window w; 6806 # endif 6807 6808 if (check_restricted() || check_secure()) 6809 return; 6810 6811 # ifdef FEAT_X11 6812 if (check_connection() == FAIL) 6813 return; 6814 # endif 6815 6816 server_name = get_var_string(&argvars[0]); 6817 keys = get_var_string_buf(&argvars[1], buf); 6818 # ifdef WIN32 6819 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0) 6820 # else 6821 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE) 6822 < 0) 6823 # endif 6824 { 6825 if (r != NULL) 6826 EMSG(r); /* sending worked but evaluation failed */ 6827 else 6828 EMSG2(_("E241: Unable to send to %s"), server_name); 6829 return; 6830 } 6831 6832 retvar->var_val.var_string = r; 6833 6834 if (argvars[2].var_type != VAR_UNKNOWN) 6835 { 6836 var v; 6837 char_u str[30]; 6838 6839 sprintf((char *)str, "0x%x", (unsigned int)w); 6840 v.var_type = VAR_STRING; 6841 v.var_val.var_string = vim_strsave(str); 6842 set_var(get_var_string(&argvars[2]), &v); 6843 } 6844 } 6845 #endif 6846 6847 /* 6848 * "remote_expr()" function 6849 */ 6850 /*ARGSUSED*/ 6851 static void 6852 f_remote_expr(argvars, retvar) 6853 VAR argvars; 6854 VAR retvar; 6855 { 6856 retvar->var_type = VAR_STRING; 6857 retvar->var_val.var_string = NULL; 6858 #ifdef FEAT_CLIENTSERVER 6859 remote_common(argvars, retvar, TRUE); 6860 #endif 6861 } 6862 6863 /* 6864 * "remote_send()" function 6865 */ 6866 /*ARGSUSED*/ 6867 static void 6868 f_remote_send(argvars, retvar) 6869 VAR argvars; 6870 VAR retvar; 6871 { 6872 retvar->var_type = VAR_STRING; 6873 retvar->var_val.var_string = NULL; 6874 #ifdef FEAT_CLIENTSERVER 6875 remote_common(argvars, retvar, FALSE); 6876 #endif 6877 } 6878 6879 /* 6880 * "remote_foreground()" function 6881 */ 6882 /*ARGSUSED*/ 6883 static void 6884 f_remote_foreground(argvars, retvar) 6885 VAR argvars; 6886 VAR retvar; 6887 { 6888 retvar->var_val.var_number = 0; 6889 #ifdef FEAT_CLIENTSERVER 6890 # ifdef WIN32 6891 /* On Win32 it's done in this application. */ 6892 serverForeground(get_var_string(&argvars[0])); 6893 # else 6894 /* Send a foreground() expression to the server. */ 6895 argvars[1].var_type = VAR_STRING; 6896 argvars[1].var_val.var_string = vim_strsave((char_u *)"foreground()"); 6897 argvars[2].var_type = VAR_UNKNOWN; 6898 remote_common(argvars, retvar, TRUE); 6899 vim_free(argvars[1].var_val.var_string); 6900 # endif 6901 #endif 6902 } 6903 6904 #ifdef HAVE_STRFTIME 6905 /* 6906 * "strftime({format}[, {time}])" function 6907 */ 6908 static void 6909 f_strftime(argvars, retvar) 6910 VAR argvars; 6911 VAR retvar; 6912 { 6913 char_u result_buf[256]; 6914 struct tm *curtime; 6915 time_t seconds; 6916 char_u *p; 6917 6918 retvar->var_type = VAR_STRING; 6919 6920 p = get_var_string(&argvars[0]); 6921 if (argvars[1].var_type == VAR_UNKNOWN) 6922 seconds = time(NULL); 6923 else 6924 seconds = (time_t)get_var_number(&argvars[1]); 6925 curtime = localtime(&seconds); 6926 /* MSVC returns NULL for an invalid value of seconds. */ 6927 if (curtime == NULL) 6928 retvar->var_val.var_string = vim_strsave((char_u *)_("(Invalid)")); 6929 else 6930 { 6931 # ifdef FEAT_MBYTE 6932 vimconv_T conv; 6933 char_u *enc; 6934 6935 conv.vc_type = CONV_NONE; 6936 enc = enc_locale(); 6937 convert_setup(&conv, p_enc, enc); 6938 if (conv.vc_type != CONV_NONE) 6939 p = string_convert(&conv, p, NULL); 6940 # endif 6941 if (p != NULL) 6942 (void)strftime((char *)result_buf, sizeof(result_buf), 6943 (char *)p, curtime); 6944 else 6945 result_buf[0] = NUL; 6946 6947 # ifdef FEAT_MBYTE 6948 if (conv.vc_type != CONV_NONE) 6949 vim_free(p); 6950 convert_setup(&conv, enc, p_enc); 6951 if (conv.vc_type != CONV_NONE) 6952 retvar->var_val.var_string = 6953 string_convert(&conv, result_buf, NULL); 6954 else 6955 # endif 6956 retvar->var_val.var_string = vim_strsave(result_buf); 6957 6958 # ifdef FEAT_MBYTE 6959 /* Release conversion descriptors */ 6960 convert_setup(&conv, NULL, NULL); 6961 vim_free(enc); 6962 # endif 6963 } 6964 } 6965 #endif 6966 6967 /* 6968 * "stridx()" function 6969 */ 6970 static void 6971 f_stridx(argvars, retvar) 6972 VAR argvars; 6973 VAR retvar; 6974 { 6975 char_u buf[NUMBUFLEN]; 6976 char_u *needle; 6977 char_u *haystack; 6978 char_u *pos; 6979 6980 needle = get_var_string(&argvars[1]); 6981 haystack = get_var_string_buf(&argvars[0], buf); 6982 pos = (char_u *)strstr((char *)haystack, (char *)needle); 6983 6984 if (pos == NULL) 6985 retvar->var_val.var_number = -1; 6986 else 6987 retvar->var_val.var_number = (varnumber_T) (pos - haystack); 6988 } 6989 6990 /* 6991 * "strridx()" function 6992 */ 6993 static void 6994 f_strridx(argvars, retvar) 6995 VAR argvars; 6996 VAR retvar; 6997 { 6998 char_u buf[NUMBUFLEN]; 6999 char_u *needle; 7000 char_u *haystack; 7001 char_u *rest; 7002 char_u *lastmatch = NULL; 7003 7004 needle = get_var_string(&argvars[1]); 7005 haystack = get_var_string_buf(&argvars[0], buf); 7006 rest = haystack; 7007 while (*haystack != '\0') 7008 { 7009 rest = (char_u *)strstr((char *)rest, (char *)needle); 7010 if (rest == NULL) 7011 break; 7012 lastmatch = rest++; 7013 } 7014 7015 if (lastmatch == NULL) 7016 retvar->var_val.var_number = -1; 7017 else 7018 retvar->var_val.var_number = (varnumber_T) (lastmatch - haystack); 7019 } 7020 7021 /* 7022 * "strlen()" function 7023 */ 7024 static void 7025 f_strlen(argvars, retvar) 7026 VAR argvars; 7027 VAR retvar; 7028 { 7029 retvar->var_val.var_number = (varnumber_T) (STRLEN(get_var_string(&argvars[0]))); 7030 } 7031 7032 /* 7033 * "strpart()" function 7034 */ 7035 static void 7036 f_strpart(argvars, retvar) 7037 VAR argvars; 7038 VAR retvar; 7039 { 7040 char_u *p; 7041 int n; 7042 int len; 7043 int slen; 7044 7045 p = get_var_string(&argvars[0]); 7046 slen = (int)STRLEN(p); 7047 7048 n = get_var_number(&argvars[1]); 7049 if (argvars[2].var_type != VAR_UNKNOWN) 7050 len = get_var_number(&argvars[2]); 7051 else 7052 len = slen - n; /* default len: all bytes that are available. */ 7053 7054 /* 7055 * Only return the overlap between the specified part and the actual 7056 * string. 7057 */ 7058 if (n < 0) 7059 { 7060 len += n; 7061 n = 0; 7062 } 7063 else if (n > slen) 7064 n = slen; 7065 if (len < 0) 7066 len = 0; 7067 else if (n + len > slen) 7068 len = slen - n; 7069 7070 retvar->var_type = VAR_STRING; 7071 retvar->var_val.var_string = vim_strnsave(p + n, len); 7072 } 7073 7074 /* 7075 * "strtrans()" function 7076 */ 7077 static void 7078 f_strtrans(argvars, retvar) 7079 VAR argvars; 7080 VAR retvar; 7081 { 7082 retvar->var_type = VAR_STRING; 7083 retvar->var_val.var_string = transstr(get_var_string(&argvars[0])); 7084 } 7085 7086 /* 7087 * "synID(line, col, trans)" function 7088 */ 7089 /*ARGSUSED*/ 7090 static void 7091 f_synID(argvars, retvar) 7092 VAR argvars; 7093 VAR retvar; 7094 { 7095 int id = 0; 7096 #ifdef FEAT_SYN_HL 7097 long line; 7098 long col; 7099 int trans; 7100 7101 line = get_var_lnum(argvars); 7102 col = get_var_number(&argvars[1]) - 1; 7103 trans = get_var_number(&argvars[2]); 7104 7105 if (line >= 1 && line <= curbuf->b_ml.ml_line_count 7106 && col >= 0 && col < (long)STRLEN(ml_get(line))) 7107 id = syn_get_id(line, col, trans); 7108 #endif 7109 7110 retvar->var_val.var_number = id; 7111 } 7112 7113 /* 7114 * "synIDattr(id, what [, mode])" function 7115 */ 7116 /*ARGSUSED*/ 7117 static void 7118 f_synIDattr(argvars, retvar) 7119 VAR argvars; 7120 VAR retvar; 7121 { 7122 char_u *p = NULL; 7123 #ifdef FEAT_SYN_HL 7124 int id; 7125 char_u *what; 7126 char_u *mode; 7127 char_u modebuf[NUMBUFLEN]; 7128 int modec; 7129 7130 id = get_var_number(&argvars[0]); 7131 what = get_var_string(&argvars[1]); 7132 if (argvars[2].var_type != VAR_UNKNOWN) 7133 { 7134 mode = get_var_string_buf(&argvars[2], modebuf); 7135 modec = TOLOWER_ASC(mode[0]); 7136 if (modec != 't' && modec != 'c' 7137 #ifdef FEAT_GUI 7138 && modec != 'g' 7139 #endif 7140 ) 7141 modec = 0; /* replace invalid with current */ 7142 } 7143 else 7144 { 7145 #ifdef FEAT_GUI 7146 if (gui.in_use) 7147 modec = 'g'; 7148 else 7149 #endif 7150 if (t_colors > 1) 7151 modec = 'c'; 7152 else 7153 modec = 't'; 7154 } 7155 7156 7157 switch (TOLOWER_ASC(what[0])) 7158 { 7159 case 'b': 7160 if (TOLOWER_ASC(what[1]) == 'g') /* bg[#] */ 7161 p = highlight_color(id, what, modec); 7162 else /* bold */ 7163 p = highlight_has_attr(id, HL_BOLD, modec); 7164 break; 7165 7166 case 'f': /* fg[#] */ 7167 p = highlight_color(id, what, modec); 7168 break; 7169 7170 case 'i': 7171 if (TOLOWER_ASC(what[1]) == 'n') /* inverse */ 7172 p = highlight_has_attr(id, HL_INVERSE, modec); 7173 else /* italic */ 7174 p = highlight_has_attr(id, HL_ITALIC, modec); 7175 break; 7176 7177 case 'n': /* name */ 7178 p = get_highlight_name(NULL, id - 1); 7179 break; 7180 7181 case 'r': /* reverse */ 7182 p = highlight_has_attr(id, HL_INVERSE, modec); 7183 break; 7184 7185 case 's': /* standout */ 7186 p = highlight_has_attr(id, HL_STANDOUT, modec); 7187 break; 7188 7189 case 'u': /* underline */ 7190 p = highlight_has_attr(id, HL_UNDERLINE, modec); 7191 break; 7192 } 7193 7194 if (p != NULL) 7195 p = vim_strsave(p); 7196 #endif 7197 retvar->var_type = VAR_STRING; 7198 retvar->var_val.var_string = p; 7199 } 7200 7201 /* 7202 * "synIDtrans(id)" function 7203 */ 7204 /*ARGSUSED*/ 7205 static void 7206 f_synIDtrans(argvars, retvar) 7207 VAR argvars; 7208 VAR retvar; 7209 { 7210 int id; 7211 7212 #ifdef FEAT_SYN_HL 7213 id = get_var_number(&argvars[0]); 7214 7215 if (id > 0) 7216 id = syn_get_final_id(id); 7217 else 7218 #endif 7219 id = 0; 7220 7221 retvar->var_val.var_number = id; 7222 } 7223 7224 /* 7225 * "system()" function 7226 */ 7227 static void 7228 f_system(argvars, retvar) 7229 VAR argvars; 7230 VAR retvar; 7231 { 7232 char_u *p; 7233 7234 p = get_cmd_output(get_var_string(&argvars[0]), SHELL_SILENT); 7235 #ifdef USE_CR 7236 /* translate <CR> into <NL> */ 7237 if (p != NULL) 7238 { 7239 char_u *s; 7240 7241 for (s = p; *s; ++s) 7242 { 7243 if (*s == CAR) 7244 *s = NL; 7245 } 7246 } 7247 #else 7248 # ifdef USE_CRNL 7249 /* translate <CR><NL> into <NL> */ 7250 if (p != NULL) 7251 { 7252 char_u *s, *d; 7253 7254 d = p; 7255 for (s = p; *s; ++s) 7256 { 7257 if (s[0] == CAR && s[1] == NL) 7258 ++s; 7259 *d++ = *s; 7260 } 7261 *d = NUL; 7262 } 7263 # endif 7264 #endif 7265 retvar->var_type = VAR_STRING; 7266 retvar->var_val.var_string = p; 7267 } 7268 7269 /* 7270 * "submatch()" function 7271 */ 7272 static void 7273 f_submatch(argvars, retvar) 7274 VAR argvars; 7275 VAR retvar; 7276 { 7277 retvar->var_type = VAR_STRING; 7278 retvar->var_val.var_string = reg_submatch((int)get_var_number(&argvars[0])); 7279 } 7280 7281 /* 7282 * "substitute()" function 7283 */ 7284 static void 7285 f_substitute(argvars, retvar) 7286 VAR argvars; 7287 VAR retvar; 7288 { 7289 char_u patbuf[NUMBUFLEN]; 7290 char_u subbuf[NUMBUFLEN]; 7291 char_u flagsbuf[NUMBUFLEN]; 7292 7293 retvar->var_type = VAR_STRING; 7294 retvar->var_val.var_string = do_string_sub( 7295 get_var_string(&argvars[0]), 7296 get_var_string_buf(&argvars[1], patbuf), 7297 get_var_string_buf(&argvars[2], subbuf), 7298 get_var_string_buf(&argvars[3], flagsbuf)); 7299 } 7300 7301 /* 7302 * "tempname()" function 7303 */ 7304 /*ARGSUSED*/ 7305 static void 7306 f_tempname(argvars, retvar) 7307 VAR argvars; 7308 VAR retvar; 7309 { 7310 static int x = 'A'; 7311 7312 retvar->var_type = VAR_STRING; 7313 retvar->var_val.var_string = vim_tempname(x); 7314 7315 /* Advance 'x' to use A-Z and 0-9, so that there are at least 34 different 7316 * names. Skip 'I' and 'O', they are used for shell redirection. */ 7317 do 7318 { 7319 if (x == 'Z') 7320 x = '0'; 7321 else if (x == '9') 7322 x = 'A'; 7323 else 7324 { 7325 #ifdef EBCDIC 7326 if (x == 'I') 7327 x = 'J'; 7328 else if (x == 'R') 7329 x = 'S'; 7330 else 7331 #endif 7332 ++x; 7333 } 7334 } while (x == 'I' || x == 'O'); 7335 } 7336 7337 /* 7338 * "tolower(string)" function 7339 */ 7340 static void 7341 f_tolower(argvars, retvar) 7342 VAR argvars; 7343 VAR retvar; 7344 { 7345 char_u *p; 7346 7347 p = vim_strsave(get_var_string(&argvars[0])); 7348 retvar->var_type = VAR_STRING; 7349 retvar->var_val.var_string = p; 7350 7351 if (p != NULL) 7352 while (*p != NUL) 7353 { 7354 #ifdef FEAT_MBYTE 7355 int l; 7356 7357 if (enc_utf8) 7358 { 7359 int c, lc; 7360 7361 c = utf_ptr2char(p); 7362 lc = utf_tolower(c); 7363 l = utf_ptr2len_check(p); 7364 /* TODO: reallocate string when byte count changes. */ 7365 if (utf_char2len(lc) == l) 7366 utf_char2bytes(lc, p); 7367 p += l; 7368 } 7369 else if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1) 7370 p += l; /* skip multi-byte character */ 7371 else 7372 #endif 7373 { 7374 *p = TOLOWER_LOC(*p); /* note that tolower() can be a macro */ 7375 ++p; 7376 } 7377 } 7378 } 7379 7380 /* 7381 * "toupper(string)" function 7382 */ 7383 static void 7384 f_toupper(argvars, retvar) 7385 VAR argvars; 7386 VAR retvar; 7387 { 7388 char_u *p; 7389 7390 p = vim_strsave(get_var_string(&argvars[0])); 7391 retvar->var_type = VAR_STRING; 7392 retvar->var_val.var_string = p; 7393 7394 if (p != NULL) 7395 while (*p != NUL) 7396 { 7397 #ifdef FEAT_MBYTE 7398 int l; 7399 7400 if (enc_utf8) 7401 { 7402 int c, uc; 7403 7404 c = utf_ptr2char(p); 7405 uc = utf_toupper(c); 7406 l = utf_ptr2len_check(p); 7407 /* TODO: reallocate string when byte count changes. */ 7408 if (utf_char2len(uc) == l) 7409 utf_char2bytes(uc, p); 7410 p += l; 7411 } 7412 else if (has_mbyte && (l = (*mb_ptr2len_check)(p)) > 1) 7413 p += l; /* skip multi-byte character */ 7414 else 7415 #endif 7416 { 7417 *p = TOUPPER_LOC(*p); /* note that toupper() can be a macro */ 7418 p++; 7419 } 7420 } 7421 } 7422 7423 /* 7424 * "type(expr)" function 7425 */ 7426 static void 7427 f_type(argvars, retvar) 7428 VAR argvars; 7429 VAR retvar; 7430 { 7431 if (argvars[0].var_type == VAR_NUMBER) 7432 retvar->var_val.var_number = 0; 7433 else 7434 retvar->var_val.var_number = 1; 7435 } 7436 7437 /* 7438 * "virtcol(string)" function 7439 */ 7440 static void 7441 f_virtcol(argvars, retvar) 7442 VAR argvars; 7443 VAR retvar; 7444 { 7445 colnr_T vcol = 0; 7446 pos_T *fp; 7447 7448 fp = var2fpos(&argvars[0], FALSE); 7449 if (fp != NULL && fp->lnum <= curbuf->b_ml.ml_line_count) 7450 { 7451 getvvcol(curwin, fp, NULL, NULL, &vcol); 7452 ++vcol; 7453 } 7454 7455 retvar->var_val.var_number = vcol; 7456 } 7457 7458 /* 7459 * "visualmode()" function 7460 */ 7461 /*ARGSUSED*/ 7462 static void 7463 f_visualmode(argvars, retvar) 7464 VAR argvars; 7465 VAR retvar; 7466 { 7467 #ifdef FEAT_VISUAL 7468 char_u str[2]; 7469 7470 retvar->var_type = VAR_STRING; 7471 str[0] = curbuf->b_visual_mode_eval; 7472 str[1] = NUL; 7473 retvar->var_val.var_string = vim_strsave(str); 7474 7475 /* A non-zero number or non-empty string argument: reset mode. */ 7476 if ((argvars[0].var_type == VAR_NUMBER 7477 && argvars[0].var_val.var_number != 0) 7478 || (argvars[0].var_type == VAR_STRING 7479 && *get_var_string(&argvars[0]) != NUL)) 7480 curbuf->b_visual_mode_eval = NUL; 7481 #else 7482 retvar->var_val.var_number = 0; /* return anything, it won't work anyway */ 7483 #endif 7484 } 7485 7486 /* 7487 * "winbufnr(nr)" function 7488 */ 7489 static void 7490 f_winbufnr(argvars, retvar) 7491 VAR argvars; 7492 VAR retvar; 7493 { 7494 win_T *wp; 7495 7496 wp = find_win_by_nr(&argvars[0]); 7497 if (wp == NULL) 7498 retvar->var_val.var_number = -1; 7499 else 7500 retvar->var_val.var_number = wp->w_buffer->b_fnum; 7501 } 7502 7503 /* 7504 * "wincol()" function 7505 */ 7506 /*ARGSUSED*/ 7507 static void 7508 f_wincol(argvars, retvar) 7509 VAR argvars; 7510 VAR retvar; 7511 { 7512 validate_cursor(); 7513 retvar->var_val.var_number = curwin->w_wcol + 1; 7514 } 7515 7516 /* 7517 * "winheight(nr)" function 7518 */ 7519 static void 7520 f_winheight(argvars, retvar) 7521 VAR argvars; 7522 VAR retvar; 7523 { 7524 win_T *wp; 7525 7526 wp = find_win_by_nr(&argvars[0]); 7527 if (wp == NULL) 7528 retvar->var_val.var_number = -1; 7529 else 7530 retvar->var_val.var_number = wp->w_height; 7531 } 7532 7533 /* 7534 * "winline()" function 7535 */ 7536 /*ARGSUSED*/ 7537 static void 7538 f_winline(argvars, retvar) 7539 VAR argvars; 7540 VAR retvar; 7541 { 7542 validate_cursor(); 7543 retvar->var_val.var_number = curwin->w_wrow + 1; 7544 } 7545 7546 /* 7547 * "winnr()" function 7548 */ 7549 /* ARGSUSED */ 7550 static void 7551 f_winnr(argvars, retvar) 7552 VAR argvars; 7553 VAR retvar; 7554 { 7555 int nr = 1; 7556 #ifdef FEAT_WINDOWS 7557 win_T *wp; 7558 7559 for (wp = firstwin; wp != curwin; wp = wp->w_next) 7560 ++nr; 7561 #endif 7562 retvar->var_val.var_number = nr; 7563 } 7564 7565 /* 7566 * "winrestcmd()" function 7567 */ 7568 /* ARGSUSED */ 7569 static void 7570 f_winrestcmd(argvars, retvar) 7571 VAR argvars; 7572 VAR retvar; 7573 { 7574 #ifdef FEAT_WINDOWS 7575 win_T *wp; 7576 int winnr = 1; 7577 garray_T ga; 7578 char_u buf[50]; 7579 7580 ga_init2(&ga, (int)sizeof(char), 70); 7581 for (wp = firstwin; wp != NULL; wp = wp->w_next) 7582 { 7583 sprintf((char *)buf, "%dresize %d|", winnr, wp->w_height); 7584 ga_concat(&ga, buf); 7585 # ifdef FEAT_VERTSPLIT 7586 sprintf((char *)buf, "vert %dresize %d|", winnr, wp->w_width); 7587 ga_concat(&ga, buf); 7588 # endif 7589 ++winnr; 7590 } 7591 7592 retvar->var_val.var_string = ga.ga_data; 7593 #else 7594 retvar->var_val.var_string = NULL; 7595 #endif 7596 retvar->var_type = VAR_STRING; 7597 } 7598 7599 /* 7600 * "winwidth(nr)" function 7601 */ 7602 static void 7603 f_winwidth(argvars, retvar) 7604 VAR argvars; 7605 VAR retvar; 7606 { 7607 win_T *wp; 7608 7609 wp = find_win_by_nr(&argvars[0]); 7610 if (wp == NULL) 7611 retvar->var_val.var_number = -1; 7612 else 7613 #ifdef FEAT_VERTSPLIT 7614 retvar->var_val.var_number = wp->w_width; 7615 #else 7616 retvar->var_val.var_number = Columns; 7617 #endif 7618 } 7619 7620 static win_T * 7621 find_win_by_nr(vp) 7622 VAR vp; 7623 { 7624 #ifdef FEAT_WINDOWS 7625 win_T *wp; 7626 #endif 7627 int nr; 7628 7629 nr = get_var_number(vp); 7630 7631 #ifdef FEAT_WINDOWS 7632 if (nr == 0) 7633 return curwin; 7634 7635 for (wp = firstwin; wp != NULL; wp = wp->w_next) 7636 if (--nr <= 0) 7637 break; 7638 return wp; 7639 #else 7640 if (nr == 0 || nr == 1) 7641 return curwin; 7642 return NULL; 7643 #endif 7644 } 7645 7646 /* 7647 * Translate a String variable into a position. 7648 */ 7649 static pos_T * 7650 var2fpos(varp, lnum) 7651 VAR varp; 7652 int lnum; /* TRUE when $ is last line */ 7653 { 7654 char_u *name; 7655 static pos_T pos; 7656 pos_T *pp; 7657 7658 name = get_var_string(varp); 7659 if (name[0] == '.') /* cursor */ 7660 return &curwin->w_cursor; 7661 if (name[0] == '\'') /* mark */ 7662 { 7663 pp = getmark(name[1], FALSE); 7664 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) 7665 return NULL; 7666 return pp; 7667 } 7668 if (name[0] == '$') /* last column or line */ 7669 { 7670 if (lnum) 7671 { 7672 pos.lnum = curbuf->b_ml.ml_line_count; 7673 pos.col = 0; 7674 } 7675 else 7676 { 7677 pos.lnum = curwin->w_cursor.lnum; 7678 pos.col = (colnr_T)STRLEN(ml_get_curline()); 7679 } 7680 return &pos; 7681 } 7682 return NULL; 7683 } 7684 7685 /* 7686 * Get the length of an environment variable name. 7687 * Advance "arg" to the first character after the name. 7688 * Return 0 for error. 7689 */ 7690 static int 7691 get_env_len(arg) 7692 char_u **arg; 7693 { 7694 char_u *p; 7695 int len; 7696 7697 for (p = *arg; vim_isIDc(*p); ++p) 7698 ; 7699 if (p == *arg) /* no name found */ 7700 return 0; 7701 7702 len = (int)(p - *arg); 7703 *arg = p; 7704 return len; 7705 } 7706 7707 /* 7708 * Get the length of the name of a function or internal variable. 7709 * "arg" is advanced to the first non-white character after the name. 7710 * Return 0 if something is wrong. 7711 */ 7712 static int 7713 get_id_len(arg) 7714 char_u **arg; 7715 { 7716 char_u *p; 7717 int len; 7718 7719 /* Find the end of the name. */ 7720 for (p = *arg; eval_isnamec(*p); ++p) 7721 ; 7722 if (p == *arg) /* no name found */ 7723 return 0; 7724 7725 len = (int)(p - *arg); 7726 *arg = skipwhite(p); 7727 7728 return len; 7729 } 7730 7731 /* 7732 * Get the length of the name of a function. 7733 * "arg" is advanced to the first non-white character after the name. 7734 * Return 0 if something is wrong. 7735 * If the name contains 'magic' {}'s, expand them and return the 7736 * expanded name in an allocated string via 'alias' - caller must free. 7737 */ 7738 static int 7739 get_func_len(arg, alias, evaluate) 7740 char_u **arg; 7741 char_u **alias; 7742 int evaluate; 7743 { 7744 int len; 7745 #ifdef FEAT_MAGIC_BRACES 7746 char_u *p; 7747 char_u *expr_start; 7748 char_u *expr_end; 7749 #endif 7750 7751 *alias = NULL; /* default to no alias */ 7752 7753 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA 7754 && (*arg)[2] == (int)KE_SNR) 7755 { 7756 /* hard coded <SNR>, already translated */ 7757 *arg += 3; 7758 return get_id_len(arg) + 3; 7759 } 7760 len = eval_fname_script(*arg); 7761 if (len > 0) 7762 { 7763 /* literal "<SID>", "s:" or "<SNR>" */ 7764 *arg += len; 7765 } 7766 7767 #ifdef FEAT_MAGIC_BRACES 7768 /* 7769 * Find the end of the name; 7770 */ 7771 p = find_name_end(*arg, &expr_start, &expr_end); 7772 /* check for {} construction */ 7773 if (expr_start != NULL) 7774 { 7775 char_u *temp_string; 7776 7777 if (!evaluate) 7778 { 7779 len += (int)(p - *arg); 7780 *arg = skipwhite(p); 7781 return len; 7782 } 7783 7784 /* 7785 * Include any <SID> etc in the expanded string: 7786 * Thus the -len here. 7787 */ 7788 temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); 7789 if (temp_string == NULL) 7790 return 0; 7791 *alias = temp_string; 7792 *arg = skipwhite(p); 7793 return (int)STRLEN(temp_string); 7794 } 7795 #endif 7796 7797 len += get_id_len(arg); 7798 if (len == 0) 7799 EMSG2(_(e_invexpr2), *arg); 7800 7801 return len; 7802 } 7803 7804 static char_u * 7805 find_name_end(arg, expr_start, expr_end) 7806 char_u *arg; 7807 char_u **expr_start; 7808 char_u **expr_end; 7809 { 7810 int nesting = 0; 7811 char_u *p; 7812 7813 *expr_start = NULL; 7814 *expr_end = NULL; 7815 7816 for (p = arg; (*p != NUL && (eval_isnamec(*p) || nesting != 0)); ++p) 7817 { 7818 #ifdef FEAT_MAGIC_BRACES 7819 if (*p == '{') 7820 { 7821 nesting++; 7822 if (*expr_start == NULL) 7823 *expr_start = p; 7824 } 7825 else if (*p == '}') 7826 { 7827 nesting--; 7828 if (nesting == 0 && *expr_end == NULL) 7829 *expr_end = p; 7830 } 7831 #endif 7832 } 7833 7834 return p; 7835 } 7836 7837 /* 7838 * Return TRUE if character "c" can be used in a variable or function name. 7839 */ 7840 static int 7841 eval_isnamec(c) 7842 int c; 7843 { 7844 return (ASCII_ISALNUM(c) || c == '_' || c == ':' 7845 #ifdef FEAT_MAGIC_BRACES 7846 || c == '{' || c == '}' 7847 #endif 7848 ); 7849 } 7850 7851 /* 7852 * Find a v: variable. 7853 * Return it's index, or -1 if not found. 7854 */ 7855 static int 7856 find_vim_var(name, len) 7857 char_u *name; 7858 int len; /* length of "name" */ 7859 { 7860 char_u *vname; 7861 int vlen; 7862 int i; 7863 7864 /* 7865 * Ignore "v:" for old built-in variables, require it for new ones. 7866 */ 7867 if (name[0] == 'v' && name[1] == ':') 7868 { 7869 vname = name + 2; 7870 vlen = len - 2; 7871 } 7872 else 7873 { 7874 vname = name; 7875 vlen = len; 7876 } 7877 for (i = 0; i < VV_LEN; ++i) 7878 if (vlen == vimvars[i].len && STRCMP(vname, vimvars[i].name) == 0 7879 && ((vimvars[i].flags & VV_COMPAT) || vname != name)) 7880 return i; 7881 return -1; 7882 } 7883 7884 /* 7885 * Set number v: variable to "val". 7886 */ 7887 void 7888 set_vim_var_nr(idx, val) 7889 int idx; 7890 long val; 7891 { 7892 vimvars[idx].val = (char_u *)val; 7893 } 7894 7895 /* 7896 * Get number v: variable value; 7897 */ 7898 long 7899 get_vim_var_nr(idx) 7900 int idx; 7901 { 7902 return (long)vimvars[idx].val; 7903 } 7904 7905 /* 7906 * Set v:count, v:count1 and v:prevcount. 7907 */ 7908 void 7909 set_vcount(count, count1) 7910 long count; 7911 long count1; 7912 { 7913 vimvars[VV_PREVCOUNT].val = vimvars[VV_COUNT].val; 7914 vimvars[VV_COUNT].val = (char_u *)count; 7915 vimvars[VV_COUNT1].val = (char_u *)count1; 7916 } 7917 7918 /* 7919 * Set string v: variable to a copy of "val". 7920 */ 7921 void 7922 set_vim_var_string(idx, val, len) 7923 int idx; 7924 char_u *val; 7925 int len; /* length of "val" to use or -1 (whole string) */ 7926 { 7927 vim_free(vimvars[idx].val); 7928 if (val == NULL) 7929 vimvars[idx].val = NULL; 7930 else if (len == -1) 7931 vimvars[idx].val = vim_strsave(val); 7932 else 7933 vimvars[idx].val = vim_strnsave(val, len); 7934 } 7935 7936 /* 7937 * Set v:register if needed. 7938 */ 7939 void 7940 set_reg_var(c) 7941 int c; 7942 { 7943 char_u regname; 7944 7945 if (c == 0 || c == ' ') 7946 regname = '"'; 7947 else 7948 regname = c; 7949 /* Avoid free/alloc when the value is already right. */ 7950 if (vimvars[VV_REG].val == NULL || vimvars[VV_REG].val[0] != c) 7951 set_vim_var_string(VV_REG, ®name, 1); 7952 } 7953 7954 /* 7955 * Get or set v:exception. If "oldval" == NULL, return the current value. 7956 * Otherwise, restore the value to "oldval" and return NULL. 7957 * Must always be called in pairs to save and restore v:exception! Does not 7958 * take care of memory allocations. 7959 */ 7960 char_u * 7961 v_exception(oldval) 7962 char_u *oldval; 7963 { 7964 if (oldval == NULL) 7965 return vimvars[VV_EXCEPTION].val; 7966 7967 vimvars[VV_EXCEPTION].val = oldval; 7968 return NULL; 7969 } 7970 7971 /* 7972 * Get or set v:throwpoint. If "oldval" == NULL, return the current value. 7973 * Otherwise, restore the value to "oldval" and return NULL. 7974 * Must always be called in pairs to save and restore v:throwpoint! Does not 7975 * take care of memory allocations. 7976 */ 7977 char_u * 7978 v_throwpoint(oldval) 7979 char_u *oldval; 7980 { 7981 if (oldval == NULL) 7982 return vimvars[VV_THROWPOINT].val; 7983 7984 vimvars[VV_THROWPOINT].val = oldval; 7985 return NULL; 7986 } 7987 7988 #if defined(FEAT_AUTOCMD) || defined(PROTO) 7989 /* 7990 * Set v:cmdarg. 7991 * If "eap" != NULL, use "eap" to generate the value and return the old value. 7992 * If "oldarg" != NULL, restore the value to "oldarg" and return NULL. 7993 * Must always be called in pairs! 7994 */ 7995 char_u * 7996 set_cmdarg(eap, oldarg) 7997 exarg_T *eap; 7998 char_u *oldarg; 7999 { 8000 char_u *oldval; 8001 char_u *newval; 8002 unsigned len; 8003 8004 oldval = vimvars[VV_CMDARG].val; 8005 if (eap != NULL) 8006 { 8007 if (eap->force_bin == FORCE_BIN) 8008 len = 6; 8009 else if (eap->force_bin == FORCE_NOBIN) 8010 len = 8; 8011 else 8012 len = 0; 8013 if (eap->force_ff != 0) 8014 len += (unsigned)STRLEN(eap->cmd + eap->force_ff) + 6; 8015 # ifdef FEAT_MBYTE 8016 if (eap->force_enc != 0) 8017 len += (unsigned)STRLEN(eap->cmd + eap->force_enc) + 7; 8018 # endif 8019 8020 newval = alloc(len + 1); 8021 if (newval == NULL) 8022 return NULL; 8023 8024 if (eap->force_bin == FORCE_BIN) 8025 sprintf((char *)newval, " ++bin"); 8026 else if (eap->force_bin == FORCE_NOBIN) 8027 sprintf((char *)newval, " ++nobin"); 8028 else 8029 *newval = NUL; 8030 if (eap->force_ff != 0) 8031 sprintf((char *)newval + STRLEN(newval), " ++ff=%s", 8032 eap->cmd + eap->force_ff); 8033 # ifdef FEAT_MBYTE 8034 if (eap->force_enc != 0) 8035 sprintf((char *)newval + STRLEN(newval), " ++enc=%s", 8036 eap->cmd + eap->force_enc); 8037 # endif 8038 vimvars[VV_CMDARG].val = newval; 8039 return oldval; 8040 } 8041 8042 vim_free(oldval); 8043 vimvars[VV_CMDARG].val = oldarg; 8044 return NULL; 8045 } 8046 #endif 8047 8048 /* 8049 * Get the value of internal variable "name". 8050 * Return OK or FAIL. 8051 */ 8052 static int 8053 get_var_var(name, len, retvar) 8054 char_u *name; 8055 int len; /* length of "name" */ 8056 VAR retvar; /* NULL when only checking existence */ 8057 { 8058 int ret = OK; 8059 int type = VAR_UNKNOWN; 8060 long number = 1; 8061 char_u *string = NULL; 8062 VAR v; 8063 int cc; 8064 int i; 8065 8066 /* truncate the name, so that we can use strcmp() */ 8067 cc = name[len]; 8068 name[len] = NUL; 8069 8070 /* 8071 * Check for "b:changedtick". 8072 */ 8073 if (STRCMP(name, "b:changedtick") == 0) 8074 { 8075 type = VAR_NUMBER; 8076 number = curbuf->b_changedtick; 8077 } 8078 8079 /* 8080 * Check for built-in v: variables. 8081 */ 8082 else if ((i = find_vim_var(name, len)) >= 0) 8083 { 8084 type = vimvars[i].type; 8085 number = (long)vimvars[i].val; 8086 string = vimvars[i].val; 8087 } 8088 8089 /* 8090 * Check for user-defined variables. 8091 */ 8092 else 8093 { 8094 v = find_var(name, FALSE); 8095 if (v != NULL) 8096 { 8097 type = v->var_type; 8098 number = v->var_val.var_number; 8099 string = v->var_val.var_string; 8100 } 8101 } 8102 8103 if (type == VAR_UNKNOWN) 8104 { 8105 if (retvar != NULL) 8106 EMSG2(_("E121: Undefined variable: %s"), name); 8107 ret = FAIL; 8108 } 8109 else if (retvar != NULL) 8110 { 8111 retvar->var_type = type; 8112 if (type == VAR_NUMBER) 8113 retvar->var_val.var_number = number; 8114 else if (type == VAR_STRING) 8115 { 8116 if (string != NULL) 8117 string = vim_strsave(string); 8118 retvar->var_val.var_string = string; 8119 } 8120 } 8121 8122 name[len] = cc; 8123 8124 return ret; 8125 } 8126 8127 /* 8128 * Allocate memory for a variable, and make it emtpy (0 or NULL value). 8129 */ 8130 static VAR 8131 alloc_var() 8132 { 8133 return (VAR)alloc_clear((unsigned)sizeof(var)); 8134 } 8135 8136 /* 8137 * Allocate memory for a variable, and assign a string to it. 8138 * The string "s" must have been allocated, it is consumed. 8139 * Return NULL for out of memory, the variable otherwise. 8140 */ 8141 static VAR 8142 alloc_string_var(s) 8143 char_u *s; 8144 { 8145 VAR retvar; 8146 8147 retvar = alloc_var(); 8148 if (retvar != NULL) 8149 { 8150 retvar->var_type = VAR_STRING; 8151 retvar->var_val.var_string = s; 8152 } 8153 else 8154 vim_free(s); 8155 return retvar; 8156 } 8157 8158 /* 8159 * Free the memory for a variable. 8160 */ 8161 static void 8162 free_var(varp) 8163 VAR varp; 8164 { 8165 if (varp != NULL) 8166 { 8167 if (varp->var_type == VAR_STRING) 8168 vim_free(varp->var_val.var_string); 8169 vim_free(varp->var_name); 8170 vim_free(varp); 8171 } 8172 } 8173 8174 /* 8175 * Free the memory for a variable value and set the value to NULL or 0. 8176 */ 8177 static void 8178 clear_var(varp) 8179 VAR varp; 8180 { 8181 if (varp != NULL) 8182 { 8183 if (varp->var_type == VAR_STRING) 8184 { 8185 vim_free(varp->var_val.var_string); 8186 varp->var_val.var_string = NULL; 8187 } 8188 else 8189 varp->var_val.var_number = 0; 8190 } 8191 } 8192 8193 /* 8194 * Get the number value of a variable. 8195 * If it is a String variable, uses vim_str2nr(). 8196 */ 8197 static long 8198 get_var_number(varp) 8199 VAR varp; 8200 { 8201 long n; 8202 8203 if (varp->var_type == VAR_NUMBER) 8204 return (long)(varp->var_val.var_number); 8205 else if (varp->var_type == VAR_UNKNOWN || varp->var_val.var_string == NULL) 8206 return 0L; 8207 else 8208 { 8209 vim_str2nr(varp->var_val.var_string, NULL, NULL, TRUE, TRUE, &n, NULL); 8210 return n; 8211 } 8212 } 8213 8214 /* 8215 * Get the lnum from the first argument. Also accepts ".", "$", etc. 8216 */ 8217 static linenr_T 8218 get_var_lnum(argvars) 8219 VAR argvars; 8220 { 8221 var retvar; 8222 linenr_T lnum; 8223 8224 lnum = get_var_number(&argvars[0]); 8225 if (lnum == 0) /* no valid number, try using line() */ 8226 { 8227 retvar.var_type = VAR_NUMBER; 8228 f_line(argvars, &retvar); 8229 lnum = retvar.var_val.var_number; 8230 clear_var(&retvar); 8231 } 8232 return lnum; 8233 } 8234 8235 /* 8236 * Get the string value of a variable. 8237 * If it is a Number variable, the number is converted into a string. 8238 * get_var_string() uses a single, static buffer. YOU CAN ONLY USE IT ONCE! 8239 * get_var_string_buf() uses a given buffer. 8240 * If the String variable has never been set, return an empty string. 8241 * Never returns NULL; 8242 */ 8243 static char_u * 8244 get_var_string(varp) 8245 VAR varp; 8246 { 8247 static char_u mybuf[NUMBUFLEN]; 8248 8249 return get_var_string_buf(varp, mybuf); 8250 } 8251 8252 static char_u * 8253 get_var_string_buf(varp, buf) 8254 VAR varp; 8255 char_u *buf; 8256 { 8257 if (varp->var_type == VAR_NUMBER) 8258 { 8259 sprintf((char *)buf, "%ld", (long)varp->var_val.var_number); 8260 return buf; 8261 } 8262 else if (varp->var_val.var_string == NULL) 8263 return (char_u *)""; 8264 else 8265 return varp->var_val.var_string; 8266 } 8267 8268 /* 8269 * Find variable "name" in the list of variables. 8270 * Return a pointer to it if found, NULL if not found. 8271 */ 8272 static VAR 8273 find_var(name, writing) 8274 char_u *name; 8275 int writing; 8276 { 8277 int i; 8278 char_u *varname; 8279 garray_T *gap; 8280 8281 /* Check for function arguments "a:" */ 8282 if (name[0] == 'a' && name[1] == ':') 8283 { 8284 if (writing) 8285 { 8286 EMSG2(_(e_readonlyvar), name); 8287 return NULL; 8288 } 8289 name += 2; 8290 if (current_funccal == NULL) 8291 return NULL; 8292 if (VIM_ISDIGIT(*name)) 8293 { 8294 i = atol((char *)name); 8295 if (i == 0) /* a:0 */ 8296 return ¤t_funccal->a0_var; 8297 i += current_funccal->func->args.ga_len; 8298 if (i > current_funccal->argcount) /* a:999 */ 8299 return NULL; 8300 return &(current_funccal->argvars[i - 1]); /* a:1, a:2, etc. */ 8301 } 8302 if (STRCMP(name, "firstline") == 0) 8303 return &(current_funccal->firstline); 8304 if (STRCMP(name, "lastline") == 0) 8305 return &(current_funccal->lastline); 8306 for (i = 0; i < current_funccal->func->args.ga_len; ++i) 8307 if (STRCMP(name, ((char_u **) 8308 (current_funccal->func->args.ga_data))[i]) == 0) 8309 return &(current_funccal->argvars[i]); /* a:name */ 8310 return NULL; 8311 } 8312 8313 gap = find_var_ga(name, &varname); 8314 if (gap == NULL) 8315 return NULL; 8316 return find_var_in_ga(gap, varname); 8317 } 8318 8319 static VAR 8320 find_var_in_ga(gap, varname) 8321 garray_T *gap; 8322 char_u *varname; 8323 { 8324 int i; 8325 8326 for (i = gap->ga_len; --i >= 0; ) 8327 if (VAR_GAP_ENTRY(i, gap).var_name != NULL 8328 && STRCMP(VAR_GAP_ENTRY(i, gap).var_name, varname) == 0) 8329 break; 8330 if (i < 0) 8331 return NULL; 8332 return &VAR_GAP_ENTRY(i, gap); 8333 } 8334 8335 /* 8336 * Find the growarray and start of name without ':' for a variable name. 8337 */ 8338 static garray_T * 8339 find_var_ga(name, varname) 8340 char_u *name; 8341 char_u **varname; 8342 { 8343 if (name[1] != ':') 8344 { 8345 /* If not "x:name" there must not be any ":" in the name. */ 8346 if (vim_strchr(name, ':') != NULL) 8347 return NULL; 8348 *varname = name; 8349 if (current_funccal == NULL) 8350 return &variables; /* global variable */ 8351 return ¤t_funccal->l_vars; /* local function variable */ 8352 } 8353 *varname = name + 2; 8354 if (*name == 'b') /* buffer variable */ 8355 return &curbuf->b_vars; 8356 if (*name == 'w') /* window variable */ 8357 return &curwin->w_vars; 8358 if (*name == 'g') /* global variable */ 8359 return &variables; 8360 if (*name == 'l' && current_funccal != NULL)/* local function variable */ 8361 return ¤t_funccal->l_vars; 8362 if (*name == 's' /* script variable */ 8363 && current_SID > 0 && current_SID <= ga_scripts.ga_len) 8364 return &SCRIPT_VARS(current_SID); 8365 return NULL; 8366 } 8367 8368 /* 8369 * Get the string value of a (global/local) variable. 8370 * Returns NULL when it doesn't exist. 8371 */ 8372 char_u * 8373 get_var_value(name) 8374 char_u *name; 8375 { 8376 VAR v; 8377 8378 v = find_var(name, FALSE); 8379 if (v == NULL) 8380 return NULL; 8381 return get_var_string(v); 8382 } 8383 8384 /* 8385 * Allocate a new growarry for a sourced script. It will be used while 8386 * sourcing this script and when executing functions defined in the script. 8387 */ 8388 void 8389 new_script_vars(id) 8390 scid_T id; 8391 { 8392 if (ga_grow(&ga_scripts, (int)(id - ga_scripts.ga_len)) == OK) 8393 { 8394 while (ga_scripts.ga_len < id) 8395 { 8396 var_init(&SCRIPT_VARS(ga_scripts.ga_len + 1)); 8397 ++ga_scripts.ga_len; 8398 --ga_scripts.ga_room; 8399 } 8400 } 8401 } 8402 8403 /* 8404 * Initialize internal variables for use. 8405 */ 8406 void 8407 var_init(gap) 8408 garray_T *gap; 8409 { 8410 ga_init2(gap, (int)sizeof(var), 4); 8411 } 8412 8413 /* 8414 * Clean up a list of internal variables. 8415 */ 8416 void 8417 var_clear(gap) 8418 garray_T *gap; 8419 { 8420 int i; 8421 8422 for (i = gap->ga_len; --i >= 0; ) 8423 var_free_one(&VAR_GAP_ENTRY(i, gap)); 8424 ga_clear(gap); 8425 } 8426 8427 static void 8428 var_free_one(v) 8429 VAR v; 8430 { 8431 vim_free(v->var_name); 8432 v->var_name = NULL; 8433 if (v->var_type == VAR_STRING) 8434 vim_free(v->var_val.var_string); 8435 v->var_val.var_string = NULL; 8436 } 8437 8438 /* 8439 * List the value of one internal variable. 8440 */ 8441 static void 8442 list_one_var(v, prefix) 8443 VAR v; 8444 char_u *prefix; 8445 { 8446 list_one_var_a(prefix, v->var_name, v->var_type, get_var_string(v)); 8447 } 8448 8449 /* 8450 * List the value of one "v:" variable. 8451 */ 8452 static void 8453 list_vim_var(i) 8454 int i; /* index in vimvars[] */ 8455 { 8456 char_u *p; 8457 char_u numbuf[NUMBUFLEN]; 8458 8459 if (vimvars[i].type == VAR_NUMBER) 8460 { 8461 p = numbuf; 8462 sprintf((char *)p, "%ld", (long)vimvars[i].val); 8463 } 8464 else if (vimvars[i].val == NULL) 8465 p = (char_u *)""; 8466 else 8467 p = vimvars[i].val; 8468 list_one_var_a((char_u *)"v:", (char_u *)vimvars[i].name, 8469 vimvars[i].type, p); 8470 } 8471 8472 static void 8473 list_one_var_a(prefix, name, type, string) 8474 char_u *prefix; 8475 char_u *name; 8476 int type; 8477 char_u *string; 8478 { 8479 msg_attr(prefix, 0); /* don't use msg(), it overwrites "v:statusmsg" */ 8480 if (name != NULL) /* "a:" vars don't have a name stored */ 8481 msg_puts(name); 8482 msg_putchar(' '); 8483 msg_advance(22); 8484 if (type == VAR_NUMBER) 8485 msg_putchar('#'); 8486 else 8487 msg_putchar(' '); 8488 msg_outtrans(string); 8489 } 8490 8491 /* 8492 * Set variable "name" to value in "varp". 8493 * If the variable already exists, the value is updated. 8494 * Otherwise the variable is created. 8495 */ 8496 static void 8497 set_var(name, varp) 8498 char_u *name; 8499 VAR varp; 8500 { 8501 int i; 8502 VAR v; 8503 char_u *varname; 8504 garray_T *gap; 8505 8506 /* 8507 * Handle setting internal v: variables. 8508 */ 8509 i = find_vim_var(name, (int)STRLEN(name)); 8510 if (i >= 0) 8511 { 8512 if (vimvars[i].flags & VV_RO) 8513 EMSG2(_(e_readonlyvar), name); 8514 else 8515 { 8516 if (vimvars[i].type == VAR_STRING) 8517 { 8518 vim_free(vimvars[i].val); 8519 vimvars[i].val = vim_strsave(get_var_string(varp)); 8520 } 8521 else 8522 vimvars[i].val = (char_u *)(long)varp->var_val.var_number; 8523 } 8524 return; 8525 } 8526 8527 v = find_var(name, TRUE); 8528 if (v != NULL) /* existing variable, only need to free string */ 8529 { 8530 if (v->var_type == VAR_STRING) 8531 vim_free(v->var_val.var_string); 8532 } 8533 else /* add a new variable */ 8534 { 8535 gap = find_var_ga(name, &varname); 8536 if (gap == NULL) /* illegal name */ 8537 { 8538 EMSG2(_("E461: Illegal variable name: %s"), name); 8539 return; 8540 } 8541 8542 /* Try to use an empty entry */ 8543 for (i = gap->ga_len; --i >= 0; ) 8544 if (VAR_GAP_ENTRY(i, gap).var_name == NULL) 8545 break; 8546 if (i < 0) /* need to allocate more room */ 8547 { 8548 if (ga_grow(gap, 1) == FAIL) 8549 return; 8550 i = gap->ga_len; 8551 } 8552 v = &VAR_GAP_ENTRY(i, gap); 8553 if ((v->var_name = vim_strsave(varname)) == NULL) 8554 return; 8555 if (i == gap->ga_len) 8556 { 8557 ++gap->ga_len; 8558 --gap->ga_room; 8559 } 8560 } 8561 copy_var(varp, v); 8562 } 8563 8564 static void 8565 copy_var(from, to) 8566 VAR from; 8567 VAR to; 8568 { 8569 to->var_type = from->var_type; 8570 if (from->var_type == VAR_STRING) 8571 to->var_val.var_string = vim_strsave(get_var_string(from)); 8572 else 8573 to->var_val.var_number = from->var_val.var_number; 8574 } 8575 8576 /* 8577 * ":echo expr1 ..." print each argument separated with a space, add a 8578 * newline at the end. 8579 * ":echon expr1 ..." print each argument plain. 8580 */ 8581 void 8582 ex_echo(eap) 8583 exarg_T *eap; 8584 { 8585 char_u *arg = eap->arg; 8586 var retvar; 8587 char_u *p; 8588 int needclr = TRUE; 8589 int atstart = TRUE; 8590 8591 if (eap->skip) 8592 ++emsg_skip; 8593 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) 8594 { 8595 p = arg; 8596 if (eval1(&arg, &retvar, !eap->skip) == FAIL) 8597 { 8598 /* 8599 * Report the invalid expression unless the expression evaluation 8600 * has been cancelled due to an aborting error, an interrupt, or an 8601 * exception. 8602 */ 8603 if (!aborting()) 8604 EMSG2(_(e_invexpr2), p); 8605 break; 8606 } 8607 if (!eap->skip) 8608 { 8609 if (atstart) 8610 { 8611 atstart = FALSE; 8612 /* Call msg_start() after eval1(), evaluating the expression 8613 * may cause a message to appear. */ 8614 if (eap->cmdidx == CMD_echo) 8615 msg_start(); 8616 } 8617 else if (eap->cmdidx == CMD_echo) 8618 msg_puts_attr((char_u *)" ", echo_attr); 8619 for (p = get_var_string(&retvar); *p != NUL && !got_int; ++p) 8620 if (*p == '\n' || *p == '\r' || *p == TAB) 8621 { 8622 if (*p != TAB && needclr) 8623 { 8624 /* remove any text still there from the command */ 8625 msg_clr_eos(); 8626 needclr = FALSE; 8627 } 8628 msg_putchar_attr(*p, echo_attr); 8629 } 8630 else 8631 { 8632 #ifdef FEAT_MBYTE 8633 if (has_mbyte) 8634 { 8635 int i = (*mb_ptr2len_check)(p); 8636 8637 (void)msg_outtrans_len_attr(p, i, echo_attr); 8638 p += i - 1; 8639 } 8640 else 8641 #endif 8642 (void)msg_outtrans_len_attr(p, 1, echo_attr); 8643 } 8644 } 8645 clear_var(&retvar); 8646 arg = skipwhite(arg); 8647 } 8648 eap->nextcmd = check_nextcmd(arg); 8649 8650 if (eap->skip) 8651 --emsg_skip; 8652 else 8653 { 8654 /* remove text that may still be there from the command */ 8655 if (needclr) 8656 msg_clr_eos(); 8657 if (eap->cmdidx == CMD_echo) 8658 msg_end(); 8659 } 8660 } 8661 8662 /* 8663 * ":echohl {name}". 8664 */ 8665 void 8666 ex_echohl(eap) 8667 exarg_T *eap; 8668 { 8669 int id; 8670 8671 id = syn_name2id(eap->arg); 8672 if (id == 0) 8673 echo_attr = 0; 8674 else 8675 echo_attr = syn_id2attr(id); 8676 } 8677 8678 /* 8679 * ":execute expr1 ..." execute the result of an expression. 8680 * ":echomsg expr1 ..." Print a message 8681 * ":echoerr expr1 ..." Print an error 8682 * Each gets spaces around each argument and a newline at the end for 8683 * echo commands 8684 */ 8685 void 8686 ex_execute(eap) 8687 exarg_T *eap; 8688 { 8689 char_u *arg = eap->arg; 8690 var retvar; 8691 int ret = OK; 8692 char_u *p; 8693 garray_T ga; 8694 int len; 8695 int save_did_emsg; 8696 8697 ga_init2(&ga, 1, 80); 8698 8699 if (eap->skip) 8700 ++emsg_skip; 8701 while (*arg != NUL && *arg != '|' && *arg != '\n') 8702 { 8703 p = arg; 8704 if (eval1(&arg, &retvar, !eap->skip) == FAIL) 8705 { 8706 /* 8707 * Report the invalid expression unless the expression evaluation 8708 * has been cancelled due to an aborting error, an interrupt, or an 8709 * exception. 8710 */ 8711 if (!aborting()) 8712 EMSG2(_(e_invexpr2), p); 8713 ret = FAIL; 8714 break; 8715 } 8716 8717 if (!eap->skip) 8718 { 8719 p = get_var_string(&retvar); 8720 len = (int)STRLEN(p); 8721 if (ga_grow(&ga, len + 2) == FAIL) 8722 { 8723 clear_var(&retvar); 8724 ret = FAIL; 8725 break; 8726 } 8727 if (ga.ga_len) 8728 { 8729 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 8730 --ga.ga_room; 8731 } 8732 STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p); 8733 ga.ga_room -= len; 8734 ga.ga_len += len; 8735 } 8736 8737 clear_var(&retvar); 8738 arg = skipwhite(arg); 8739 } 8740 8741 if (ret != FAIL && ga.ga_data != NULL) 8742 { 8743 if (eap->cmdidx == CMD_echomsg) 8744 MSG_ATTR(ga.ga_data, echo_attr); 8745 else if (eap->cmdidx == CMD_echoerr) 8746 { 8747 /* We don't want to abort following commands, restore did_emsg. */ 8748 save_did_emsg = did_emsg; 8749 EMSG((char_u *)ga.ga_data); 8750 if (!force_abort) 8751 did_emsg = save_did_emsg; 8752 } 8753 else if (eap->cmdidx == CMD_execute) 8754 do_cmdline((char_u *)ga.ga_data, 8755 eap->getline, eap->cookie, DOCMD_NOWAIT|DOCMD_VERBOSE); 8756 } 8757 8758 ga_clear(&ga); 8759 8760 if (eap->skip) 8761 --emsg_skip; 8762 8763 eap->nextcmd = check_nextcmd(arg); 8764 } 8765 8766 /* 8767 * Skip over the name of an option: "&option", "&g:option" or "&l:option". 8768 * "arg" points to the "&" or '+' when called, to "option" when returning. 8769 * Returns NULL when no option name found. Otherwise pointer to the char 8770 * after the option name. 8771 */ 8772 static char_u * 8773 find_option_end(arg, opt_flags) 8774 char_u **arg; 8775 int *opt_flags; 8776 { 8777 char_u *p = *arg; 8778 8779 ++p; 8780 if (*p == 'g' && p[1] == ':') 8781 { 8782 *opt_flags = OPT_GLOBAL; 8783 p += 2; 8784 } 8785 else if (*p == 'l' && p[1] == ':') 8786 { 8787 *opt_flags = OPT_LOCAL; 8788 p += 2; 8789 } 8790 else 8791 *opt_flags = 0; 8792 8793 if (!ASCII_ISALPHA(*p)) 8794 return NULL; 8795 *arg = p; 8796 8797 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) 8798 p += 4; /* termcap option */ 8799 else 8800 while (ASCII_ISALPHA(*p)) 8801 ++p; 8802 return p; 8803 } 8804 8805 /* 8806 * ":function" 8807 */ 8808 void 8809 ex_function(eap) 8810 exarg_T *eap; 8811 { 8812 char_u *theline; 8813 int j; 8814 int c; 8815 #ifdef FEAT_MAGIC_BRACES 8816 int saved_did_emsg; 8817 #endif 8818 char_u *name = NULL; 8819 char_u *p; 8820 char_u *arg; 8821 garray_T newargs; 8822 garray_T newlines; 8823 int varargs = FALSE; 8824 int mustend = FALSE; 8825 int flags = 0; 8826 ufunc_T *fp; 8827 int indent; 8828 int nesting; 8829 char_u *skip_until = NULL; 8830 static char_u e_funcexts[] = N_("E122: Function %s already exists, add ! to replace it"); 8831 8832 /* 8833 * ":function" without argument: list functions. 8834 */ 8835 if (ends_excmd(*eap->arg)) 8836 { 8837 if (!eap->skip) 8838 for (fp = firstfunc; fp != NULL && !got_int; fp = fp->next) 8839 list_func_head(fp, FALSE); 8840 eap->nextcmd = check_nextcmd(eap->arg); 8841 return; 8842 } 8843 8844 p = eap->arg; 8845 name = trans_function_name(&p, eap->skip, FALSE); 8846 if (name == NULL && !eap->skip) 8847 { 8848 /* 8849 * Return on an invalid expression in braces, unless the expression 8850 * evaluation has been cancelled due to an aborting error, an 8851 * interrupt, or an exception. 8852 */ 8853 if (!aborting()) 8854 return; 8855 else 8856 eap->skip = TRUE; 8857 } 8858 #ifdef FEAT_MAGIC_BRACES 8859 /* An error in a function call during evaluation of an expression in magic 8860 * braces should not cause the function not to be defined. */ 8861 saved_did_emsg = did_emsg; 8862 did_emsg = FALSE; 8863 #endif 8864 8865 /* 8866 * ":function func" with only function name: list function. 8867 */ 8868 if (vim_strchr(p, '(') == NULL) 8869 { 8870 if (!ends_excmd(*skipwhite(p))) 8871 { 8872 EMSG(_(e_trailing)); 8873 goto erret_name; 8874 } 8875 eap->nextcmd = check_nextcmd(p); 8876 if (eap->nextcmd != NULL) 8877 *p = NUL; 8878 if (!eap->skip && !got_int) 8879 { 8880 fp = find_func(name); 8881 if (fp != NULL) 8882 { 8883 list_func_head(fp, TRUE); 8884 for (j = 0; j < fp->lines.ga_len && !got_int; ++j) 8885 { 8886 msg_putchar('\n'); 8887 msg_outnum((long)(j + 1)); 8888 if (j < 9) 8889 msg_putchar(' '); 8890 if (j < 99) 8891 msg_putchar(' '); 8892 msg_prt_line(FUNCLINE(fp, j)); 8893 out_flush(); /* show a line at a time */ 8894 ui_breakcheck(); 8895 } 8896 if (!got_int) 8897 { 8898 msg_putchar('\n'); 8899 msg_puts((char_u *)" endfunction"); 8900 } 8901 } 8902 else 8903 EMSG2(_("E123: Undefined function: %s"), eap->arg); 8904 } 8905 goto erret_name; 8906 } 8907 8908 /* 8909 * ":function name(arg1, arg2)" Define function. 8910 */ 8911 p = skipwhite(p); 8912 if (*p != '(') 8913 { 8914 if (!eap->skip) 8915 { 8916 EMSG2(_("E124: Missing '(': %s"), eap->arg); 8917 goto erret_name; 8918 } 8919 /* attempt to continue by skipping some text */ 8920 if (vim_strchr(p, '(') != NULL) 8921 p = vim_strchr(p, '('); 8922 } 8923 p = skipwhite(p + 1); 8924 8925 ga_init2(&newargs, (int)sizeof(char_u *), 3); 8926 ga_init2(&newlines, (int)sizeof(char_u *), 3); 8927 8928 /* 8929 * Isolate the arguments: "arg1, arg2, ...)" 8930 */ 8931 while (*p != ')') 8932 { 8933 if (p[0] == '.' && p[1] == '.' && p[2] == '.') 8934 { 8935 varargs = TRUE; 8936 p += 3; 8937 mustend = TRUE; 8938 } 8939 else 8940 { 8941 arg = p; 8942 while (ASCII_ISALNUM(*p) || *p == '_') 8943 ++p; 8944 if (arg == p || isdigit(*arg) 8945 || (p - arg == 9 && STRNCMP(arg, "firstline", 9) == 0) 8946 || (p - arg == 8 && STRNCMP(arg, "lastline", 8) == 0)) 8947 { 8948 if (!eap->skip) 8949 EMSG2(_("E125: Illegal argument: %s"), arg); 8950 break; 8951 } 8952 if (ga_grow(&newargs, 1) == FAIL) 8953 goto erret; 8954 c = *p; 8955 *p = NUL; 8956 arg = vim_strsave(arg); 8957 if (arg == NULL) 8958 goto erret; 8959 ((char_u **)(newargs.ga_data))[newargs.ga_len] = arg; 8960 *p = c; 8961 newargs.ga_len++; 8962 newargs.ga_room--; 8963 if (*p == ',') 8964 ++p; 8965 else 8966 mustend = TRUE; 8967 } 8968 p = skipwhite(p); 8969 if (mustend && *p != ')') 8970 { 8971 if (!eap->skip) 8972 EMSG2(_(e_invarg2), eap->arg); 8973 break; 8974 } 8975 } 8976 ++p; /* skip the ')' */ 8977 8978 /* find extra arguments "range" and "abort" */ 8979 for (;;) 8980 { 8981 p = skipwhite(p); 8982 if (STRNCMP(p, "range", 5) == 0) 8983 { 8984 flags |= FC_RANGE; 8985 p += 5; 8986 } 8987 else if (STRNCMP(p, "abort", 5) == 0) 8988 { 8989 flags |= FC_ABORT; 8990 p += 5; 8991 } 8992 else 8993 break; 8994 } 8995 8996 if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) 8997 EMSG(_(e_trailing)); 8998 8999 /* 9000 * Read the body of the function, until ":endfunction" is found. 9001 */ 9002 if (KeyTyped) 9003 { 9004 /* Check if the function already exists, don't let the user type the 9005 * whole function before telling him it doesn't work! For a script we 9006 * need to skip the body to be able to find what follows. */ 9007 if (!eap->skip && !eap->forceit && find_func(name) != NULL) 9008 EMSG2(_(e_funcexts), name); 9009 9010 msg_putchar('\n'); /* don't overwrite the function name */ 9011 cmdline_row = msg_row; 9012 } 9013 9014 indent = 2; 9015 nesting = 0; 9016 for (;;) 9017 { 9018 msg_scroll = TRUE; 9019 need_wait_return = FALSE; 9020 if (eap->getline == NULL) 9021 theline = getcmdline(':', 0L, indent); 9022 else 9023 theline = eap->getline(':', eap->cookie, indent); 9024 if (KeyTyped) 9025 lines_left = Rows - 1; 9026 if (theline == NULL) 9027 { 9028 EMSG(_("E126: Missing :endfunction")); 9029 goto erret; 9030 } 9031 9032 if (skip_until != NULL) 9033 { 9034 /* between ":append" and "." and between ":python <<EOF" and "EOF" 9035 * don't check for ":endfunc". */ 9036 if (STRCMP(theline, skip_until) == 0) 9037 { 9038 vim_free(skip_until); 9039 skip_until = NULL; 9040 } 9041 } 9042 else 9043 { 9044 /* skip ':' and blanks*/ 9045 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) 9046 ; 9047 9048 /* Check for "endfunction" (should be more strict...). */ 9049 if (STRNCMP(p, "endf", 4) == 0 && nesting-- == 0) 9050 { 9051 vim_free(theline); 9052 break; 9053 } 9054 9055 /* Increase indent inside "if", "while", and "try", decrease 9056 * at "end". */ 9057 if (indent > 2 && STRNCMP(p, "end", 3) == 0) 9058 indent -= 2; 9059 else if (STRNCMP(p, "if", 2) == 0 || STRNCMP(p, "wh", 2) == 0 9060 || STRNCMP(p, "try", 3) == 0) 9061 indent += 2; 9062 9063 /* Check for defining a function inside this function. */ 9064 if (STRNCMP(p, "fu", 2) == 0) 9065 { 9066 p = skipwhite(skiptowhite(p)); 9067 p += eval_fname_script(p); 9068 if (ASCII_ISALPHA(*p)) 9069 { 9070 vim_free(trans_function_name(&p, TRUE, FALSE)); 9071 if (*skipwhite(p) == '(') 9072 { 9073 ++nesting; 9074 indent += 2; 9075 } 9076 } 9077 } 9078 9079 /* Check for ":append" or ":insert". */ 9080 p = skip_range(p, NULL); 9081 if ((p[0] == 'a' && (!ASCII_ISALPHA(p[1]) || p[1] == 'p')) 9082 || (p[0] == 'i' 9083 && (!ASCII_ISALPHA(p[1]) || (p[1] == 'n' 9084 && (!ASCII_ISALPHA(p[2]) || (p[2] == 's')))))) 9085 skip_until = vim_strsave((char_u *)"."); 9086 9087 /* Check for ":python <<EOF", ":tcl <<EOF", etc. */ 9088 arg = skipwhite(skiptowhite(p)); 9089 if (arg[0] == '<' && arg[1] =='<' 9090 && ((p[0] == 'p' && p[1] == 'y' 9091 && (!ASCII_ISALPHA(p[2]) || p[2] == 't')) 9092 || (p[0] == 'p' && p[1] == 'e' 9093 && (!ASCII_ISALPHA(p[2]) || p[2] == 'r')) 9094 || (p[0] == 't' && p[1] == 'c' 9095 && (!ASCII_ISALPHA(p[2]) || p[2] == 'l')) 9096 || (p[0] == 'r' && p[1] == 'u' && p[2] == 'b' 9097 && (!ASCII_ISALPHA(p[3]) || p[3] == 'y')) 9098 )) 9099 { 9100 /* ":python <<" continues until a dot, like ":append" */ 9101 p = skipwhite(arg + 2); 9102 if (*p == NUL) 9103 skip_until = vim_strsave((char_u *)"."); 9104 else 9105 skip_until = vim_strsave(p); 9106 } 9107 } 9108 9109 /* Add the line to the function. */ 9110 if (ga_grow(&newlines, 1) == FAIL) 9111 goto erret; 9112 ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; 9113 newlines.ga_len++; 9114 newlines.ga_room--; 9115 } 9116 9117 /* Don't define the function when skipping commands or when an error was 9118 * detected. */ 9119 if (eap->skip || did_emsg) 9120 goto erret; 9121 9122 /* 9123 * If there are no errors, add the function 9124 */ 9125 fp = find_func(name); 9126 if (fp != NULL) 9127 { 9128 if (!eap->forceit) 9129 { 9130 EMSG2(_(e_funcexts), name); 9131 goto erret; 9132 } 9133 if (fp->calls) 9134 { 9135 EMSG2(_("E127: Cannot redefine function %s: It is in use"), name); 9136 goto erret; 9137 } 9138 /* redefine existing function */ 9139 ga_clear_strings(&(fp->args)); 9140 ga_clear_strings(&(fp->lines)); 9141 vim_free(name); 9142 } 9143 else 9144 { 9145 fp = (ufunc_T *)alloc((unsigned)sizeof(ufunc_T)); 9146 if (fp == NULL) 9147 goto erret; 9148 /* insert the new function in the function list */ 9149 fp->next = firstfunc; 9150 firstfunc = fp; 9151 fp->name = name; 9152 } 9153 fp->args = newargs; 9154 fp->lines = newlines; 9155 fp->varargs = varargs; 9156 fp->flags = flags; 9157 fp->calls = 0; 9158 fp->script_ID = current_SID; 9159 #ifdef FEAT_MAGIC_BRACES 9160 did_emsg |= saved_did_emsg; 9161 #endif 9162 vim_free(skip_until); 9163 return; 9164 9165 erret: 9166 vim_free(skip_until); 9167 ga_clear_strings(&newargs); 9168 ga_clear_strings(&newlines); 9169 erret_name: 9170 vim_free(name); 9171 #ifdef FEAT_MAGIC_BRACES 9172 did_emsg |= saved_did_emsg; 9173 #endif 9174 } 9175 9176 /* 9177 * Get a function name, translating "<SID>" and "<SNR>". 9178 * Returns the function name in allocated memory, or NULL for failure. 9179 * Advances "pp" to just after the function name (if no error). 9180 */ 9181 static char_u * 9182 trans_function_name(pp, skip, internal) 9183 char_u **pp; 9184 int skip; /* only find the end, don't evaluate */ 9185 int internal; /* TRUE if internal function name OK */ 9186 { 9187 char_u *name; 9188 char_u *start; 9189 char_u *end; 9190 int lead; 9191 char_u sid_buf[20]; 9192 char_u *temp_string = NULL; 9193 char_u *expr_start, *expr_end; 9194 int len; 9195 9196 /* A name starting with "<SID>" or "<SNR>" is local to a script. */ 9197 start = *pp; 9198 lead = eval_fname_script(start); 9199 if (lead > 0) 9200 start += lead; 9201 end = find_name_end(start, &expr_start, &expr_end); 9202 if (end == start) 9203 { 9204 if (!skip) 9205 EMSG(_("E129: Function name required")); 9206 return NULL; 9207 } 9208 #ifdef FEAT_MAGIC_BRACES 9209 if (expr_start != NULL && !skip) 9210 { 9211 /* expand magic curlies */ 9212 temp_string = make_expanded_name(start, expr_start, expr_end, end); 9213 if (temp_string == NULL) 9214 { 9215 /* 9216 * Report an invalid expression in braces, unless the expression 9217 * evaluation has been cancelled due to an aborting error, an 9218 * interrupt, or an exception. 9219 */ 9220 if (!aborting()) 9221 EMSG2(_(e_invarg2), start); 9222 else 9223 *pp = end; 9224 return NULL; 9225 } 9226 start = temp_string; 9227 len = (int)STRLEN(temp_string); 9228 } 9229 else 9230 #endif 9231 len = (int)(end - start); 9232 9233 /* 9234 * Copy the function name to allocated memory. 9235 * Accept <SID>name() inside a script, translate into <SNR>123_name(). 9236 * Accept <SNR>123_name() outside a script. 9237 */ 9238 if (skip) 9239 lead = 0; /* do nothing */ 9240 else if (lead > 0) 9241 { 9242 lead = 3; 9243 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 9244 { 9245 if (current_SID <= 0) 9246 { 9247 EMSG(_(e_usingsid)); 9248 return NULL; 9249 } 9250 sprintf((char *)sid_buf, "%ld_", (long)current_SID); 9251 lead += (int)STRLEN(sid_buf); 9252 } 9253 } 9254 else if (!internal && !ASCII_ISUPPER(*start)) 9255 { 9256 EMSG2(_("E128: Function name must start with a capital: %s"), start); 9257 return NULL; 9258 } 9259 name = alloc((unsigned)(len + lead + 1)); 9260 if (name != NULL) 9261 { 9262 if (lead > 0) 9263 { 9264 name[0] = K_SPECIAL; 9265 name[1] = KS_EXTRA; 9266 name[2] = (int)KE_SNR; 9267 if (eval_fname_sid(*pp)) /* If it's "<SID>" */ 9268 STRCPY(name + 3, sid_buf); 9269 } 9270 mch_memmove(name + lead, start, (size_t)len); 9271 name[len + lead] = NUL; 9272 } 9273 *pp = end; 9274 9275 vim_free(temp_string); 9276 return name; 9277 } 9278 9279 /* 9280 * Return 5 if "p" starts with "<SID>" or "<SNR>" (ignoring case). 9281 * Return 2 if "p" starts with "s:". 9282 * Return 0 otherwise. 9283 */ 9284 static int 9285 eval_fname_script(p) 9286 char_u *p; 9287 { 9288 if (p[0] == '<' && (STRNICMP(p + 1, "SID>", 4) == 0 9289 || STRNICMP(p + 1, "SNR>", 4) == 0)) 9290 return 5; 9291 if (p[0] == 's' && p[1] == ':') 9292 return 2; 9293 return 0; 9294 } 9295 9296 /* 9297 * Return TRUE if "p" starts with "<SID>" or "s:". 9298 * Only works if eval_fname_script() returned non-zero for "p"! 9299 */ 9300 static int 9301 eval_fname_sid(p) 9302 char_u *p; 9303 { 9304 return (*p == 's' || TOUPPER_ASC(p[2]) == 'I'); 9305 } 9306 9307 /* 9308 * List the head of the function: "name(arg1, arg2)". 9309 */ 9310 static void 9311 list_func_head(fp, indent) 9312 ufunc_T *fp; 9313 int indent; 9314 { 9315 int j; 9316 9317 msg_start(); 9318 if (indent) 9319 MSG_PUTS(" "); 9320 MSG_PUTS("function "); 9321 if (fp->name[0] == K_SPECIAL) 9322 { 9323 MSG_PUTS_ATTR("<SNR>", hl_attr(HLF_8)); 9324 msg_puts(fp->name + 3); 9325 } 9326 else 9327 msg_puts(fp->name); 9328 msg_putchar('('); 9329 for (j = 0; j < fp->args.ga_len; ++j) 9330 { 9331 if (j) 9332 MSG_PUTS(", "); 9333 msg_puts(FUNCARG(fp, j)); 9334 } 9335 if (fp->varargs) 9336 { 9337 if (j) 9338 MSG_PUTS(", "); 9339 MSG_PUTS("..."); 9340 } 9341 msg_putchar(')'); 9342 } 9343 9344 /* 9345 * Find a function by name, return pointer to it in ufuncs. 9346 * Return NULL for unknown function. 9347 */ 9348 static ufunc_T * 9349 find_func(name) 9350 char_u *name; 9351 { 9352 ufunc_T *fp; 9353 9354 for (fp = firstfunc; fp != NULL; fp = fp->next) 9355 if (STRCMP(name, fp->name) == 0) 9356 break; 9357 return fp; 9358 } 9359 9360 #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 9361 9362 /* 9363 * Function given to ExpandGeneric() to obtain the list of user defined 9364 * function names. 9365 */ 9366 char_u * 9367 get_user_func_name(xp, idx) 9368 expand_T *xp; 9369 int idx; 9370 { 9371 static ufunc_T *fp = NULL; 9372 9373 if (idx == 0) 9374 fp = firstfunc; 9375 if (fp != NULL) 9376 { 9377 if (STRLEN(fp->name) + 4 >= IOSIZE) 9378 return fp->name; /* prevents overflow */ 9379 9380 cat_func_name(IObuff, fp); 9381 if (xp->xp_context != EXPAND_USER_FUNC) 9382 { 9383 STRCAT(IObuff, "("); 9384 if (!fp->varargs && fp->args.ga_len == 0) 9385 STRCAT(IObuff, ")"); 9386 } 9387 9388 fp = fp->next; 9389 return IObuff; 9390 } 9391 return NULL; 9392 } 9393 9394 #endif /* FEAT_CMDL_COMPL */ 9395 9396 /* 9397 * Copy the function name of "fp" to buffer "buf". 9398 * "buf" must be able to hold the function name plus three bytes. 9399 * Takes care of script-local function names. 9400 */ 9401 static void 9402 cat_func_name(buf, fp) 9403 char_u *buf; 9404 ufunc_T *fp; 9405 { 9406 if (fp->name[0] == K_SPECIAL) 9407 { 9408 STRCPY(buf, "<SNR>"); 9409 STRCAT(buf, fp->name + 3); 9410 } 9411 else 9412 STRCPY(buf, fp->name); 9413 } 9414 9415 /* 9416 * ":delfunction {name}" 9417 */ 9418 void 9419 ex_delfunction(eap) 9420 exarg_T *eap; 9421 { 9422 ufunc_T *fp = NULL, *pfp; 9423 char_u *p; 9424 char_u *name; 9425 9426 p = eap->arg; 9427 name = trans_function_name(&p, eap->skip, FALSE); 9428 if (name == NULL) 9429 return; 9430 if (!ends_excmd(*skipwhite(p))) 9431 { 9432 vim_free(name); 9433 EMSG(_(e_trailing)); 9434 return; 9435 } 9436 eap->nextcmd = check_nextcmd(p); 9437 if (eap->nextcmd != NULL) 9438 *p = NUL; 9439 9440 if (!eap->skip) 9441 fp = find_func(name); 9442 vim_free(name); 9443 9444 if (!eap->skip) 9445 { 9446 if (fp == NULL) 9447 { 9448 EMSG2(_("E130: Undefined function: %s"), eap->arg); 9449 return; 9450 } 9451 if (fp->calls) 9452 { 9453 EMSG2(_("E131: Cannot delete function %s: It is in use"), eap->arg); 9454 return; 9455 } 9456 9457 /* clear this function */ 9458 vim_free(fp->name); 9459 ga_clear_strings(&(fp->args)); 9460 ga_clear_strings(&(fp->lines)); 9461 9462 /* remove the function from the function list */ 9463 if (firstfunc == fp) 9464 firstfunc = fp->next; 9465 else 9466 { 9467 for (pfp = firstfunc; pfp != NULL; pfp = pfp->next) 9468 if (pfp->next == fp) 9469 { 9470 pfp->next = fp->next; 9471 break; 9472 } 9473 } 9474 vim_free(fp); 9475 } 9476 } 9477 9478 /* 9479 * Call a user function. 9480 */ 9481 static void 9482 call_user_func(fp, argcount, argvars, retvar, firstline, lastline) 9483 ufunc_T *fp; /* pointer to function */ 9484 int argcount; /* nr of args */ 9485 VAR argvars; /* arguments */ 9486 VAR retvar; /* return value */ 9487 linenr_T firstline; /* first line of range */ 9488 linenr_T lastline; /* last line of range */ 9489 { 9490 char_u *save_sourcing_name; 9491 linenr_T save_sourcing_lnum; 9492 scid_T save_current_SID; 9493 struct funccall fc; 9494 struct funccall *save_fcp = current_funccal; 9495 int save_did_emsg; 9496 static int depth = 0; 9497 9498 /* If depth of calling is getting too high, don't execute the function */ 9499 if (depth >= p_mfd) 9500 { 9501 EMSG(_("E132: Function call depth is higher than 'maxfuncdepth'")); 9502 retvar->var_type = VAR_NUMBER; 9503 retvar->var_val.var_number = -1; 9504 return; 9505 } 9506 ++depth; 9507 9508 line_breakcheck(); /* check for CTRL-C hit */ 9509 9510 /* set local variables */ 9511 var_init(&fc.l_vars); 9512 fc.func = fp; 9513 fc.argcount = argcount; 9514 fc.argvars = argvars; 9515 fc.retvar = retvar; 9516 retvar->var_val.var_number = 0; 9517 fc.linenr = 0; 9518 fc.returned = FALSE; 9519 fc.level = ex_nesting_level; 9520 fc.a0_var.var_type = VAR_NUMBER; 9521 fc.a0_var.var_val.var_number = argcount - fp->args.ga_len; 9522 fc.a0_var.var_name = NULL; 9523 current_funccal = &fc; 9524 fc.firstline.var_type = VAR_NUMBER; 9525 fc.firstline.var_val.var_number = firstline; 9526 fc.firstline.var_name = NULL; 9527 fc.lastline.var_type = VAR_NUMBER; 9528 fc.lastline.var_val.var_number = lastline; 9529 fc.lastline.var_name = NULL; 9530 /* Check if this function has a breakpoint. */ 9531 fc.breakpoint = dbg_find_breakpoint(FALSE, fp->name, (linenr_T)0); 9532 fc.dbg_tick = debug_tick; 9533 9534 /* Don't redraw while executing the function. */ 9535 ++RedrawingDisabled; 9536 save_sourcing_name = sourcing_name; 9537 save_sourcing_lnum = sourcing_lnum; 9538 sourcing_lnum = 1; 9539 sourcing_name = alloc((unsigned)((save_sourcing_name == NULL ? 0 9540 : STRLEN(save_sourcing_name)) + STRLEN(fp->name) + 13)); 9541 if (sourcing_name != NULL) 9542 { 9543 if (save_sourcing_name != NULL 9544 && STRNCMP(save_sourcing_name, "function ", 9) == 0) 9545 sprintf((char *)sourcing_name, "%s..", save_sourcing_name); 9546 else 9547 STRCPY(sourcing_name, "function "); 9548 cat_func_name(sourcing_name + STRLEN(sourcing_name), fp); 9549 9550 if (p_verbose >= 12) 9551 { 9552 ++no_wait_return; 9553 msg_scroll = TRUE; /* always scroll up, don't overwrite */ 9554 msg_str((char_u *)_("calling %s"), sourcing_name); 9555 if (p_verbose >= 14) 9556 { 9557 int i; 9558 char_u buf[MSG_BUF_LEN]; 9559 9560 msg_puts((char_u *)"("); 9561 for (i = 0; i < argcount; ++i) 9562 { 9563 if (i > 0) 9564 msg_puts((char_u *)", "); 9565 if (argvars[i].var_type == VAR_NUMBER) 9566 msg_outnum((long)argvars[i].var_val.var_number); 9567 else 9568 { 9569 trunc_string(get_var_string(&argvars[i]), 9570 buf, MSG_BUF_LEN); 9571 msg_puts((char_u *)"\""); 9572 msg_puts(buf); 9573 msg_puts((char_u *)"\""); 9574 } 9575 } 9576 msg_puts((char_u *)")"); 9577 } 9578 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 9579 cmdline_row = msg_row; 9580 --no_wait_return; 9581 } 9582 } 9583 save_current_SID = current_SID; 9584 current_SID = fp->script_ID; 9585 save_did_emsg = did_emsg; 9586 did_emsg = FALSE; 9587 9588 /* call do_cmdline() to execute the lines */ 9589 do_cmdline(NULL, get_func_line, (void *)&fc, 9590 DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT); 9591 9592 --RedrawingDisabled; 9593 9594 /* when the function was aborted because of an error, return -1 */ 9595 if ((did_emsg && (fp->flags & FC_ABORT)) || retvar->var_type == VAR_UNKNOWN) 9596 { 9597 clear_var(retvar); 9598 retvar->var_type = VAR_NUMBER; 9599 retvar->var_val.var_number = -1; 9600 } 9601 9602 /* when being verbose, mention the return value */ 9603 if (p_verbose >= 12) 9604 { 9605 char_u *sn, *val; 9606 9607 ++no_wait_return; 9608 msg_scroll = TRUE; /* always scroll up, don't overwrite */ 9609 9610 /* Make sure the output fits in IObuff. */ 9611 sn = sourcing_name; 9612 if (STRLEN(sourcing_name) > IOSIZE / 2 - 50) 9613 sn = sourcing_name + STRLEN(sourcing_name) - (IOSIZE / 2 - 50); 9614 9615 if (aborting()) 9616 smsg((char_u *)_("%s aborted"), sn); 9617 else if (fc.retvar->var_type == VAR_NUMBER) 9618 smsg((char_u *)_("%s returning #%ld"), sn, 9619 (long)fc.retvar->var_val.var_number); 9620 else if (fc.retvar->var_type == VAR_STRING) 9621 { 9622 val = get_var_string(fc.retvar); 9623 if (STRLEN(val) > IOSIZE / 2 - 50) 9624 val = val + STRLEN(val) - (IOSIZE / 2 - 50); 9625 smsg((char_u *)_("%s returning \"%s\""), sn, val); 9626 } 9627 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 9628 cmdline_row = msg_row; 9629 --no_wait_return; 9630 } 9631 9632 vim_free(sourcing_name); 9633 sourcing_name = save_sourcing_name; 9634 sourcing_lnum = save_sourcing_lnum; 9635 current_SID = save_current_SID; 9636 9637 if (p_verbose >= 12 && sourcing_name != NULL) 9638 { 9639 ++no_wait_return; 9640 msg_scroll = TRUE; /* always scroll up, don't overwrite */ 9641 msg_str((char_u *)_("continuing in %s"), sourcing_name); 9642 msg_puts((char_u *)"\n"); /* don't overwrite this either */ 9643 cmdline_row = msg_row; 9644 --no_wait_return; 9645 } 9646 9647 did_emsg |= save_did_emsg; 9648 current_funccal = save_fcp; 9649 9650 var_clear(&fc.l_vars); /* free all local variables */ 9651 --depth; 9652 } 9653 9654 /* 9655 * ":return [expr]" 9656 */ 9657 void 9658 ex_return(eap) 9659 exarg_T *eap; 9660 { 9661 char_u *arg = eap->arg; 9662 var retvar; 9663 int returning = FALSE; 9664 9665 if (current_funccal == NULL) 9666 { 9667 EMSG(_("E133: :return not inside a function")); 9668 return; 9669 } 9670 9671 if (eap->skip) 9672 ++emsg_skip; 9673 9674 eap->nextcmd = NULL; 9675 if ((*arg != NUL && *arg != '|' && *arg != '\n') 9676 && eval0(arg, &retvar, &eap->nextcmd, !eap->skip) != FAIL) 9677 { 9678 if (!eap->skip) 9679 returning = do_return(eap, FALSE, TRUE, &retvar); 9680 else 9681 clear_var(&retvar); 9682 } 9683 /* It's safer to return also on error. */ 9684 else if (!eap->skip) 9685 { 9686 /* 9687 * Return unless the expression evaluation has been cancelled due to an 9688 * aborting error, an interrupt, or an exception. 9689 */ 9690 if (!aborting()) 9691 returning = do_return(eap, FALSE, TRUE, NULL); 9692 } 9693 9694 /* When skipping or the return gets pending, advance to the next command 9695 * in this line (!returning). Otherwise, ignore the rest of the line. 9696 * Following lines will be ignored by get_func_line(). */ 9697 if (returning) 9698 eap->nextcmd = NULL; 9699 else if (eap->nextcmd == NULL) /* no argument */ 9700 eap->nextcmd = check_nextcmd(arg); 9701 9702 if (eap->skip) 9703 --emsg_skip; 9704 } 9705 9706 /* 9707 * Return from a function. Possibly makes the return pending. Also called 9708 * for a pending return at the ":endtry" or after returning from an extra 9709 * do_cmdline(). "reanimate" is used in the latter case. "is_cmd" is set 9710 * when called due to a ":return" command. "value" may point to a variable 9711 * with the return value. Returns TRUE when the return can be carried out, 9712 * FALSE when the return gets pending. 9713 */ 9714 int 9715 do_return(eap, reanimate, is_cmd, value) 9716 exarg_T *eap; 9717 int reanimate; 9718 int is_cmd; 9719 void *value; 9720 { 9721 int idx; 9722 struct condstack *cstack = eap->cstack; 9723 9724 if (reanimate) 9725 /* Undo the return. */ 9726 current_funccal->returned = FALSE; 9727 9728 /* 9729 * Cleanup (and inactivate) conditionals, but stop when a try conditional 9730 * not in its finally clause (which then is to be executed next) is found. 9731 * In this case, make the ":return" pending for execution at the ":endtry". 9732 * Otherwise, return normally. 9733 */ 9734 idx = cleanup_conditionals(eap->cstack, 0, TRUE); 9735 if (idx >= 0) 9736 { 9737 cstack->cs_pending[idx] = CSTP_RETURN; 9738 9739 if (!is_cmd && !reanimate) 9740 /* A pending return again gets pending. "value" points to an 9741 * allocated variable with the value of the original ":return"'s 9742 * argument if present or is NULL else. */ 9743 cstack->cs_retvar[idx] = value; 9744 else 9745 { 9746 /* When undoing a return in order to make it pending, get the stored 9747 * return value. */ 9748 if (reanimate) 9749 value = current_funccal->retvar; 9750 9751 if (value != NULL) 9752 { 9753 /* Store the value of the pending return. */ 9754 if ((cstack->cs_retvar[idx] = alloc_var()) != NULL) 9755 *(VAR)cstack->cs_retvar[idx] = *(VAR)value; 9756 else 9757 EMSG(_(e_outofmem)); 9758 } 9759 else 9760 cstack->cs_retvar[idx] = NULL; 9761 9762 if (reanimate) 9763 { 9764 /* The pending return value could be overwritten by a ":return" 9765 * without argument in a finally clause; reset the default 9766 * return value. */ 9767 current_funccal->retvar->var_type = VAR_NUMBER; 9768 current_funccal->retvar->var_val.var_number = 0; 9769 } 9770 } 9771 report_make_pending(CSTP_RETURN, value); 9772 } 9773 else 9774 { 9775 current_funccal->returned = TRUE; 9776 9777 /* If the return is carried out now, store the return value. For 9778 * a return immediately after reanimation, the value is already 9779 * there. */ 9780 if (!reanimate && value != NULL) 9781 { 9782 clear_var(current_funccal->retvar); 9783 *current_funccal->retvar = *(VAR)value; 9784 if (!is_cmd) 9785 vim_free(value); 9786 } 9787 } 9788 9789 return idx < 0; 9790 } 9791 9792 /* 9793 * Free the variable with a pending return value. 9794 */ 9795 void 9796 discard_pending_return(retvar) 9797 void *retvar; 9798 { 9799 /* The variable was copied from one with an undefined var_name. So we can't 9800 * use free_var() to clear and free it. */ 9801 clear_var((VAR)retvar); 9802 vim_free(retvar); 9803 } 9804 9805 /* 9806 * Generate a return command for producing the value of "retvar". The result 9807 * is an allocated string. Used by report_pending() for verbose messages. 9808 */ 9809 char_u * 9810 get_return_cmd(retvar) 9811 void *retvar; 9812 { 9813 char_u *s = IObuff; 9814 9815 if (retvar == NULL || ((VAR)retvar)->var_type == VAR_UNKNOWN) 9816 s = (char_u *)":return"; 9817 else if (((VAR)retvar)->var_type == VAR_STRING) 9818 sprintf((char *)IObuff, ":return \"%s\"", 9819 ((VAR)retvar)->var_val.var_string); 9820 else 9821 sprintf((char *)IObuff, ":return %ld", 9822 (long)(((VAR)retvar)->var_val.var_number)); 9823 return vim_strsave(s); 9824 } 9825 9826 /* 9827 * Get next function line. 9828 * Called by do_cmdline() to get the next line. 9829 * Returns allocated string, or NULL for end of function. 9830 */ 9831 /* ARGSUSED */ 9832 char_u * 9833 get_func_line(c, cookie, indent) 9834 int c; /* not used */ 9835 void *cookie; 9836 int indent; /* not used */ 9837 { 9838 struct funccall *fcp = (struct funccall *)cookie; 9839 char_u *retval; 9840 garray_T *gap; /* growarray with function lines */ 9841 9842 /* If breakpoints have been added/deleted need to check for it. */ 9843 if (fcp->dbg_tick != debug_tick) 9844 { 9845 fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name, 9846 sourcing_lnum); 9847 fcp->dbg_tick = debug_tick; 9848 } 9849 9850 gap = &fcp->func->lines; 9851 if ((fcp->func->flags & FC_ABORT) && did_emsg && !aborted_in_try()) 9852 retval = NULL; 9853 else if (fcp->returned || fcp->linenr >= gap->ga_len) 9854 retval = NULL; 9855 else 9856 { 9857 retval = vim_strsave(((char_u **)(gap->ga_data))[fcp->linenr++]); 9858 sourcing_lnum = fcp->linenr; 9859 } 9860 9861 /* Did we encounter a breakpoint? */ 9862 if (fcp->breakpoint != 0 && fcp->breakpoint <= sourcing_lnum) 9863 { 9864 dbg_breakpoint(fcp->func->name, sourcing_lnum); 9865 /* Find next breakpoint. */ 9866 fcp->breakpoint = dbg_find_breakpoint(FALSE, fcp->func->name, 9867 sourcing_lnum); 9868 fcp->dbg_tick = debug_tick; 9869 } 9870 9871 return retval; 9872 } 9873 9874 /* 9875 * Return TRUE if the currently active function should be ended, because a 9876 * return was encountered or an error occured. Used inside a ":while". 9877 */ 9878 int 9879 func_has_ended(cookie) 9880 void *cookie; 9881 { 9882 struct funccall *fcp = (struct funccall *)cookie; 9883 9884 /* Ignore the "abort" flag if the abortion behavior has been changed due to 9885 * an error inside a try conditional. */ 9886 return (((fcp->func->flags & FC_ABORT) && did_emsg && !aborted_in_try()) 9887 || fcp->returned); 9888 } 9889 9890 /* 9891 * return TRUE if cookie indicates a function which "abort"s on errors. 9892 */ 9893 int 9894 func_has_abort(cookie) 9895 void *cookie; 9896 { 9897 return ((struct funccall *)cookie)->func->flags & FC_ABORT; 9898 } 9899 9900 #if defined(FEAT_VIMINFO) || defined(FEAT_SESSION) 9901 typedef enum 9902 { 9903 VAR_FLAVOUR_DEFAULT, 9904 VAR_FLAVOUR_SESSION, 9905 VAR_FLAVOUR_VIMINFO 9906 } var_flavour_T; 9907 9908 static var_flavour_T var_flavour __ARGS((char_u *varname)); 9909 9910 static var_flavour_T 9911 var_flavour(varname) 9912 char_u *varname; 9913 { 9914 char_u *p = varname; 9915 9916 if (ASCII_ISUPPER(*p)) 9917 { 9918 while (*(++p)) 9919 if (ASCII_ISLOWER(*p)) 9920 return VAR_FLAVOUR_SESSION; 9921 return VAR_FLAVOUR_VIMINFO; 9922 } 9923 else 9924 return VAR_FLAVOUR_DEFAULT; 9925 } 9926 #endif 9927 9928 #if defined(FEAT_VIMINFO) || defined(PROTO) 9929 /* 9930 * Restore global vars that start with a capital from the viminfo file 9931 */ 9932 int 9933 read_viminfo_varlist(virp, writing) 9934 vir_T *virp; 9935 int writing; 9936 { 9937 char_u *tab; 9938 int is_string = FALSE; 9939 VAR varp = NULL; 9940 char_u *val; 9941 9942 if (!writing && (find_viminfo_parameter('!') != NULL)) 9943 { 9944 tab = vim_strchr(virp->vir_line + 1, '\t'); 9945 if (tab != NULL) 9946 { 9947 *tab++ = '\0'; /* isolate the variable name */ 9948 if (*tab == 'S') /* string var */ 9949 is_string = TRUE; 9950 9951 tab = vim_strchr(tab, '\t'); 9952 if (tab != NULL) 9953 { 9954 /* create a nameless variable to hold the value */ 9955 if (is_string) 9956 { 9957 val = viminfo_readstring(virp, 9958 (int)(tab - virp->vir_line + 1), TRUE); 9959 if (val != NULL) 9960 varp = alloc_string_var(val); 9961 } 9962 else 9963 { 9964 varp = alloc_var(); 9965 if (varp != NULL) 9966 { 9967 varp->var_type = VAR_NUMBER; 9968 varp->var_val.var_number = atol((char *)tab + 1); 9969 } 9970 } 9971 /* assign the value to the variable */ 9972 if (varp != NULL) 9973 { 9974 set_var(virp->vir_line + 1, varp); 9975 free_var(varp); 9976 } 9977 } 9978 } 9979 } 9980 9981 return viminfo_readline(virp); 9982 } 9983 9984 /* 9985 * Write global vars that start with a capital to the viminfo file 9986 */ 9987 void 9988 write_viminfo_varlist(fp) 9989 FILE *fp; 9990 { 9991 garray_T *gap = &variables; /* global variable */ 9992 VAR this_var; 9993 int i; 9994 9995 if (find_viminfo_parameter('!') == NULL) 9996 return; 9997 9998 fprintf(fp, _("\n# global variables:\n")); 9999 for (i = gap->ga_len; --i >= 0; ) 10000 { 10001 this_var = &VAR_GAP_ENTRY(i, gap); 10002 if (this_var->var_name != NULL 10003 && var_flavour(this_var->var_name) == VAR_FLAVOUR_VIMINFO) 10004 { 10005 fprintf(fp, "!%s\t%s\t", this_var->var_name, 10006 (this_var->var_type == VAR_STRING) ? "STR" : "NUM"); 10007 viminfo_writestring(fp, get_var_string(this_var)); 10008 } 10009 } 10010 } 10011 #endif 10012 10013 #if defined(FEAT_SESSION) || defined(PROTO) 10014 int 10015 store_session_globals(fd) 10016 FILE *fd; 10017 { 10018 garray_T *gap = &variables; /* global variable */ 10019 VAR this_var; 10020 int i; 10021 char_u *p, *t; 10022 10023 for (i = gap->ga_len; --i >= 0; ) 10024 { 10025 this_var = &VAR_GAP_ENTRY(i, gap); 10026 if (this_var->var_name != NULL) 10027 { 10028 if (var_flavour(this_var->var_name) == VAR_FLAVOUR_SESSION) 10029 { 10030 /* Escapse special characters with a backslash. Turn a LF and 10031 * CR into \n and \r. */ 10032 p = vim_strsave_escaped(get_var_string(this_var), 10033 (char_u *)"\\\"\n\r"); 10034 if (p == NULL) /* out of memory */ 10035 continue; 10036 for (t = p; *t != NUL; ++t) 10037 if (*t == '\n') 10038 *t = 'n'; 10039 else if (*t == '\r') 10040 *t = 'r'; 10041 if ((fprintf(fd, "let %s = %c%s%c", 10042 this_var->var_name, 10043 (this_var->var_type == VAR_STRING) ? '"' : ' ', 10044 p, 10045 (this_var->var_type == VAR_STRING) ? '"' : ' ') < 0) 10046 || put_eol(fd) == FAIL) 10047 { 10048 vim_free(p); 10049 return FAIL; 10050 } 10051 vim_free(p); 10052 } 10053 10054 } 10055 } 10056 return OK; 10057 } 10058 #endif 10059 10060 #endif /* FEAT_EVAL */ 10061 10062 #if defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) || defined(PROTO) 10063 10064 10065 #ifdef WIN3264 10066 /* 10067 * Functions for ":8" filename modifier: get 8.3 version of a filename. 10068 */ 10069 static int get_short_pathname __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 10070 static int shortpath_for_invalid_fname __ARGS((char_u **fname, char_u **bufp, int *fnamelen)); 10071 static int shortpath_for_partial __ARGS((char_u **fnamep, char_u **bufp, int *fnamelen)); 10072 10073 /* 10074 * Get the short pathname of a file. 10075 * Returns 1 on success. *fnamelen is 0 for nonexistant path. 10076 */ 10077 static int 10078 get_short_pathname(fnamep, bufp, fnamelen) 10079 char_u **fnamep; 10080 char_u **bufp; 10081 int *fnamelen; 10082 { 10083 int l,len; 10084 char_u *newbuf; 10085 10086 len = *fnamelen; 10087 10088 l = GetShortPathName(*fnamep, *fnamep, len); 10089 if (l > len - 1) 10090 { 10091 /* If that doesn't work (not enough space), then save the string 10092 * and try again with a new buffer big enough 10093 */ 10094 newbuf = vim_strnsave(*fnamep, l); 10095 if (newbuf == NULL) 10096 return 0; 10097 10098 vim_free(*bufp); 10099 *fnamep = *bufp = newbuf; 10100 10101 l = GetShortPathName(*fnamep,*fnamep,l+1); 10102 10103 /* Really should always succeed, as the buffer is big enough */ 10104 } 10105 10106 *fnamelen = l; 10107 return 1; 10108 } 10109 10110 /* 10111 * Create a short path name. Returns the length of the buffer it needs. 10112 * Doesn't copy over the end of the buffer passed in. 10113 */ 10114 static int 10115 shortpath_for_invalid_fname(fname, bufp, fnamelen) 10116 char_u **fname; 10117 char_u **bufp; 10118 int *fnamelen; 10119 { 10120 char_u *s, *p, *pbuf2, *pbuf3; 10121 char_u ch; 10122 int l,len,len2,plen,slen; 10123 10124 /* Make a copy */ 10125 len2 = *fnamelen; 10126 pbuf2 = vim_strnsave(*fname, len2); 10127 pbuf3 = NULL; 10128 10129 s = pbuf2 + len2 - 1; /* Find the end */ 10130 slen = 1; 10131 plen = len2; 10132 10133 l = 0; 10134 if (vim_ispathsep(*s)) 10135 { 10136 --s; 10137 ++slen; 10138 --plen; 10139 } 10140 10141 do 10142 { 10143 /* Go back one path-seperator */ 10144 while (s > pbuf2 && !vim_ispathsep(*s)) 10145 { 10146 --s; 10147 ++slen; 10148 --plen; 10149 } 10150 if (s <= pbuf2) 10151 break; 10152 10153 /* Remeber the character that is about to be blatted */ 10154 ch = *s; 10155 *s = 0; /* get_short_pathname requires a null-terminated string */ 10156 10157 /* Try it in situ */ 10158 p = pbuf2; 10159 if (!get_short_pathname(&p, &pbuf3, &plen)) 10160 { 10161 vim_free(pbuf2); 10162 return -1; 10163 } 10164 *s = ch; /* Preserve the string */ 10165 } while (plen == 0); 10166 10167 if (plen > 0) 10168 { 10169 /* Remeber the length of the new string. */ 10170 *fnamelen = len = plen + slen; 10171 vim_free(*bufp); 10172 if (len > len2) 10173 { 10174 /* If there's not enough space in the currently allocated string, 10175 * then copy it to a buffer big enough. 10176 */ 10177 *fname= *bufp = vim_strnsave(p, len); 10178 if (*fname == NULL) 10179 return -1; 10180 } 10181 else 10182 { 10183 /* Transfer pbuf2 to being the main buffer (it's big enough) */ 10184 *fname = *bufp = pbuf2; 10185 if (p != pbuf2) 10186 strncpy(*fname, p, plen); 10187 pbuf2 = NULL; 10188 } 10189 /* Concat the next bit */ 10190 strncpy(*fname + plen, s, slen); 10191 (*fname)[len] = '\0'; 10192 } 10193 vim_free(pbuf3); 10194 vim_free(pbuf2); 10195 return 0; 10196 } 10197 10198 /* 10199 * Get a pathname for a partial path. 10200 */ 10201 static int 10202 shortpath_for_partial(fnamep, bufp, fnamelen) 10203 char_u **fnamep; 10204 char_u **bufp; 10205 int *fnamelen; 10206 { 10207 int sepcount, len, tflen; 10208 char_u *p; 10209 char_u *pbuf, *tfname; 10210 int hasTilde; 10211 10212 /* Count up the path seperators from the RHS.. so we know which part 10213 * of the path to return. 10214 */ 10215 sepcount = 0; 10216 for (p = *fnamep + *fnamelen - 1; p >= *fnamep; --p) 10217 if (vim_ispathsep(*p)) 10218 ++sepcount; 10219 10220 /* Need full path first (use expand_env() to remove a "~/") */ 10221 hasTilde = (**fnamep == '~'); 10222 if (hasTilde) 10223 pbuf = tfname = expand_env_save(*fnamep); 10224 else 10225 pbuf = tfname = FullName_save(*fnamep, FALSE); 10226 10227 len = tflen = STRLEN(tfname); 10228 10229 if (!get_short_pathname(&tfname, &pbuf, &len)) 10230 return -1; 10231 10232 if (len == 0) 10233 { 10234 /* Don't have a valid filename, so shorten the rest of the 10235 * path if we can. This CAN give us invalid 8.3 filenames, but 10236 * there's not a lot of point in guessing what it might be. 10237 */ 10238 len = tflen; 10239 if (shortpath_for_invalid_fname(&tfname, &pbuf, &len) == -1) 10240 return -1; 10241 } 10242 10243 /* Count the paths backward to find the beginning of the desired string. */ 10244 for (p = tfname + len - 1; p >= tfname; --p) 10245 if (vim_ispathsep(*p)) 10246 { 10247 if (sepcount == 0 || (hasTilde && sepcount == 1)) 10248 break; 10249 else 10250 sepcount --; 10251 } 10252 if (hasTilde) 10253 { 10254 --p; 10255 if (p >= tfname) 10256 *p = '~'; 10257 else 10258 return -1; 10259 } 10260 else 10261 ++p; 10262 10263 /* Copy in the string - p indexes into tfname - allocated at pbuf */ 10264 vim_free(*bufp); 10265 *fnamelen = (int)STRLEN(p); 10266 *bufp = pbuf; 10267 *fnamep = p; 10268 10269 return 0; 10270 } 10271 #endif /* WIN3264 */ 10272 10273 /* 10274 * Adjust a filename, according to a string of modifiers. 10275 * *fnamep must be NUL terminated when called. When returning, the length is 10276 * determined by *fnamelen. 10277 * Returns valid flags. 10278 * When there is an error, *fnamep is set to NULL. 10279 */ 10280 int 10281 modify_fname(src, usedlen, fnamep, bufp, fnamelen) 10282 char_u *src; /* string with modifiers */ 10283 int *usedlen; /* characters after src that are used */ 10284 char_u **fnamep; /* file name so far */ 10285 char_u **bufp; /* buffer for allocated file name or NULL */ 10286 int *fnamelen; /* length of fnamep */ 10287 { 10288 int valid = 0; 10289 char_u *tail; 10290 char_u *s, *p, *pbuf; 10291 char_u dirname[MAXPATHL]; 10292 int c; 10293 int has_fullname = 0; 10294 #ifdef WIN3264 10295 int has_shortname = 0; 10296 #endif 10297 10298 repeat: 10299 /* ":p" - full path/file_name */ 10300 if (src[*usedlen] == ':' && src[*usedlen + 1] == 'p') 10301 { 10302 has_fullname = 1; 10303 10304 valid |= VALID_PATH; 10305 *usedlen += 2; 10306 10307 /* Expand "~/path" for all systems and "~user/path" for Unix and VMS */ 10308 if ((*fnamep)[0] == '~' 10309 #if !defined(UNIX) && !(defined(VMS) && defined(USER_HOME)) 10310 && ((*fnamep)[1] == '/' 10311 # ifdef BACKSLASH_IN_FILENAME 10312 || (*fnamep)[1] == '\\' 10313 # endif 10314 || (*fnamep)[1] == NUL) 10315 10316 #endif 10317 ) 10318 { 10319 *fnamep = expand_env_save(*fnamep); 10320 vim_free(*bufp); /* free any allocated file name */ 10321 *bufp = *fnamep; 10322 if (*fnamep == NULL) 10323 return -1; 10324 } 10325 10326 /* When "/." or "/.." is used: force expansion to get rid of it. */ 10327 for (p = *fnamep; *p != NUL; ++p) 10328 { 10329 if (vim_ispathsep(*p) 10330 && p[1] == '.' 10331 && (p[2] == NUL 10332 || vim_ispathsep(p[2]) 10333 || (p[2] == '.' 10334 && (p[3] == NUL || vim_ispathsep(p[3]))))) 10335 break; 10336 } 10337 10338 /* FullName_save() is slow, don't use it when not needed. */ 10339 if (*p != NUL || !vim_isAbsName(*fnamep)) 10340 { 10341 *fnamep = FullName_save(*fnamep, *p != NUL); 10342 vim_free(*bufp); /* free any allocated file name */ 10343 *bufp = *fnamep; 10344 if (*fnamep == NULL) 10345 return -1; 10346 } 10347 10348 /* Append a path separator to a directory. */ 10349 if (mch_isdir(*fnamep)) 10350 { 10351 /* Make room for one or two extra characters. */ 10352 *fnamep = vim_strnsave(*fnamep, (int)STRLEN(*fnamep) + 2); 10353 vim_free(*bufp); /* free any allocated file name */ 10354 *bufp = *fnamep; 10355 if (*fnamep == NULL) 10356 return -1; 10357 add_pathsep(*fnamep); 10358 } 10359 } 10360 10361 /* ":." - path relative to the current directory */ 10362 /* ":~" - path relative to the home directory */ 10363 /* ":8" - shortname path - postponed till after */ 10364 while (src[*usedlen] == ':' 10365 && ((c = src[*usedlen + 1]) == '.' || c == '~' || c == '8')) 10366 { 10367 *usedlen += 2; 10368 if (c == '8') 10369 { 10370 #ifdef WIN3264 10371 has_shortname = 1; /* Postpone this. */ 10372 #endif 10373 continue; 10374 } 10375 pbuf = NULL; 10376 /* Need full path first (use expand_env() to remove a "~/") */ 10377 if (!has_fullname) 10378 { 10379 if (c == '.' && **fnamep == '~') 10380 p = pbuf = expand_env_save(*fnamep); 10381 else 10382 p = pbuf = FullName_save(*fnamep, FALSE); 10383 } 10384 else 10385 p = *fnamep; 10386 10387 has_fullname = 0; 10388 10389 if (p != NULL) 10390 { 10391 if (c == '.') 10392 { 10393 mch_dirname(dirname, MAXPATHL); 10394 s = shorten_fname(p, dirname); 10395 if (s != NULL) 10396 { 10397 *fnamep = s; 10398 if (pbuf != NULL) 10399 { 10400 vim_free(*bufp); /* free any allocated file name */ 10401 *bufp = pbuf; 10402 pbuf = NULL; 10403 } 10404 } 10405 } 10406 else 10407 { 10408 home_replace(NULL, p, dirname, MAXPATHL, TRUE); 10409 /* Only replace it when it starts with '~' */ 10410 if (*dirname == '~') 10411 { 10412 s = vim_strsave(dirname); 10413 if (s != NULL) 10414 { 10415 *fnamep = s; 10416 vim_free(*bufp); 10417 *bufp = s; 10418 } 10419 } 10420 } 10421 vim_free(pbuf); 10422 } 10423 } 10424 10425 tail = gettail(*fnamep); 10426 *fnamelen = (int)STRLEN(*fnamep); 10427 10428 /* ":h" - head, remove "/file_name", can be repeated */ 10429 /* Don't remove the first "/" or "c:\" */ 10430 while (src[*usedlen] == ':' && src[*usedlen + 1] == 'h') 10431 { 10432 valid |= VALID_HEAD; 10433 *usedlen += 2; 10434 s = get_past_head(*fnamep); 10435 while (tail > s && vim_ispathsep(tail[-1])) 10436 --tail; 10437 *fnamelen = (int)(tail - *fnamep); 10438 #ifdef VMS 10439 if (*fnamelen > 0) 10440 *fnamelen += 1; /* the path separator is part of the path */ 10441 #endif 10442 while (tail > s && !vim_ispathsep(tail[-1])) 10443 --tail; 10444 } 10445 10446 /* ":8" - shortname */ 10447 if (src[*usedlen] == ':' && src[*usedlen + 1] == '8') 10448 { 10449 *usedlen += 2; 10450 #ifdef WIN3264 10451 has_shortname = 1; 10452 #endif 10453 } 10454 10455 #ifdef WIN3264 10456 /* Check shortname after we have done 'heads' and before we do 'tails' 10457 */ 10458 if (has_shortname) 10459 { 10460 pbuf = NULL; 10461 /* Copy the string if it is shortened by :h */ 10462 if (*fnamelen < (int)STRLEN(*fnamep)) 10463 { 10464 p = vim_strnsave(*fnamep, *fnamelen); 10465 if (p == 0) 10466 return -1; 10467 vim_free(*bufp); 10468 *bufp = *fnamep = p; 10469 } 10470 10471 /* Split into two implementations - makes it easier. First is where 10472 * there isn't a full name already, second is where there is. 10473 */ 10474 if (!has_fullname && !vim_isAbsName(*fnamep)) 10475 { 10476 if (shortpath_for_partial(fnamep, bufp, fnamelen) == -1) 10477 return -1; 10478 } 10479 else 10480 { 10481 int l; 10482 10483 /* Simple case, already have the full-name 10484 * Nearly always shorter, so try first time. */ 10485 l = *fnamelen; 10486 if (!get_short_pathname(fnamep, bufp, &l)) 10487 return -1; 10488 10489 if (l == 0) 10490 { 10491 /* Couldn't find the filename.. search the paths. 10492 */ 10493 l = *fnamelen; 10494 if (shortpath_for_invalid_fname(fnamep, bufp, &l ) == -1) 10495 return -1; 10496 } 10497 *fnamelen = l; 10498 } 10499 } 10500 #endif /* WIN3264 */ 10501 10502 /* ":t" - tail, just the basename */ 10503 if (src[*usedlen] == ':' && src[*usedlen + 1] == 't') 10504 { 10505 *usedlen += 2; 10506 *fnamelen -= (int)(tail - *fnamep); 10507 *fnamep = tail; 10508 } 10509 10510 /* ":e" - extension, can be repeated */ 10511 /* ":r" - root, without extension, can be repeated */ 10512 while (src[*usedlen] == ':' 10513 && (src[*usedlen + 1] == 'e' || src[*usedlen + 1] == 'r')) 10514 { 10515 /* find a '.' in the tail: 10516 * - for second :e: before the current fname 10517 * - otherwise: The last '.' 10518 */ 10519 if (src[*usedlen + 1] == 'e' && *fnamep > tail) 10520 s = *fnamep - 2; 10521 else 10522 s = *fnamep + *fnamelen - 1; 10523 for ( ; s > tail; --s) 10524 if (s[0] == '.') 10525 break; 10526 if (src[*usedlen + 1] == 'e') /* :e */ 10527 { 10528 if (s > tail) 10529 { 10530 *fnamelen += (int)(*fnamep - (s + 1)); 10531 *fnamep = s + 1; 10532 #ifdef VMS 10533 /* cut version from the extension */ 10534 s = *fnamep + *fnamelen - 1; 10535 for ( ; s > *fnamep; --s) 10536 if (s[0] == ';') 10537 break; 10538 if (s > *fnamep) 10539 *fnamelen = s - *fnamep; 10540 #endif 10541 } 10542 else if (*fnamep <= tail) 10543 *fnamelen = 0; 10544 } 10545 else /* :r */ 10546 { 10547 if (s > tail) /* remove one extension */ 10548 *fnamelen = (int)(s - *fnamep); 10549 } 10550 *usedlen += 2; 10551 } 10552 10553 /* ":s?pat?foo?" - substitute */ 10554 /* ":gs?pat?foo?" - global substitute */ 10555 if (src[*usedlen] == ':' 10556 && (src[*usedlen + 1] == 's' 10557 || (src[*usedlen + 1] == 'g' && src[*usedlen + 2] == 's'))) 10558 { 10559 char_u *str; 10560 char_u *pat; 10561 char_u *sub; 10562 int sep; 10563 char_u *flags; 10564 int didit = FALSE; 10565 10566 flags = (char_u *)""; 10567 s = src + *usedlen + 2; 10568 if (src[*usedlen + 1] == 'g') 10569 { 10570 flags = (char_u *)"g"; 10571 ++s; 10572 } 10573 10574 sep = *s++; 10575 if (sep) 10576 { 10577 /* find end of pattern */ 10578 p = vim_strchr(s, sep); 10579 if (p != NULL) 10580 { 10581 pat = vim_strnsave(s, (int)(p - s)); 10582 if (pat != NULL) 10583 { 10584 s = p + 1; 10585 /* find end of substitution */ 10586 p = vim_strchr(s, sep); 10587 if (p != NULL) 10588 { 10589 sub = vim_strnsave(s, (int)(p - s)); 10590 str = vim_strnsave(*fnamep, *fnamelen); 10591 if (sub != NULL && str != NULL) 10592 { 10593 *usedlen = (int)(p + 1 - src); 10594 s = do_string_sub(str, pat, sub, flags); 10595 if (s != NULL) 10596 { 10597 *fnamep = s; 10598 *fnamelen = (int)STRLEN(s); 10599 vim_free(*bufp); 10600 *bufp = s; 10601 didit = TRUE; 10602 } 10603 } 10604 vim_free(sub); 10605 vim_free(str); 10606 } 10607 vim_free(pat); 10608 } 10609 } 10610 /* after using ":s", repeat all the modifiers */ 10611 if (didit) 10612 goto repeat; 10613 } 10614 } 10615 10616 return valid; 10617 } 10618 10619 /* 10620 * Perform a substitution on "str" with pattern "pat" and substitute "sub". 10621 * "flags" can be "g" to do a global substitute. 10622 * Returns an allocated string, NULL for error. 10623 */ 10624 char_u * 10625 do_string_sub(str, pat, sub, flags) 10626 char_u *str; 10627 char_u *pat; 10628 char_u *sub; 10629 char_u *flags; 10630 { 10631 int sublen; 10632 regmatch_T regmatch; 10633 int i; 10634 int do_all; 10635 char_u *tail; 10636 garray_T ga; 10637 char_u *ret; 10638 char_u *save_cpo; 10639 10640 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ 10641 save_cpo = p_cpo; 10642 p_cpo = (char_u *)""; 10643 10644 ga_init2(&ga, 1, 200); 10645 10646 do_all = (flags[0] == 'g'); 10647 10648 regmatch.rm_ic = p_ic; 10649 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 10650 if (regmatch.regprog != NULL) 10651 { 10652 tail = str; 10653 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) 10654 { 10655 /* 10656 * Get some space for a temporary buffer to do the substitution 10657 * into. It will contain: 10658 * - The text up to where the match is. 10659 * - The substituted text. 10660 * - The text after the match. 10661 */ 10662 sublen = vim_regsub(®match, sub, tail, FALSE, TRUE, FALSE); 10663 if (ga_grow(&ga, (int)(STRLEN(tail) + sublen - 10664 (regmatch.endp[0] - regmatch.startp[0]))) == FAIL) 10665 { 10666 ga_clear(&ga); 10667 break; 10668 } 10669 10670 /* copy the text up to where the match is */ 10671 i = (int)(regmatch.startp[0] - tail); 10672 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); 10673 /* add the substituted text */ 10674 (void)vim_regsub(®match, sub, (char_u *)ga.ga_data 10675 + ga.ga_len + i, TRUE, TRUE, FALSE); 10676 ga.ga_len += i + sublen - 1; 10677 ga.ga_room -= i + sublen - 1; 10678 /* avoid getting stuck on a match with an empty string */ 10679 if (tail == regmatch.endp[0]) 10680 { 10681 if (*tail == NUL) 10682 break; 10683 *((char_u *)ga.ga_data + ga.ga_len) = *tail++; 10684 ++ga.ga_len; 10685 --ga.ga_room; 10686 } 10687 else 10688 { 10689 tail = regmatch.endp[0]; 10690 if (*tail == NUL) 10691 break; 10692 } 10693 if (!do_all) 10694 break; 10695 } 10696 10697 if (ga.ga_data != NULL) 10698 STRCPY((char *)ga.ga_data + ga.ga_len, tail); 10699 10700 vim_free(regmatch.regprog); 10701 } 10702 10703 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); 10704 ga_clear(&ga); 10705 p_cpo = save_cpo; 10706 10707 return ret; 10708 } 10709 10710 #endif /* defined(FEAT_MODIFY_FNAME) || defined(FEAT_EVAL) */ 10711