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