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