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