comparison src/eval.c @ 83:d9030055c432 v7.0033

updated for version 7.0033
author vimboss
date Fri, 07 Jan 2005 21:51:51 +0000
parents d2796c60ca6f
children 8173ec1e9f1f
comparison
equal deleted inserted replaced
82:366d9947baf2 83:d9030055c432
107 static char *e_letunexp = N_("E18: Unexpected characters in :let"); 107 static char *e_letunexp = N_("E18: Unexpected characters in :let");
108 static char *e_listidx = N_("E999: list index out of range: %ld"); 108 static char *e_listidx = N_("E999: list index out of range: %ld");
109 static char *e_undefvar = N_("E121: Undefined variable: %s"); 109 static char *e_undefvar = N_("E121: Undefined variable: %s");
110 static char *e_missbrac = N_("E111: Missing ']'"); 110 static char *e_missbrac = N_("E111: Missing ']'");
111 static char *e_intern2 = N_("E999: Internal error: %s"); 111 static char *e_intern2 = N_("E999: Internal error: %s");
112 static char *e_listarg = N_("E999: Argument of %s must be a list");
112 113
113 /* 114 /*
114 * All user-defined global variables are stored in "variables". 115 * All user-defined global variables are stored in "variables".
115 */ 116 */
116 garray_T variables = {0, 0, sizeof(var), 4, NULL}; 117 garray_T variables = {0, 0, sizeof(var), 4, NULL};
336 static int get_env_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); 337 static int get_env_tv __ARGS((char_u **arg, typeval *rettv, int evaluate));
337 static int find_internal_func __ARGS((char_u *name)); 338 static int find_internal_func __ARGS((char_u *name));
338 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); 339 static char_u *deref_func_name __ARGS((char_u *name, int *lenp));
339 static int get_func_tv __ARGS((char_u *name, int len, typeval *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); 340 static int get_func_tv __ARGS((char_u *name, int len, typeval *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate));
340 static int call_func __ARGS((char_u *name, int len, typeval *rettv, int argcount, typeval *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); 341 static int call_func __ARGS((char_u *name, int len, typeval *rettv, int argcount, typeval *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate));
342
343 static void f_add __ARGS((typeval *argvars, typeval *rettv));
341 static void f_append __ARGS((typeval *argvars, typeval *rettv)); 344 static void f_append __ARGS((typeval *argvars, typeval *rettv));
342 static void f_argc __ARGS((typeval *argvars, typeval *rettv)); 345 static void f_argc __ARGS((typeval *argvars, typeval *rettv));
343 static void f_argidx __ARGS((typeval *argvars, typeval *rettv)); 346 static void f_argidx __ARGS((typeval *argvars, typeval *rettv));
344 static void f_argv __ARGS((typeval *argvars, typeval *rettv)); 347 static void f_argv __ARGS((typeval *argvars, typeval *rettv));
345 static void f_browse __ARGS((typeval *argvars, typeval *rettv)); 348 static void f_browse __ARGS((typeval *argvars, typeval *rettv));
346 static void f_browsedir __ARGS((typeval *argvars, typeval *rettv)); 349 static void f_browsedir __ARGS((typeval *argvars, typeval *rettv));
347 static buf_T *find_buffer __ARGS((typeval *avar));
348 static void f_bufexists __ARGS((typeval *argvars, typeval *rettv)); 350 static void f_bufexists __ARGS((typeval *argvars, typeval *rettv));
349 static void f_buflisted __ARGS((typeval *argvars, typeval *rettv)); 351 static void f_buflisted __ARGS((typeval *argvars, typeval *rettv));
350 static void f_bufloaded __ARGS((typeval *argvars, typeval *rettv)); 352 static void f_bufloaded __ARGS((typeval *argvars, typeval *rettv));
351 static buf_T *get_buf_tv __ARGS((typeval *tv));
352 static void f_bufname __ARGS((typeval *argvars, typeval *rettv)); 353 static void f_bufname __ARGS((typeval *argvars, typeval *rettv));
353 static void f_bufnr __ARGS((typeval *argvars, typeval *rettv)); 354 static void f_bufnr __ARGS((typeval *argvars, typeval *rettv));
354 static void f_bufwinnr __ARGS((typeval *argvars, typeval *rettv)); 355 static void f_bufwinnr __ARGS((typeval *argvars, typeval *rettv));
355 static void f_byte2line __ARGS((typeval *argvars, typeval *rettv)); 356 static void f_byte2line __ARGS((typeval *argvars, typeval *rettv));
356 static void f_byteidx __ARGS((typeval *argvars, typeval *rettv)); 357 static void f_byteidx __ARGS((typeval *argvars, typeval *rettv));
376 static void f_extend __ARGS((typeval *argvars, typeval *rettv)); 377 static void f_extend __ARGS((typeval *argvars, typeval *rettv));
377 static void f_filereadable __ARGS((typeval *argvars, typeval *rettv)); 378 static void f_filereadable __ARGS((typeval *argvars, typeval *rettv));
378 static void f_filewritable __ARGS((typeval *argvars, typeval *rettv)); 379 static void f_filewritable __ARGS((typeval *argvars, typeval *rettv));
379 static void f_finddir __ARGS((typeval *argvars, typeval *rettv)); 380 static void f_finddir __ARGS((typeval *argvars, typeval *rettv));
380 static void f_findfile __ARGS((typeval *argvars, typeval *rettv)); 381 static void f_findfile __ARGS((typeval *argvars, typeval *rettv));
381 static void f_findfilendir __ARGS((typeval *argvars, typeval *rettv, int dir));
382 static void f_fnamemodify __ARGS((typeval *argvars, typeval *rettv)); 382 static void f_fnamemodify __ARGS((typeval *argvars, typeval *rettv));
383 static void f_foldclosed __ARGS((typeval *argvars, typeval *rettv)); 383 static void f_foldclosed __ARGS((typeval *argvars, typeval *rettv));
384 static void f_foldclosedend __ARGS((typeval *argvars, typeval *rettv)); 384 static void f_foldclosedend __ARGS((typeval *argvars, typeval *rettv));
385 static void foldclosed_both __ARGS((typeval *argvars, typeval *rettv, int end));
386 static void f_foldlevel __ARGS((typeval *argvars, typeval *rettv)); 385 static void f_foldlevel __ARGS((typeval *argvars, typeval *rettv));
387 static void f_foldtext __ARGS((typeval *argvars, typeval *rettv)); 386 static void f_foldtext __ARGS((typeval *argvars, typeval *rettv));
388 static void f_foldtextresult __ARGS((typeval *argvars, typeval *rettv)); 387 static void f_foldtextresult __ARGS((typeval *argvars, typeval *rettv));
389 static void f_foreground __ARGS((typeval *argvars, typeval *rettv)); 388 static void f_foreground __ARGS((typeval *argvars, typeval *rettv));
390 static void f_function __ARGS((typeval *argvars, typeval *rettv)); 389 static void f_function __ARGS((typeval *argvars, typeval *rettv));
390 static void f_get __ARGS((typeval *argvars, typeval *rettv));
391 static void f_getbufvar __ARGS((typeval *argvars, typeval *rettv)); 391 static void f_getbufvar __ARGS((typeval *argvars, typeval *rettv));
392 static void f_getchar __ARGS((typeval *argvars, typeval *rettv)); 392 static void f_getchar __ARGS((typeval *argvars, typeval *rettv));
393 static void f_getcharmod __ARGS((typeval *argvars, typeval *rettv)); 393 static void f_getcharmod __ARGS((typeval *argvars, typeval *rettv));
394 static void f_getcmdline __ARGS((typeval *argvars, typeval *rettv)); 394 static void f_getcmdline __ARGS((typeval *argvars, typeval *rettv));
395 static void f_getcmdpos __ARGS((typeval *argvars, typeval *rettv)); 395 static void f_getcmdpos __ARGS((typeval *argvars, typeval *rettv));
411 static void f_hasmapto __ARGS((typeval *argvars, typeval *rettv)); 411 static void f_hasmapto __ARGS((typeval *argvars, typeval *rettv));
412 static void f_histadd __ARGS((typeval *argvars, typeval *rettv)); 412 static void f_histadd __ARGS((typeval *argvars, typeval *rettv));
413 static void f_histdel __ARGS((typeval *argvars, typeval *rettv)); 413 static void f_histdel __ARGS((typeval *argvars, typeval *rettv));
414 static void f_histget __ARGS((typeval *argvars, typeval *rettv)); 414 static void f_histget __ARGS((typeval *argvars, typeval *rettv));
415 static void f_histnr __ARGS((typeval *argvars, typeval *rettv)); 415 static void f_histnr __ARGS((typeval *argvars, typeval *rettv));
416 static void f_hlID __ARGS((typeval *argvars, typeval *rettv));
416 static void f_hlexists __ARGS((typeval *argvars, typeval *rettv)); 417 static void f_hlexists __ARGS((typeval *argvars, typeval *rettv));
417 static void f_hlID __ARGS((typeval *argvars, typeval *rettv));
418 static void f_hostname __ARGS((typeval *argvars, typeval *rettv)); 418 static void f_hostname __ARGS((typeval *argvars, typeval *rettv));
419 static void f_iconv __ARGS((typeval *argvars, typeval *rettv)); 419 static void f_iconv __ARGS((typeval *argvars, typeval *rettv));
420 static void f_indent __ARGS((typeval *argvars, typeval *rettv)); 420 static void f_indent __ARGS((typeval *argvars, typeval *rettv));
421 static void f_insert __ARGS((typeval *argvars, typeval *rettv));
422 static void f_isdirectory __ARGS((typeval *argvars, typeval *rettv));
423 static void f_index __ARGS((typeval *argvars, typeval *rettv)); 421 static void f_index __ARGS((typeval *argvars, typeval *rettv));
424 static void f_input __ARGS((typeval *argvars, typeval *rettv)); 422 static void f_input __ARGS((typeval *argvars, typeval *rettv));
425 static void f_inputdialog __ARGS((typeval *argvars, typeval *rettv)); 423 static void f_inputdialog __ARGS((typeval *argvars, typeval *rettv));
426 static void f_inputrestore __ARGS((typeval *argvars, typeval *rettv)); 424 static void f_inputrestore __ARGS((typeval *argvars, typeval *rettv));
427 static void f_inputsave __ARGS((typeval *argvars, typeval *rettv)); 425 static void f_inputsave __ARGS((typeval *argvars, typeval *rettv));
428 static void f_inputsecret __ARGS((typeval *argvars, typeval *rettv)); 426 static void f_inputsecret __ARGS((typeval *argvars, typeval *rettv));
427 static void f_insert __ARGS((typeval *argvars, typeval *rettv));
428 static void f_isdirectory __ARGS((typeval *argvars, typeval *rettv));
429 static void f_last_buffer_nr __ARGS((typeval *argvars, typeval *rettv)); 429 static void f_last_buffer_nr __ARGS((typeval *argvars, typeval *rettv));
430 static void f_len __ARGS((typeval *argvars, typeval *rettv)); 430 static void f_len __ARGS((typeval *argvars, typeval *rettv));
431 static void f_libcall __ARGS((typeval *argvars, typeval *rettv)); 431 static void f_libcall __ARGS((typeval *argvars, typeval *rettv));
432 static void f_libcallnr __ARGS((typeval *argvars, typeval *rettv)); 432 static void f_libcallnr __ARGS((typeval *argvars, typeval *rettv));
433 static void libcall_common __ARGS((typeval *argvars, typeval *rettv, int type));
434 static void f_line __ARGS((typeval *argvars, typeval *rettv)); 433 static void f_line __ARGS((typeval *argvars, typeval *rettv));
435 static void f_line2byte __ARGS((typeval *argvars, typeval *rettv)); 434 static void f_line2byte __ARGS((typeval *argvars, typeval *rettv));
436 static void f_lispindent __ARGS((typeval *argvars, typeval *rettv)); 435 static void f_lispindent __ARGS((typeval *argvars, typeval *rettv));
437 static void f_localtime __ARGS((typeval *argvars, typeval *rettv)); 436 static void f_localtime __ARGS((typeval *argvars, typeval *rettv));
438 static void f_maparg __ARGS((typeval *argvars, typeval *rettv)); 437 static void f_maparg __ARGS((typeval *argvars, typeval *rettv));
439 static void f_mapcheck __ARGS((typeval *argvars, typeval *rettv)); 438 static void f_mapcheck __ARGS((typeval *argvars, typeval *rettv));
440 static void get_maparg __ARGS((typeval *argvars, typeval *rettv, int exact));
441 static void f_match __ARGS((typeval *argvars, typeval *rettv)); 439 static void f_match __ARGS((typeval *argvars, typeval *rettv));
442 static void f_matchend __ARGS((typeval *argvars, typeval *rettv)); 440 static void f_matchend __ARGS((typeval *argvars, typeval *rettv));
443 static void f_matchstr __ARGS((typeval *argvars, typeval *rettv)); 441 static void f_matchstr __ARGS((typeval *argvars, typeval *rettv));
444 static void f_mode __ARGS((typeval *argvars, typeval *rettv)); 442 static void f_mode __ARGS((typeval *argvars, typeval *rettv));
445 static void f_nextnonblank __ARGS((typeval *argvars, typeval *rettv)); 443 static void f_nextnonblank __ARGS((typeval *argvars, typeval *rettv));
446 static void f_nr2char __ARGS((typeval *argvars, typeval *rettv)); 444 static void f_nr2char __ARGS((typeval *argvars, typeval *rettv));
447 static void f_prevnonblank __ARGS((typeval *argvars, typeval *rettv)); 445 static void f_prevnonblank __ARGS((typeval *argvars, typeval *rettv));
448 static void f_setbufvar __ARGS((typeval *argvars, typeval *rettv));
449 static void f_setcmdpos __ARGS((typeval *argvars, typeval *rettv));
450 static void f_setwinvar __ARGS((typeval *argvars, typeval *rettv));
451 static void f_remove __ARGS((typeval *argvars, typeval *rettv));
452 static void f_rename __ARGS((typeval *argvars, typeval *rettv));
453 static void f_repeat __ARGS((typeval *argvars, typeval *rettv));
454 static void f_resolve __ARGS((typeval *argvars, typeval *rettv));
455 static void f_search __ARGS((typeval *argvars, typeval *rettv));
456 static void f_searchpair __ARGS((typeval *argvars, typeval *rettv));
457 static int get_search_arg __ARGS((typeval *varp, int *flagsp));
458 static void f_remote_expr __ARGS((typeval *argvars, typeval *rettv)); 446 static void f_remote_expr __ARGS((typeval *argvars, typeval *rettv));
459 static void f_remote_foreground __ARGS((typeval *argvars, typeval *rettv)); 447 static void f_remote_foreground __ARGS((typeval *argvars, typeval *rettv));
460 static void f_remote_peek __ARGS((typeval *argvars, typeval *rettv)); 448 static void f_remote_peek __ARGS((typeval *argvars, typeval *rettv));
461 static void f_remote_read __ARGS((typeval *argvars, typeval *rettv)); 449 static void f_remote_read __ARGS((typeval *argvars, typeval *rettv));
462 static void f_remote_send __ARGS((typeval *argvars, typeval *rettv)); 450 static void f_remote_send __ARGS((typeval *argvars, typeval *rettv));
451 static void f_remove __ARGS((typeval *argvars, typeval *rettv));
452 static void f_rename __ARGS((typeval *argvars, typeval *rettv));
453 static void f_repeat __ARGS((typeval *argvars, typeval *rettv));
454 static void f_resolve __ARGS((typeval *argvars, typeval *rettv));
455 static void f_reverse __ARGS((typeval *argvars, typeval *rettv));
456 static void f_search __ARGS((typeval *argvars, typeval *rettv));
457 static void f_searchpair __ARGS((typeval *argvars, typeval *rettv));
463 static void f_server2client __ARGS((typeval *argvars, typeval *rettv)); 458 static void f_server2client __ARGS((typeval *argvars, typeval *rettv));
464 static void f_serverlist __ARGS((typeval *argvars, typeval *rettv)); 459 static void f_serverlist __ARGS((typeval *argvars, typeval *rettv));
460 static void f_setbufvar __ARGS((typeval *argvars, typeval *rettv));
461 static void f_setcmdpos __ARGS((typeval *argvars, typeval *rettv));
465 static void f_setline __ARGS((typeval *argvars, typeval *rettv)); 462 static void f_setline __ARGS((typeval *argvars, typeval *rettv));
466 static void f_setreg __ARGS((typeval *argvars, typeval *rettv)); 463 static void f_setreg __ARGS((typeval *argvars, typeval *rettv));
464 static void f_setwinvar __ARGS((typeval *argvars, typeval *rettv));
467 static void f_simplify __ARGS((typeval *argvars, typeval *rettv)); 465 static void f_simplify __ARGS((typeval *argvars, typeval *rettv));
468 static void find_some_match __ARGS((typeval *argvars, typeval *rettv, int start)); 466 static void f_sort __ARGS((typeval *argvars, typeval *rettv));
467 static void f_str2list __ARGS((typeval *argvars, typeval *rettv));
468 #ifdef HAVE_STRFTIME
469 static void f_strftime __ARGS((typeval *argvars, typeval *rettv)); 469 static void f_strftime __ARGS((typeval *argvars, typeval *rettv));
470 #endif
470 static void f_stridx __ARGS((typeval *argvars, typeval *rettv)); 471 static void f_stridx __ARGS((typeval *argvars, typeval *rettv));
471 static void f_string __ARGS((typeval *argvars, typeval *rettv)); 472 static void f_string __ARGS((typeval *argvars, typeval *rettv));
472 static void f_strlen __ARGS((typeval *argvars, typeval *rettv)); 473 static void f_strlen __ARGS((typeval *argvars, typeval *rettv));
473 static void f_strpart __ARGS((typeval *argvars, typeval *rettv)); 474 static void f_strpart __ARGS((typeval *argvars, typeval *rettv));
474 static void f_strridx __ARGS((typeval *argvars, typeval *rettv)); 475 static void f_strridx __ARGS((typeval *argvars, typeval *rettv));
475 static void f_strtrans __ARGS((typeval *argvars, typeval *rettv)); 476 static void f_strtrans __ARGS((typeval *argvars, typeval *rettv));
477 static void f_submatch __ARGS((typeval *argvars, typeval *rettv));
478 static void f_substitute __ARGS((typeval *argvars, typeval *rettv));
476 static void f_synID __ARGS((typeval *argvars, typeval *rettv)); 479 static void f_synID __ARGS((typeval *argvars, typeval *rettv));
477 static void f_synIDattr __ARGS((typeval *argvars, typeval *rettv)); 480 static void f_synIDattr __ARGS((typeval *argvars, typeval *rettv));
478 static void f_synIDtrans __ARGS((typeval *argvars, typeval *rettv)); 481 static void f_synIDtrans __ARGS((typeval *argvars, typeval *rettv));
479 static void f_system __ARGS((typeval *argvars, typeval *rettv)); 482 static void f_system __ARGS((typeval *argvars, typeval *rettv));
480 static void f_submatch __ARGS((typeval *argvars, typeval *rettv));
481 static void f_substitute __ARGS((typeval *argvars, typeval *rettv));
482 static void f_tempname __ARGS((typeval *argvars, typeval *rettv)); 483 static void f_tempname __ARGS((typeval *argvars, typeval *rettv));
483 static void f_tolower __ARGS((typeval *argvars, typeval *rettv)); 484 static void f_tolower __ARGS((typeval *argvars, typeval *rettv));
484 static void f_toupper __ARGS((typeval *argvars, typeval *rettv)); 485 static void f_toupper __ARGS((typeval *argvars, typeval *rettv));
485 static void f_tr __ARGS((typeval *argvars, typeval *rettv)); 486 static void f_tr __ARGS((typeval *argvars, typeval *rettv));
486 static void f_type __ARGS((typeval *argvars, typeval *rettv)); 487 static void f_type __ARGS((typeval *argvars, typeval *rettv));
491 static void f_winheight __ARGS((typeval *argvars, typeval *rettv)); 492 static void f_winheight __ARGS((typeval *argvars, typeval *rettv));
492 static void f_winline __ARGS((typeval *argvars, typeval *rettv)); 493 static void f_winline __ARGS((typeval *argvars, typeval *rettv));
493 static void f_winnr __ARGS((typeval *argvars, typeval *rettv)); 494 static void f_winnr __ARGS((typeval *argvars, typeval *rettv));
494 static void f_winrestcmd __ARGS((typeval *argvars, typeval *rettv)); 495 static void f_winrestcmd __ARGS((typeval *argvars, typeval *rettv));
495 static void f_winwidth __ARGS((typeval *argvars, typeval *rettv)); 496 static void f_winwidth __ARGS((typeval *argvars, typeval *rettv));
497
496 static win_T *find_win_by_nr __ARGS((typeval *vp)); 498 static win_T *find_win_by_nr __ARGS((typeval *vp));
497 static pos_T *var2fpos __ARGS((typeval *varp, int lnum)); 499 static pos_T *var2fpos __ARGS((typeval *varp, int lnum));
498 static int get_env_len __ARGS((char_u **arg)); 500 static int get_env_len __ARGS((char_u **arg));
499 static int get_id_len __ARGS((char_u **arg)); 501 static int get_id_len __ARGS((char_u **arg));
500 static int get_func_len __ARGS((char_u **arg, char_u **alias, int evaluate)); 502 static int get_func_len __ARGS((char_u **arg, char_u **alias, int evaluate));
3249 item = item->li_next; 3251 item = item->li_next;
3250 } 3252 }
3251 clear_tv(rettv); 3253 clear_tv(rettv);
3252 rettv->v_type = VAR_LIST; 3254 rettv->v_type = VAR_LIST;
3253 rettv->vval.v_list = l; 3255 rettv->vval.v_list = l;
3256 ++l->lv_refcount;
3254 } 3257 }
3255 else 3258 else
3256 { 3259 {
3257 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv, 3260 copy_tv(&list_find(rettv->vval.v_list, n1)->li_tv,
3258 &var1); 3261 &var1);
4141 char f_max_argc; /* maximal number of arguments */ 4144 char f_max_argc; /* maximal number of arguments */
4142 void (*f_func) __ARGS((typeval *args, typeval *rvar)); 4145 void (*f_func) __ARGS((typeval *args, typeval *rvar));
4143 /* implemenation of function */ 4146 /* implemenation of function */
4144 } functions[] = 4147 } functions[] =
4145 { 4148 {
4149 {"add", 2, 2, f_add},
4146 {"append", 2, 2, f_append}, 4150 {"append", 2, 2, f_append},
4147 {"argc", 0, 0, f_argc}, 4151 {"argc", 0, 0, f_argc},
4148 {"argidx", 0, 0, f_argidx}, 4152 {"argidx", 0, 0, f_argidx},
4149 {"argv", 1, 1, f_argv}, 4153 {"argv", 1, 1, f_argv},
4150 {"browse", 4, 4, f_browse}, 4154 {"browse", 4, 4, f_browse},
4191 {"foldlevel", 1, 1, f_foldlevel}, 4195 {"foldlevel", 1, 1, f_foldlevel},
4192 {"foldtext", 0, 0, f_foldtext}, 4196 {"foldtext", 0, 0, f_foldtext},
4193 {"foldtextresult", 1, 1, f_foldtextresult}, 4197 {"foldtextresult", 1, 1, f_foldtextresult},
4194 {"foreground", 0, 0, f_foreground}, 4198 {"foreground", 0, 0, f_foreground},
4195 {"function", 1, 1, f_function}, 4199 {"function", 1, 1, f_function},
4200 {"get", 2, 3, f_get},
4196 {"getbufvar", 2, 2, f_getbufvar}, 4201 {"getbufvar", 2, 2, f_getbufvar},
4197 {"getchar", 0, 1, f_getchar}, 4202 {"getchar", 0, 1, f_getchar},
4198 {"getcharmod", 0, 0, f_getcharmod}, 4203 {"getcharmod", 0, 0, f_getcharmod},
4199 {"getcmdline", 0, 0, f_getcmdline}, 4204 {"getcmdline", 0, 0, f_getcmdline},
4200 {"getcmdpos", 0, 0, f_getcmdpos}, 4205 {"getcmdpos", 0, 0, f_getcmdpos},
4202 {"getfontname", 0, 1, f_getfontname}, 4207 {"getfontname", 0, 1, f_getfontname},
4203 {"getfperm", 1, 1, f_getfperm}, 4208 {"getfperm", 1, 1, f_getfperm},
4204 {"getfsize", 1, 1, f_getfsize}, 4209 {"getfsize", 1, 1, f_getfsize},
4205 {"getftime", 1, 1, f_getftime}, 4210 {"getftime", 1, 1, f_getftime},
4206 {"getftype", 1, 1, f_getftype}, 4211 {"getftype", 1, 1, f_getftype},
4207 {"getline", 1, 1, f_getline}, 4212 {"getline", 1, 2, f_getline},
4208 {"getreg", 0, 1, f_getreg}, 4213 {"getreg", 0, 1, f_getreg},
4209 {"getregtype", 0, 1, f_getregtype}, 4214 {"getregtype", 0, 1, f_getregtype},
4210 {"getwinposx", 0, 0, f_getwinposx}, 4215 {"getwinposx", 0, 0, f_getwinposx},
4211 {"getwinposy", 0, 0, f_getwinposy}, 4216 {"getwinposy", 0, 0, f_getwinposy},
4212 {"getwinvar", 2, 2, f_getwinvar}, 4217 {"getwinvar", 2, 2, f_getwinvar},
4257 {"remote_send", 2, 3, f_remote_send}, 4262 {"remote_send", 2, 3, f_remote_send},
4258 {"remove", 2, 3, f_remove}, 4263 {"remove", 2, 3, f_remove},
4259 {"rename", 2, 2, f_rename}, 4264 {"rename", 2, 2, f_rename},
4260 {"repeat", 2, 2, f_repeat}, 4265 {"repeat", 2, 2, f_repeat},
4261 {"resolve", 1, 1, f_resolve}, 4266 {"resolve", 1, 1, f_resolve},
4267 {"reverse", 1, 1, f_reverse},
4262 {"search", 1, 2, f_search}, 4268 {"search", 1, 2, f_search},
4263 {"searchpair", 3, 5, f_searchpair}, 4269 {"searchpair", 3, 5, f_searchpair},
4264 {"server2client", 2, 2, f_server2client}, 4270 {"server2client", 2, 2, f_server2client},
4265 {"serverlist", 0, 0, f_serverlist}, 4271 {"serverlist", 0, 0, f_serverlist},
4266 {"setbufvar", 3, 3, f_setbufvar}, 4272 {"setbufvar", 3, 3, f_setbufvar},
4267 {"setcmdpos", 1, 1, f_setcmdpos}, 4273 {"setcmdpos", 1, 1, f_setcmdpos},
4268 {"setline", 2, 2, f_setline}, 4274 {"setline", 2, 2, f_setline},
4269 {"setreg", 2, 3, f_setreg}, 4275 {"setreg", 2, 3, f_setreg},
4270 {"setwinvar", 3, 3, f_setwinvar}, 4276 {"setwinvar", 3, 3, f_setwinvar},
4271 {"simplify", 1, 1, f_simplify}, 4277 {"simplify", 1, 1, f_simplify},
4278 {"sort", 1, 2, f_sort},
4279 {"str2list", 1, 2, f_str2list},
4272 #ifdef HAVE_STRFTIME 4280 #ifdef HAVE_STRFTIME
4273 {"strftime", 1, 2, f_strftime}, 4281 {"strftime", 1, 2, f_strftime},
4274 #endif 4282 #endif
4275 {"stridx", 2, 2, f_stridx}, 4283 {"stridx", 2, 2, f_stridx},
4276 {"string", 1, 1, f_string}, 4284 {"string", 1, 1, f_string},
4667 /********************************************* 4675 /*********************************************
4668 * Implementation of the built-in functions 4676 * Implementation of the built-in functions
4669 */ 4677 */
4670 4678
4671 /* 4679 /*
4672 * "append(lnum, string)" function 4680 * "add(list, item)" function
4673 * or "append(list, item)" function 4681 */
4674 */ 4682 static void
4675 static void 4683 f_add(argvars, rettv)
4676 f_append(argvars, rettv) 4684 typeval *argvars;
4677 typeval *argvars; 4685 typeval *rettv;
4678 typeval *rettv; 4686 {
4679 {
4680 long lnum;
4681 listvar *l; 4687 listvar *l;
4682 4688
4683 rettv->vval.v_number = 1; /* Default: Failed */ 4689 rettv->vval.v_number = 1; /* Default: Failed */
4684 if (argvars[0].v_type == VAR_LIST) 4690 if (argvars[0].v_type == VAR_LIST)
4685 { 4691 {
4686 l = argvars[0].vval.v_list; 4692 l = argvars[0].vval.v_list;
4687 if (l != NULL && list_append_tv(l, &argvars[1]) == OK) 4693 if (l != NULL && list_append_tv(l, &argvars[1]) == OK)
4688 {
4689 ++l->lv_refcount;
4690 copy_tv(&argvars[0], rettv); 4694 copy_tv(&argvars[0], rettv);
4691 }
4692 } 4695 }
4693 else 4696 else
4694 { 4697 EMSG(_(e_listreq));
4695 lnum = get_tv_lnum(argvars); 4698 }
4696 if (lnum >= 0 4699
4697 && lnum <= curbuf->b_ml.ml_line_count 4700 /*
4698 && u_save(lnum, lnum + 1) == OK) 4701 * "append(lnum, string/list)" function
4699 { 4702 */
4700 ml_append(lnum, get_tv_string(&argvars[1]), (colnr_T)0, FALSE); 4703 static void
4701 if (curwin->w_cursor.lnum > lnum) 4704 f_append(argvars, rettv)
4702 ++curwin->w_cursor.lnum; 4705 typeval *argvars;
4703 appended_lines_mark(lnum, 1L); 4706 typeval *rettv;
4704 rettv->vval.v_number = 0; 4707 {
4705 } 4708 long lnum;
4709 listvar *l = NULL;
4710 listitem *li = NULL;
4711 typeval *tv;
4712 long added = 0;
4713
4714 rettv->vval.v_number = 1; /* Default: Failed */
4715 lnum = get_tv_lnum(argvars);
4716 if (lnum >= 0
4717 && lnum <= curbuf->b_ml.ml_line_count
4718 && u_save(lnum, lnum + 1) == OK)
4719 {
4720 if (argvars[1].v_type == VAR_LIST)
4721 {
4722 l = argvars[1].vval.v_list;
4723 if (l == NULL)
4724 return;
4725 li = l->lv_first;
4726 }
4727 for (;;)
4728 {
4729 if (l == NULL)
4730 tv = &argvars[1]; /* append a string */
4731 else if (li == NULL)
4732 break; /* end of list */
4733 else
4734 tv = &li->li_tv; /* append item from list */
4735 ml_append(lnum + added, get_tv_string(tv), (colnr_T)0, FALSE);
4736 ++added;
4737 if (l == NULL)
4738 break;
4739 li = li->li_next;
4740 }
4741
4742 appended_lines_mark(lnum, added);
4743 if (curwin->w_cursor.lnum > lnum)
4744 curwin->w_cursor.lnum += added;
4745 rettv->vval.v_number = 0; /* Success */
4706 } 4746 }
4707 } 4747 }
4708 4748
4709 /* 4749 /*
4710 * "argc()" function 4750 * "argc()" function
4802 rettv->vval.v_string = NULL; 4842 rettv->vval.v_string = NULL;
4803 #endif 4843 #endif
4804 rettv->v_type = VAR_STRING; 4844 rettv->v_type = VAR_STRING;
4805 } 4845 }
4806 4846
4847 static buf_T *find_buffer __ARGS((typeval *avar));
4848
4807 /* 4849 /*
4808 * Find a buffer by number or exact name. 4850 * Find a buffer by number or exact name.
4809 */ 4851 */
4810 static buf_T * 4852 static buf_T *
4811 find_buffer(avar) 4853 find_buffer(avar)
4872 buf_T *buf; 4914 buf_T *buf;
4873 4915
4874 buf = find_buffer(&argvars[0]); 4916 buf = find_buffer(&argvars[0]);
4875 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL); 4917 rettv->vval.v_number = (buf != NULL && buf->b_ml.ml_mfp != NULL);
4876 } 4918 }
4919
4920 static buf_T *get_buf_tv __ARGS((typeval *tv));
4877 4921
4878 /* 4922 /*
4879 * Get buffer by number or pattern. 4923 * Get buffer by number or pattern.
4880 */ 4924 */
4881 static buf_T * 4925 static buf_T *
5721 ++retval; 5765 ++retval;
5722 } 5766 }
5723 rettv->vval.v_number = retval; 5767 rettv->vval.v_number = retval;
5724 } 5768 }
5725 5769
5726 /* 5770 static void findfilendir __ARGS((typeval *argvars, typeval *rettv, int dir));
5727 * "finddir({fname}[, {path}[, {count}]])" function 5771
5728 */ 5772 static void
5729 static void 5773 findfilendir(argvars, rettv, dir)
5730 f_finddir(argvars, rettv)
5731 typeval *argvars;
5732 typeval *rettv;
5733 {
5734 f_findfilendir(argvars, rettv, TRUE);
5735 }
5736
5737 /*
5738 * "findfile({fname}[, {path}[, {count}]])" function
5739 */
5740 static void
5741 f_findfile(argvars, rettv)
5742 typeval *argvars;
5743 typeval *rettv;
5744 {
5745 f_findfilendir(argvars, rettv, FALSE);
5746 }
5747
5748 static void
5749 f_findfilendir(argvars, rettv, dir)
5750 typeval *argvars; 5774 typeval *argvars;
5751 typeval *rettv; 5775 typeval *rettv;
5752 int dir; 5776 int dir;
5753 { 5777 {
5754 #ifdef FEAT_SEARCHPATH 5778 #ifdef FEAT_SEARCHPATH
5787 #endif 5811 #endif
5788 rettv->v_type = VAR_STRING; 5812 rettv->v_type = VAR_STRING;
5789 } 5813 }
5790 5814
5791 /* 5815 /*
5816 * "finddir({fname}[, {path}[, {count}]])" function
5817 */
5818 static void
5819 f_finddir(argvars, rettv)
5820 typeval *argvars;
5821 typeval *rettv;
5822 {
5823 findfilendir(argvars, rettv, TRUE);
5824 }
5825
5826 /*
5827 * "findfile({fname}[, {path}[, {count}]])" function
5828 */
5829 static void
5830 f_findfile(argvars, rettv)
5831 typeval *argvars;
5832 typeval *rettv;
5833 {
5834 findfilendir(argvars, rettv, FALSE);
5835 }
5836
5837 /*
5792 * "fnamemodify({fname}, {mods})" function 5838 * "fnamemodify({fname}, {mods})" function
5793 */ 5839 */
5794 static void 5840 static void
5795 f_fnamemodify(argvars, rettv) 5841 f_fnamemodify(argvars, rettv)
5796 typeval *argvars; 5842 typeval *argvars;
5815 else 5861 else
5816 rettv->vval.v_string = vim_strnsave(fname, len); 5862 rettv->vval.v_string = vim_strnsave(fname, len);
5817 vim_free(fbuf); 5863 vim_free(fbuf);
5818 } 5864 }
5819 5865
5820 /* 5866 static void foldclosed_both __ARGS((typeval *argvars, typeval *rettv, int end));
5821 * "foldclosed()" function
5822 */
5823 static void
5824 f_foldclosed(argvars, rettv)
5825 typeval *argvars;
5826 typeval *rettv;
5827 {
5828 foldclosed_both(argvars, rettv, FALSE);
5829 }
5830
5831 /*
5832 * "foldclosedend()" function
5833 */
5834 static void
5835 f_foldclosedend(argvars, rettv)
5836 typeval *argvars;
5837 typeval *rettv;
5838 {
5839 foldclosed_both(argvars, rettv, TRUE);
5840 }
5841 5867
5842 /* 5868 /*
5843 * "foldclosed()" function 5869 * "foldclosed()" function
5844 */ 5870 */
5845 static void 5871 static void
5864 return; 5890 return;
5865 } 5891 }
5866 } 5892 }
5867 #endif 5893 #endif
5868 rettv->vval.v_number = -1; 5894 rettv->vval.v_number = -1;
5895 }
5896
5897 /*
5898 * "foldclosed()" function
5899 */
5900 static void
5901 f_foldclosed(argvars, rettv)
5902 typeval *argvars;
5903 typeval *rettv;
5904 {
5905 foldclosed_both(argvars, rettv, FALSE);
5906 }
5907
5908 /*
5909 * "foldclosedend()" function
5910 */
5911 static void
5912 f_foldclosedend(argvars, rettv)
5913 typeval *argvars;
5914 typeval *rettv;
5915 {
5916 foldclosed_both(argvars, rettv, TRUE);
5869 } 5917 }
5870 5918
5871 /* 5919 /*
5872 * "foldlevel()" function 5920 * "foldlevel()" function
5873 */ 5921 */
6026 else 6074 else
6027 { 6075 {
6028 rettv->vval.v_string = vim_strsave(s); 6076 rettv->vval.v_string = vim_strsave(s);
6029 rettv->v_type = VAR_FUNC; 6077 rettv->v_type = VAR_FUNC;
6030 } 6078 }
6079 }
6080
6081 /*
6082 * "get()" function
6083 */
6084 static void
6085 f_get(argvars, rettv)
6086 typeval *argvars;
6087 typeval *rettv;
6088 {
6089 listitem *item;
6090 listvar *l;
6091
6092 if (argvars[0].v_type != VAR_LIST)
6093 EMSG2(_(e_listarg), "get()");
6094 else if ((l = argvars[0].vval.v_list) != NULL)
6095 {
6096 item = list_find(l, get_tv_number(&argvars[1]));
6097 if (item == NULL)
6098 {
6099 if (argvars[2].v_type == VAR_UNKNOWN)
6100 rettv->vval.v_number = 0;
6101 else
6102 copy_tv(&argvars[2], rettv);
6103 }
6104 else
6105 copy_tv(&item->li_tv, rettv);
6106 }
6107 }
6108
6109 /*
6110 * "getbufvar()" function
6111 */
6112 static void
6113 f_getbufvar(argvars, rettv)
6114 typeval *argvars;
6115 typeval *rettv;
6116 {
6117 buf_T *buf;
6118 buf_T *save_curbuf;
6119 char_u *varname;
6120 VAR v;
6121
6122 ++emsg_off;
6123 buf = get_buf_tv(&argvars[0]);
6124 varname = get_tv_string(&argvars[1]);
6125
6126 rettv->v_type = VAR_STRING;
6127 rettv->vval.v_string = NULL;
6128
6129 if (buf != NULL && varname != NULL)
6130 {
6131 if (*varname == '&') /* buffer-local-option */
6132 {
6133 /* set curbuf to be our buf, temporarily */
6134 save_curbuf = curbuf;
6135 curbuf = buf;
6136
6137 get_option_tv(&varname, rettv, TRUE);
6138
6139 /* restore previous notion of curbuf */
6140 curbuf = save_curbuf;
6141 }
6142 else
6143 {
6144 /* look up the variable */
6145 v = find_var_in_ga(&buf->b_vars, varname);
6146 if (v != NULL)
6147 copy_tv(&v->tv, rettv);
6148 }
6149 }
6150
6151 --emsg_off;
6031 } 6152 }
6032 6153
6033 /* 6154 /*
6034 * "getchar()" function 6155 * "getchar()" function
6035 */ 6156 */
6121 f_getcmdpos(argvars, rettv) 6242 f_getcmdpos(argvars, rettv)
6122 typeval *argvars; 6243 typeval *argvars;
6123 typeval *rettv; 6244 typeval *rettv;
6124 { 6245 {
6125 rettv->vval.v_number = get_cmdline_pos() + 1; 6246 rettv->vval.v_number = get_cmdline_pos() + 1;
6126 }
6127
6128 /*
6129 * "getbufvar()" function
6130 */
6131 static void
6132 f_getbufvar(argvars, rettv)
6133 typeval *argvars;
6134 typeval *rettv;
6135 {
6136 buf_T *buf;
6137 buf_T *save_curbuf;
6138 char_u *varname;
6139 VAR v;
6140
6141 ++emsg_off;
6142 buf = get_buf_tv(&argvars[0]);
6143 varname = get_tv_string(&argvars[1]);
6144
6145 rettv->v_type = VAR_STRING;
6146 rettv->vval.v_string = NULL;
6147
6148 if (buf != NULL && varname != NULL)
6149 {
6150 if (*varname == '&') /* buffer-local-option */
6151 {
6152 /* set curbuf to be our buf, temporarily */
6153 save_curbuf = curbuf;
6154 curbuf = buf;
6155
6156 get_option_tv(&varname, rettv, TRUE);
6157
6158 /* restore previous notion of curbuf */
6159 curbuf = save_curbuf;
6160 }
6161 else
6162 {
6163 /* look up the variable */
6164 v = find_var_in_ga(&buf->b_vars, varname);
6165 if (v != NULL)
6166 copy_tv(&v->tv, rettv);
6167 }
6168 }
6169
6170 --emsg_off;
6171 } 6247 }
6172 6248
6173 /* 6249 /*
6174 * "getcwd()" function 6250 * "getcwd()" function
6175 */ 6251 */
6389 } 6465 }
6390 rettv->vval.v_string = type; 6466 rettv->vval.v_string = type;
6391 } 6467 }
6392 6468
6393 /* 6469 /*
6470 * "getline(lnum)" function
6471 */
6472 static void
6473 f_getline(argvars, rettv)
6474 typeval *argvars;
6475 typeval *rettv;
6476 {
6477 linenr_T lnum;
6478 linenr_T end;
6479 char_u *p;
6480 listvar *l;
6481 listitem *li;
6482
6483 lnum = get_tv_lnum(argvars);
6484
6485 if (argvars[1].v_type == VAR_UNKNOWN)
6486 {
6487 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
6488 p = ml_get(lnum);
6489 else
6490 p = (char_u *)"";
6491
6492 rettv->v_type = VAR_STRING;
6493 rettv->vval.v_string = vim_strsave(p);
6494 }
6495 else
6496 {
6497 end = get_tv_lnum(&argvars[1]);
6498 if (end < lnum)
6499 {
6500 EMSG(_(e_invrange));
6501 rettv->vval.v_number = 0;
6502 }
6503 else
6504 {
6505 l = list_alloc();
6506 if (l != NULL)
6507 {
6508 if (lnum < 1)
6509 lnum = 1;
6510 if (end > curbuf->b_ml.ml_line_count)
6511 end = curbuf->b_ml.ml_line_count;
6512 while (lnum <= end)
6513 {
6514 li = listitem_alloc();
6515 if (li == NULL)
6516 break;
6517 list_append(l, li);
6518 li->li_tv.v_type = VAR_STRING;
6519 li->li_tv.vval.v_string = vim_strsave(ml_get(lnum++));
6520 }
6521 rettv->vval.v_list = l;
6522 rettv->v_type = VAR_LIST;
6523 ++l->lv_refcount;
6524 }
6525 }
6526 }
6527 }
6528
6529 /*
6394 * "getreg()" function 6530 * "getreg()" function
6395 */ 6531 */
6396 static void 6532 static void
6397 f_getreg(argvars, rettv) 6533 f_getreg(argvars, rettv)
6398 typeval *argvars; 6534 typeval *argvars;
6449 break; 6585 break;
6450 #endif 6586 #endif
6451 } 6587 }
6452 rettv->v_type = VAR_STRING; 6588 rettv->v_type = VAR_STRING;
6453 rettv->vval.v_string = vim_strsave(buf); 6589 rettv->vval.v_string = vim_strsave(buf);
6454 }
6455
6456 /*
6457 * "getline(lnum)" function
6458 */
6459 static void
6460 f_getline(argvars, rettv)
6461 typeval *argvars;
6462 typeval *rettv;
6463 {
6464 linenr_T lnum;
6465 char_u *p;
6466
6467 lnum = get_tv_lnum(argvars);
6468
6469 if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
6470 p = ml_get(lnum);
6471 else
6472 p = (char_u *)"";
6473
6474 rettv->v_type = VAR_STRING;
6475 rettv->vval.v_string = vim_strsave(p);
6476 } 6590 }
6477 6591
6478 /* 6592 /*
6479 * "getwinposx()" function 6593 * "getwinposx()" function
6480 */ 6594 */
7220 i = -1; 7334 i = -1;
7221 rettv->vval.v_number = i; 7335 rettv->vval.v_number = i;
7222 } 7336 }
7223 7337
7224 /* 7338 /*
7339 * "highlightID(name)" function
7340 */
7341 static void
7342 f_hlID(argvars, rettv)
7343 typeval *argvars;
7344 typeval *rettv;
7345 {
7346 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0]));
7347 }
7348
7349 /*
7225 * "highlight_exists()" function 7350 * "highlight_exists()" function
7226 */ 7351 */
7227 static void 7352 static void
7228 f_hlexists(argvars, rettv) 7353 f_hlexists(argvars, rettv)
7229 typeval *argvars; 7354 typeval *argvars;
7230 typeval *rettv; 7355 typeval *rettv;
7231 { 7356 {
7232 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0])); 7357 rettv->vval.v_number = highlight_exists(get_tv_string(&argvars[0]));
7233 }
7234
7235 /*
7236 * "highlightID(name)" function
7237 */
7238 static void
7239 f_hlID(argvars, rettv)
7240 typeval *argvars;
7241 typeval *rettv;
7242 {
7243 rettv->vval.v_number = syn_name2id(get_tv_string(&argvars[0]));
7244 } 7358 }
7245 7359
7246 /* 7360 /*
7247 * "hostname()" function 7361 * "hostname()" function
7248 */ 7362 */
7526 long n; 7640 long n;
7527 listitem *item; 7641 listitem *item;
7528 listvar *l; 7642 listvar *l;
7529 7643
7530 if (argvars[0].v_type != VAR_LIST) 7644 if (argvars[0].v_type != VAR_LIST)
7531 EMSG(_("E999: First argument of insert() must be a list")); 7645 EMSG2(_(e_listarg), "insert()");
7532 else if ((l = argvars[0].vval.v_list) != NULL) 7646 else if ((l = argvars[0].vval.v_list) != NULL)
7533 { 7647 {
7534 if (argvars[2].v_type != VAR_UNKNOWN) 7648 if (argvars[2].v_type != VAR_UNKNOWN)
7535 before = get_tv_number(&argvars[2]); 7649 before = get_tv_number(&argvars[2]);
7536 7650
7599 EMSG(_("E999: Invalid type for len()")); 7713 EMSG(_("E999: Invalid type for len()"));
7600 break; 7714 break;
7601 } 7715 }
7602 } 7716 }
7603 7717
7604 /* 7718 static void libcall_common __ARGS((typeval *argvars, typeval *rettv, int type));
7605 * "libcall()" function
7606 */
7607 static void
7608 f_libcall(argvars, rettv)
7609 typeval *argvars;
7610 typeval *rettv;
7611 {
7612 libcall_common(argvars, rettv, VAR_STRING);
7613 }
7614
7615 /*
7616 * "libcallnr()" function
7617 */
7618 static void
7619 f_libcallnr(argvars, rettv)
7620 typeval *argvars;
7621 typeval *rettv;
7622 {
7623 libcall_common(argvars, rettv, VAR_NUMBER);
7624 }
7625 7719
7626 static void 7720 static void
7627 libcall_common(argvars, rettv, type) 7721 libcall_common(argvars, rettv, type)
7628 typeval *argvars; 7722 typeval *argvars;
7629 typeval *rettv; 7723 typeval *rettv;
7667 } 7761 }
7668 #endif 7762 #endif
7669 } 7763 }
7670 7764
7671 /* 7765 /*
7766 * "libcall()" function
7767 */
7768 static void
7769 f_libcall(argvars, rettv)
7770 typeval *argvars;
7771 typeval *rettv;
7772 {
7773 libcall_common(argvars, rettv, VAR_STRING);
7774 }
7775
7776 /*
7777 * "libcallnr()" function
7778 */
7779 static void
7780 f_libcallnr(argvars, rettv)
7781 typeval *argvars;
7782 typeval *rettv;
7783 {
7784 libcall_common(argvars, rettv, VAR_NUMBER);
7785 }
7786
7787 /*
7672 * "line(string)" function 7788 * "line(string)" function
7673 */ 7789 */
7674 static void 7790 static void
7675 f_line(argvars, rettv) 7791 f_line(argvars, rettv)
7676 typeval *argvars; 7792 typeval *argvars;
7744 typeval *rettv; 7860 typeval *rettv;
7745 { 7861 {
7746 rettv->vval.v_number = (varnumber_T)time(NULL); 7862 rettv->vval.v_number = (varnumber_T)time(NULL);
7747 } 7863 }
7748 7864
7749 /* 7865 static void get_maparg __ARGS((typeval *argvars, typeval *rettv, int exact));
7750 * "maparg()" function
7751 */
7752 static void
7753 f_maparg(argvars, rettv)
7754 typeval *argvars;
7755 typeval *rettv;
7756 {
7757 get_maparg(argvars, rettv, TRUE);
7758 }
7759
7760 /*
7761 * "mapcheck()" function
7762 */
7763 static void
7764 f_mapcheck(argvars, rettv)
7765 typeval *argvars;
7766 typeval *rettv;
7767 {
7768 get_maparg(argvars, rettv, FALSE);
7769 }
7770 7866
7771 static void 7867 static void
7772 get_maparg(argvars, rettv, exact) 7868 get_maparg(argvars, rettv, exact)
7773 typeval *argvars; 7869 typeval *argvars;
7774 typeval *rettv; 7870 typeval *rettv;
7812 rettv->vval.v_string = (char_u *)ga.ga_data; 7908 rettv->vval.v_string = (char_u *)ga.ga_data;
7813 } 7909 }
7814 } 7910 }
7815 7911
7816 /* 7912 /*
7817 * "match()" function 7913 * "maparg()" function
7818 */ 7914 */
7819 static void 7915 static void
7820 f_match(argvars, rettv) 7916 f_maparg(argvars, rettv)
7821 typeval *argvars; 7917 typeval *argvars;
7822 typeval *rettv; 7918 typeval *rettv;
7823 { 7919 {
7824 find_some_match(argvars, rettv, 1); 7920 get_maparg(argvars, rettv, TRUE);
7825 } 7921 }
7826 7922
7827 /* 7923 /*
7828 * "matchend()" function 7924 * "mapcheck()" function
7829 */ 7925 */
7830 static void 7926 static void
7831 f_matchend(argvars, rettv) 7927 f_mapcheck(argvars, rettv)
7832 typeval *argvars; 7928 typeval *argvars;
7833 typeval *rettv; 7929 typeval *rettv;
7834 { 7930 {
7835 find_some_match(argvars, rettv, 0); 7931 get_maparg(argvars, rettv, FALSE);
7836 } 7932 }
7837 7933
7838 /* 7934 static void find_some_match __ARGS((typeval *argvars, typeval *rettv, int start));
7839 * "matchstr()" function
7840 */
7841 static void
7842 f_matchstr(argvars, rettv)
7843 typeval *argvars;
7844 typeval *rettv;
7845 {
7846 find_some_match(argvars, rettv, 2);
7847 }
7848 7935
7849 static void 7936 static void
7850 find_some_match(argvars, rettv, type) 7937 find_some_match(argvars, rettv, type)
7851 typeval *argvars; 7938 typeval *argvars;
7852 typeval *rettv; 7939 typeval *rettv;
7930 theend: 8017 theend:
7931 p_cpo = save_cpo; 8018 p_cpo = save_cpo;
7932 } 8019 }
7933 8020
7934 /* 8021 /*
8022 * "match()" function
8023 */
8024 static void
8025 f_match(argvars, rettv)
8026 typeval *argvars;
8027 typeval *rettv;
8028 {
8029 find_some_match(argvars, rettv, 1);
8030 }
8031
8032 /*
8033 * "matchend()" function
8034 */
8035 static void
8036 f_matchend(argvars, rettv)
8037 typeval *argvars;
8038 typeval *rettv;
8039 {
8040 find_some_match(argvars, rettv, 0);
8041 }
8042
8043 /*
8044 * "matchstr()" function
8045 */
8046 static void
8047 f_matchstr(argvars, rettv)
8048 typeval *argvars;
8049 typeval *rettv;
8050 {
8051 find_some_match(argvars, rettv, 2);
8052 }
8053
8054 /*
7935 * "mode()" function 8055 * "mode()" function
7936 */ 8056 */
7937 /*ARGSUSED*/ 8057 /*ARGSUSED*/
7938 static void 8058 static void
7939 f_mode(argvars, rettv) 8059 f_mode(argvars, rettv)
7970 rettv->vval.v_string = vim_strsave(buf); 8090 rettv->vval.v_string = vim_strsave(buf);
7971 rettv->v_type = VAR_STRING; 8091 rettv->v_type = VAR_STRING;
7972 } 8092 }
7973 8093
7974 /* 8094 /*
8095 * "nextnonblank()" function
8096 */
8097 static void
8098 f_nextnonblank(argvars, rettv)
8099 typeval *argvars;
8100 typeval *rettv;
8101 {
8102 linenr_T lnum;
8103
8104 for (lnum = get_tv_lnum(argvars); ; ++lnum)
8105 {
8106 if (lnum > curbuf->b_ml.ml_line_count)
8107 {
8108 lnum = 0;
8109 break;
8110 }
8111 if (*skipwhite(ml_get(lnum)) != NUL)
8112 break;
8113 }
8114 rettv->vval.v_number = lnum;
8115 }
8116
8117 /*
7975 * "nr2char()" function 8118 * "nr2char()" function
7976 */ 8119 */
7977 static void 8120 static void
7978 f_nr2char(argvars, rettv) 8121 f_nr2char(argvars, rettv)
7979 typeval *argvars; 8122 typeval *argvars;
7990 buf[0] = (char_u)get_tv_number(&argvars[0]); 8133 buf[0] = (char_u)get_tv_number(&argvars[0]);
7991 buf[1] = NUL; 8134 buf[1] = NUL;
7992 } 8135 }
7993 rettv->v_type = VAR_STRING; 8136 rettv->v_type = VAR_STRING;
7994 rettv->vval.v_string = vim_strsave(buf); 8137 rettv->vval.v_string = vim_strsave(buf);
8138 }
8139
8140 /*
8141 * "prevnonblank()" function
8142 */
8143 static void
8144 f_prevnonblank(argvars, rettv)
8145 typeval *argvars;
8146 typeval *rettv;
8147 {
8148 linenr_T lnum;
8149
8150 lnum = get_tv_lnum(argvars);
8151 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count)
8152 lnum = 0;
8153 else
8154 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL)
8155 --lnum;
8156 rettv->vval.v_number = lnum;
8157 }
8158
8159 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
8160 static void make_connection __ARGS((void));
8161 static int check_connection __ARGS((void));
8162
8163 static void
8164 make_connection()
8165 {
8166 if (X_DISPLAY == NULL
8167 # ifdef FEAT_GUI
8168 && !gui.in_use
8169 # endif
8170 )
8171 {
8172 x_force_connect = TRUE;
8173 setup_term_clip();
8174 x_force_connect = FALSE;
8175 }
8176 }
8177
8178 static int
8179 check_connection()
8180 {
8181 make_connection();
8182 if (X_DISPLAY == NULL)
8183 {
8184 EMSG(_("E240: No connection to Vim server"));
8185 return FAIL;
8186 }
8187 return OK;
8188 }
8189 #endif
8190
8191 #ifdef FEAT_CLIENTSERVER
8192 static void remote_common __ARGS((typeval *argvars, typeval *rettv, int expr));
8193
8194 static void
8195 remote_common(argvars, rettv, expr)
8196 typeval *argvars;
8197 typeval *rettv;
8198 int expr;
8199 {
8200 char_u *server_name;
8201 char_u *keys;
8202 char_u *r = NULL;
8203 char_u buf[NUMBUFLEN];
8204 # ifdef WIN32
8205 HWND w;
8206 # else
8207 Window w;
8208 # endif
8209
8210 if (check_restricted() || check_secure())
8211 return;
8212
8213 # ifdef FEAT_X11
8214 if (check_connection() == FAIL)
8215 return;
8216 # endif
8217
8218 server_name = get_tv_string(&argvars[0]);
8219 keys = get_tv_string_buf(&argvars[1], buf);
8220 # ifdef WIN32
8221 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0)
8222 # else
8223 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE)
8224 < 0)
8225 # endif
8226 {
8227 if (r != NULL)
8228 EMSG(r); /* sending worked but evaluation failed */
8229 else
8230 EMSG2(_("E241: Unable to send to %s"), server_name);
8231 return;
8232 }
8233
8234 rettv->vval.v_string = r;
8235
8236 if (argvars[2].v_type != VAR_UNKNOWN)
8237 {
8238 var v;
8239 char_u str[30];
8240
8241 sprintf((char *)str, "0x%x", (unsigned int)w);
8242 v.tv.v_type = VAR_STRING;
8243 v.tv.vval.v_string = vim_strsave(str);
8244 set_var(get_tv_string(&argvars[2]), &v.tv, FALSE);
8245 vim_free(v.tv.vval.v_string);
8246 }
8247 }
8248 #endif
8249
8250 /*
8251 * "remote_expr()" function
8252 */
8253 /*ARGSUSED*/
8254 static void
8255 f_remote_expr(argvars, rettv)
8256 typeval *argvars;
8257 typeval *rettv;
8258 {
8259 rettv->v_type = VAR_STRING;
8260 rettv->vval.v_string = NULL;
8261 #ifdef FEAT_CLIENTSERVER
8262 remote_common(argvars, rettv, TRUE);
8263 #endif
8264 }
8265
8266 /*
8267 * "remote_foreground()" function
8268 */
8269 /*ARGSUSED*/
8270 static void
8271 f_remote_foreground(argvars, rettv)
8272 typeval *argvars;
8273 typeval *rettv;
8274 {
8275 rettv->vval.v_number = 0;
8276 #ifdef FEAT_CLIENTSERVER
8277 # ifdef WIN32
8278 /* On Win32 it's done in this application. */
8279 serverForeground(get_tv_string(&argvars[0]));
8280 # else
8281 /* Send a foreground() expression to the server. */
8282 argvars[1].v_type = VAR_STRING;
8283 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()");
8284 argvars[2].v_type = VAR_UNKNOWN;
8285 remote_common(argvars, rettv, TRUE);
8286 vim_free(argvars[1].vval.v_string);
8287 # endif
8288 #endif
8289 }
8290
8291 /*ARGSUSED*/
8292 static void
8293 f_remote_peek(argvars, rettv)
8294 typeval *argvars;
8295 typeval *rettv;
8296 {
8297 #ifdef FEAT_CLIENTSERVER
8298 var v;
8299 char_u *s = NULL;
8300 # ifdef WIN32
8301 int n = 0;
8302 # endif
8303
8304 if (check_restricted() || check_secure())
8305 {
8306 rettv->vval.v_number = -1;
8307 return;
8308 }
8309 # ifdef WIN32
8310 sscanf(get_tv_string(&argvars[0]), "%x", &n);
8311 if (n == 0)
8312 rettv->vval.v_number = -1;
8313 else
8314 {
8315 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE);
8316 rettv->vval.v_number = (s != NULL);
8317 }
8318 # else
8319 rettv->vval.v_number = 0;
8320 if (check_connection() == FAIL)
8321 return;
8322
8323 rettv->vval.v_number = serverPeekReply(X_DISPLAY,
8324 serverStrToWin(get_tv_string(&argvars[0])), &s);
8325 # endif
8326
8327 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0)
8328 {
8329 v.tv.v_type = VAR_STRING;
8330 v.tv.vval.v_string = vim_strsave(s);
8331 set_var(get_tv_string(&argvars[1]), &v.tv, FALSE);
8332 vim_free(v.tv.vval.v_string);
8333 }
8334 #else
8335 rettv->vval.v_number = -1;
8336 #endif
8337 }
8338
8339 /*ARGSUSED*/
8340 static void
8341 f_remote_read(argvars, rettv)
8342 typeval *argvars;
8343 typeval *rettv;
8344 {
8345 char_u *r = NULL;
8346
8347 #ifdef FEAT_CLIENTSERVER
8348 if (!check_restricted() && !check_secure())
8349 {
8350 # ifdef WIN32
8351 /* The server's HWND is encoded in the 'id' parameter */
8352 int n = 0;
8353
8354 sscanf(get_tv_string(&argvars[0]), "%x", &n);
8355 if (n != 0)
8356 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE);
8357 if (r == NULL)
8358 # else
8359 if (check_connection() == FAIL || serverReadReply(X_DISPLAY,
8360 serverStrToWin(get_tv_string(&argvars[0])), &r, FALSE) < 0)
8361 # endif
8362 EMSG(_("E277: Unable to read a server reply"));
8363 }
8364 #endif
8365 rettv->v_type = VAR_STRING;
8366 rettv->vval.v_string = r;
8367 }
8368
8369 /*
8370 * "remote_send()" function
8371 */
8372 /*ARGSUSED*/
8373 static void
8374 f_remote_send(argvars, rettv)
8375 typeval *argvars;
8376 typeval *rettv;
8377 {
8378 rettv->v_type = VAR_STRING;
8379 rettv->vval.v_string = NULL;
8380 #ifdef FEAT_CLIENTSERVER
8381 remote_common(argvars, rettv, FALSE);
8382 #endif
7995 } 8383 }
7996 8384
7997 /* 8385 /*
7998 * "remove({list}, {idx} [, {end}])" function 8386 * "remove({list}, {idx} [, {end}])" function
7999 */ 8387 */
8008 long idx; 8396 long idx;
8009 long end; 8397 long end;
8010 8398
8011 rettv->vval.v_number = 0; 8399 rettv->vval.v_number = 0;
8012 if (argvars[0].v_type != VAR_LIST) 8400 if (argvars[0].v_type != VAR_LIST)
8013 EMSG(_("E999: First argument of remove() must be a list")); 8401 EMSG2(_(e_listarg), "remove()");
8014 else if ((l = argvars[0].vval.v_list) != NULL) 8402 else if ((l = argvars[0].vval.v_list) != NULL)
8015 { 8403 {
8016 idx = get_tv_number(&argvars[1]); 8404 idx = get_tv_number(&argvars[1]);
8017 item = list_find(l, idx); 8405 item = list_find(l, idx);
8018 if (item == NULL) 8406 if (item == NULL)
8331 #endif 8719 #endif
8332 rettv->v_type = VAR_STRING; 8720 rettv->v_type = VAR_STRING;
8333 } 8721 }
8334 8722
8335 /* 8723 /*
8336 * "simplify()" function 8724 * "reverse({list})" function
8337 */ 8725 */
8338 static void 8726 static void
8339 f_simplify(argvars, rettv) 8727 f_reverse(argvars, rettv)
8340 typeval *argvars; 8728 typeval *argvars;
8341 typeval *rettv; 8729 typeval *rettv;
8342 { 8730 {
8343 char_u *p; 8731 listvar *l;
8344 8732 listitem *li, *ni;
8345 p = get_tv_string(&argvars[0]); 8733
8346 rettv->vval.v_string = vim_strsave(p); 8734 rettv->vval.v_number = 0;
8347 simplify_filename(rettv->vval.v_string); /* simplify in place */ 8735 if (argvars[0].v_type != VAR_LIST)
8348 rettv->v_type = VAR_STRING; 8736 EMSG2(_(e_listarg), "reverse()");
8737 else if ((l = argvars[0].vval.v_list) != NULL)
8738 {
8739 li = l->lv_last;
8740 l->lv_first = l->lv_last = li;
8741 while (li != NULL)
8742 {
8743 ni = li->li_prev;
8744 list_append(l, li);
8745 li = ni;
8746 }
8747 rettv->vval.v_list = l;
8748 rettv->v_type = VAR_LIST;
8749 ++l->lv_refcount;
8750 }
8349 } 8751 }
8350 8752
8351 #define SP_NOMOVE 1 /* don't move cursor */ 8753 #define SP_NOMOVE 1 /* don't move cursor */
8352 #define SP_REPEAT 2 /* repeat to find outer pair */ 8754 #define SP_REPEAT 2 /* repeat to find outer pair */
8353 #define SP_RETCOUNT 4 /* return matchcount */ 8755 #define SP_RETCOUNT 4 /* return matchcount */
8354 8756
8355 /* 8757 static int get_search_arg __ARGS((typeval *varp, int *flagsp));
8356 * "search()" function
8357 */
8358 static void
8359 f_search(argvars, rettv)
8360 typeval *argvars;
8361 typeval *rettv;
8362 {
8363 char_u *pat;
8364 pos_T pos;
8365 pos_T save_cursor;
8366 int save_p_ws = p_ws;
8367 int dir;
8368 int flags = 0;
8369
8370 rettv->vval.v_number = 0; /* default: FAIL */
8371
8372 pat = get_tv_string(&argvars[0]);
8373 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */
8374 if (dir == 0)
8375 goto theend;
8376 if ((flags & ~SP_NOMOVE) != 0)
8377 {
8378 EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
8379 goto theend;
8380 }
8381
8382 pos = save_cursor = curwin->w_cursor;
8383 if (searchit(curwin, curbuf, &pos, dir, pat, 1L,
8384 SEARCH_KEEP, RE_SEARCH) != FAIL)
8385 {
8386 rettv->vval.v_number = pos.lnum;
8387 curwin->w_cursor = pos;
8388 /* "/$" will put the cursor after the end of the line, may need to
8389 * correct that here */
8390 check_cursor();
8391 }
8392
8393 /* If 'n' flag is used: restore cursor position. */
8394 if (flags & SP_NOMOVE)
8395 curwin->w_cursor = save_cursor;
8396 theend:
8397 p_ws = save_p_ws;
8398 }
8399
8400 /*
8401 * "searchpair()" function
8402 */
8403 static void
8404 f_searchpair(argvars, rettv)
8405 typeval *argvars;
8406 typeval *rettv;
8407 {
8408 char_u *spat, *mpat, *epat;
8409 char_u *skip;
8410 char_u *pat, *pat2, *pat3;
8411 pos_T pos;
8412 pos_T firstpos;
8413 pos_T save_cursor;
8414 pos_T save_pos;
8415 int save_p_ws = p_ws;
8416 char_u *save_cpo;
8417 int dir;
8418 int flags = 0;
8419 char_u nbuf1[NUMBUFLEN];
8420 char_u nbuf2[NUMBUFLEN];
8421 char_u nbuf3[NUMBUFLEN];
8422 int n;
8423 int r;
8424 int nest = 1;
8425 int err;
8426
8427 rettv->vval.v_number = 0; /* default: FAIL */
8428
8429 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
8430 save_cpo = p_cpo;
8431 p_cpo = (char_u *)"";
8432
8433 /* Get the three pattern arguments: start, middle, end. */
8434 spat = get_tv_string(&argvars[0]);
8435 mpat = get_tv_string_buf(&argvars[1], nbuf1);
8436 epat = get_tv_string_buf(&argvars[2], nbuf2);
8437
8438 /* Make two search patterns: start/end (pat2, for in nested pairs) and
8439 * start/middle/end (pat3, for the top pair). */
8440 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
8441 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
8442 if (pat2 == NULL || pat3 == NULL)
8443 goto theend;
8444 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
8445 if (*mpat == NUL)
8446 STRCPY(pat3, pat2);
8447 else
8448 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
8449 spat, epat, mpat);
8450
8451 /* Handle the optional fourth argument: flags */
8452 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */
8453 if (dir == 0)
8454 goto theend;
8455
8456 /* Optional fifth argument: skip expresion */
8457 if (argvars[3].v_type == VAR_UNKNOWN
8458 || argvars[4].v_type == VAR_UNKNOWN)
8459 skip = (char_u *)"";
8460 else
8461 skip = get_tv_string_buf(&argvars[4], nbuf3);
8462
8463 save_cursor = curwin->w_cursor;
8464 pos = curwin->w_cursor;
8465 firstpos.lnum = 0;
8466 pat = pat3;
8467 for (;;)
8468 {
8469 n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
8470 SEARCH_KEEP, RE_SEARCH);
8471 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos)))
8472 /* didn't find it or found the first match again: FAIL */
8473 break;
8474
8475 if (firstpos.lnum == 0)
8476 firstpos = pos;
8477
8478 /* If the skip pattern matches, ignore this match. */
8479 if (*skip != NUL)
8480 {
8481 save_pos = curwin->w_cursor;
8482 curwin->w_cursor = pos;
8483 r = eval_to_bool(skip, &err, NULL, FALSE);
8484 curwin->w_cursor = save_pos;
8485 if (err)
8486 {
8487 /* Evaluating {skip} caused an error, break here. */
8488 curwin->w_cursor = save_cursor;
8489 rettv->vval.v_number = -1;
8490 break;
8491 }
8492 if (r)
8493 continue;
8494 }
8495
8496 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2))
8497 {
8498 /* Found end when searching backwards or start when searching
8499 * forward: nested pair. */
8500 ++nest;
8501 pat = pat2; /* nested, don't search for middle */
8502 }
8503 else
8504 {
8505 /* Found end when searching forward or start when searching
8506 * backward: end of (nested) pair; or found middle in outer pair. */
8507 if (--nest == 1)
8508 pat = pat3; /* outer level, search for middle */
8509 }
8510
8511 if (nest == 0)
8512 {
8513 /* Found the match: return matchcount or line number. */
8514 if (flags & SP_RETCOUNT)
8515 ++rettv->vval.v_number;
8516 else
8517 rettv->vval.v_number = pos.lnum;
8518 curwin->w_cursor = pos;
8519 if (!(flags & SP_REPEAT))
8520 break;
8521 nest = 1; /* search for next unmatched */
8522 }
8523 }
8524
8525 /* If 'n' flag is used or search failed: restore cursor position. */
8526 if ((flags & SP_NOMOVE) || rettv->vval.v_number == 0)
8527 curwin->w_cursor = save_cursor;
8528
8529 theend:
8530 vim_free(pat2);
8531 vim_free(pat3);
8532 p_ws = save_p_ws;
8533 p_cpo = save_cpo;
8534 }
8535 8758
8536 /* 8759 /*
8537 * Get flags for a search function. 8760 * Get flags for a search function.
8538 * Possibly sets "p_ws". 8761 * Possibly sets "p_ws".
8539 * Returns BACKWARD, FORWARD or zero (for an error). 8762 * Returns BACKWARD, FORWARD or zero (for an error).
8581 } 8804 }
8582 return dir; 8805 return dir;
8583 } 8806 }
8584 8807
8585 /* 8808 /*
8809 * "search()" function
8810 */
8811 static void
8812 f_search(argvars, rettv)
8813 typeval *argvars;
8814 typeval *rettv;
8815 {
8816 char_u *pat;
8817 pos_T pos;
8818 pos_T save_cursor;
8819 int save_p_ws = p_ws;
8820 int dir;
8821 int flags = 0;
8822
8823 rettv->vval.v_number = 0; /* default: FAIL */
8824
8825 pat = get_tv_string(&argvars[0]);
8826 dir = get_search_arg(&argvars[1], &flags); /* may set p_ws */
8827 if (dir == 0)
8828 goto theend;
8829 if ((flags & ~SP_NOMOVE) != 0)
8830 {
8831 EMSG2(_(e_invarg2), get_tv_string(&argvars[1]));
8832 goto theend;
8833 }
8834
8835 pos = save_cursor = curwin->w_cursor;
8836 if (searchit(curwin, curbuf, &pos, dir, pat, 1L,
8837 SEARCH_KEEP, RE_SEARCH) != FAIL)
8838 {
8839 rettv->vval.v_number = pos.lnum;
8840 curwin->w_cursor = pos;
8841 /* "/$" will put the cursor after the end of the line, may need to
8842 * correct that here */
8843 check_cursor();
8844 }
8845
8846 /* If 'n' flag is used: restore cursor position. */
8847 if (flags & SP_NOMOVE)
8848 curwin->w_cursor = save_cursor;
8849 theend:
8850 p_ws = save_p_ws;
8851 }
8852
8853 /*
8854 * "searchpair()" function
8855 */
8856 static void
8857 f_searchpair(argvars, rettv)
8858 typeval *argvars;
8859 typeval *rettv;
8860 {
8861 char_u *spat, *mpat, *epat;
8862 char_u *skip;
8863 char_u *pat, *pat2, *pat3;
8864 pos_T pos;
8865 pos_T firstpos;
8866 pos_T save_cursor;
8867 pos_T save_pos;
8868 int save_p_ws = p_ws;
8869 char_u *save_cpo;
8870 int dir;
8871 int flags = 0;
8872 char_u nbuf1[NUMBUFLEN];
8873 char_u nbuf2[NUMBUFLEN];
8874 char_u nbuf3[NUMBUFLEN];
8875 int n;
8876 int r;
8877 int nest = 1;
8878 int err;
8879
8880 rettv->vval.v_number = 0; /* default: FAIL */
8881
8882 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
8883 save_cpo = p_cpo;
8884 p_cpo = (char_u *)"";
8885
8886 /* Get the three pattern arguments: start, middle, end. */
8887 spat = get_tv_string(&argvars[0]);
8888 mpat = get_tv_string_buf(&argvars[1], nbuf1);
8889 epat = get_tv_string_buf(&argvars[2], nbuf2);
8890
8891 /* Make two search patterns: start/end (pat2, for in nested pairs) and
8892 * start/middle/end (pat3, for the top pair). */
8893 pat2 = alloc((unsigned)(STRLEN(spat) + STRLEN(epat) + 15));
8894 pat3 = alloc((unsigned)(STRLEN(spat) + STRLEN(mpat) + STRLEN(epat) + 23));
8895 if (pat2 == NULL || pat3 == NULL)
8896 goto theend;
8897 sprintf((char *)pat2, "\\(%s\\m\\)\\|\\(%s\\m\\)", spat, epat);
8898 if (*mpat == NUL)
8899 STRCPY(pat3, pat2);
8900 else
8901 sprintf((char *)pat3, "\\(%s\\m\\)\\|\\(%s\\m\\)\\|\\(%s\\m\\)",
8902 spat, epat, mpat);
8903
8904 /* Handle the optional fourth argument: flags */
8905 dir = get_search_arg(&argvars[3], &flags); /* may set p_ws */
8906 if (dir == 0)
8907 goto theend;
8908
8909 /* Optional fifth argument: skip expresion */
8910 if (argvars[3].v_type == VAR_UNKNOWN
8911 || argvars[4].v_type == VAR_UNKNOWN)
8912 skip = (char_u *)"";
8913 else
8914 skip = get_tv_string_buf(&argvars[4], nbuf3);
8915
8916 save_cursor = curwin->w_cursor;
8917 pos = curwin->w_cursor;
8918 firstpos.lnum = 0;
8919 pat = pat3;
8920 for (;;)
8921 {
8922 n = searchit(curwin, curbuf, &pos, dir, pat, 1L,
8923 SEARCH_KEEP, RE_SEARCH);
8924 if (n == FAIL || (firstpos.lnum != 0 && equalpos(pos, firstpos)))
8925 /* didn't find it or found the first match again: FAIL */
8926 break;
8927
8928 if (firstpos.lnum == 0)
8929 firstpos = pos;
8930
8931 /* If the skip pattern matches, ignore this match. */
8932 if (*skip != NUL)
8933 {
8934 save_pos = curwin->w_cursor;
8935 curwin->w_cursor = pos;
8936 r = eval_to_bool(skip, &err, NULL, FALSE);
8937 curwin->w_cursor = save_pos;
8938 if (err)
8939 {
8940 /* Evaluating {skip} caused an error, break here. */
8941 curwin->w_cursor = save_cursor;
8942 rettv->vval.v_number = -1;
8943 break;
8944 }
8945 if (r)
8946 continue;
8947 }
8948
8949 if ((dir == BACKWARD && n == 3) || (dir == FORWARD && n == 2))
8950 {
8951 /* Found end when searching backwards or start when searching
8952 * forward: nested pair. */
8953 ++nest;
8954 pat = pat2; /* nested, don't search for middle */
8955 }
8956 else
8957 {
8958 /* Found end when searching forward or start when searching
8959 * backward: end of (nested) pair; or found middle in outer pair. */
8960 if (--nest == 1)
8961 pat = pat3; /* outer level, search for middle */
8962 }
8963
8964 if (nest == 0)
8965 {
8966 /* Found the match: return matchcount or line number. */
8967 if (flags & SP_RETCOUNT)
8968 ++rettv->vval.v_number;
8969 else
8970 rettv->vval.v_number = pos.lnum;
8971 curwin->w_cursor = pos;
8972 if (!(flags & SP_REPEAT))
8973 break;
8974 nest = 1; /* search for next unmatched */
8975 }
8976 }
8977
8978 /* If 'n' flag is used or search failed: restore cursor position. */
8979 if ((flags & SP_NOMOVE) || rettv->vval.v_number == 0)
8980 curwin->w_cursor = save_cursor;
8981
8982 theend:
8983 vim_free(pat2);
8984 vim_free(pat3);
8985 p_ws = save_p_ws;
8986 p_cpo = save_cpo;
8987 }
8988
8989 /*ARGSUSED*/
8990 static void
8991 f_server2client(argvars, rettv)
8992 typeval *argvars;
8993 typeval *rettv;
8994 {
8995 #ifdef FEAT_CLIENTSERVER
8996 char_u buf[NUMBUFLEN];
8997 char_u *server = get_tv_string(&argvars[0]);
8998 char_u *reply = get_tv_string_buf(&argvars[1], buf);
8999
9000 rettv->vval.v_number = -1;
9001 if (check_restricted() || check_secure())
9002 return;
9003 # ifdef FEAT_X11
9004 if (check_connection() == FAIL)
9005 return;
9006 # endif
9007
9008 if (serverSendReply(server, reply) < 0)
9009 {
9010 EMSG(_("E258: Unable to send to client"));
9011 return;
9012 }
9013 rettv->vval.v_number = 0;
9014 #else
9015 rettv->vval.v_number = -1;
9016 #endif
9017 }
9018
9019 /*ARGSUSED*/
9020 static void
9021 f_serverlist(argvars, rettv)
9022 typeval *argvars;
9023 typeval *rettv;
9024 {
9025 char_u *r = NULL;
9026
9027 #ifdef FEAT_CLIENTSERVER
9028 # ifdef WIN32
9029 r = serverGetVimNames();
9030 # else
9031 make_connection();
9032 if (X_DISPLAY != NULL)
9033 r = serverGetVimNames(X_DISPLAY);
9034 # endif
9035 #endif
9036 rettv->v_type = VAR_STRING;
9037 rettv->vval.v_string = r;
9038 }
9039
9040 /*
8586 * "setbufvar()" function 9041 * "setbufvar()" function
8587 */ 9042 */
8588 /*ARGSUSED*/ 9043 /*ARGSUSED*/
8589 static void 9044 static void
8590 f_setbufvar(argvars, rettv) 9045 f_setbufvar(argvars, rettv)
8809 } 9264 }
8810 --emsg_off; 9265 --emsg_off;
8811 } 9266 }
8812 9267
8813 /* 9268 /*
8814 * "nextnonblank()" function 9269 * "simplify()" function
8815 */ 9270 */
8816 static void 9271 static void
8817 f_nextnonblank(argvars, rettv) 9272 f_simplify(argvars, rettv)
8818 typeval *argvars; 9273 typeval *argvars;
8819 typeval *rettv; 9274 typeval *rettv;
8820 { 9275 {
8821 linenr_T lnum; 9276 char_u *p;
8822 9277
8823 for (lnum = get_tv_lnum(argvars); ; ++lnum) 9278 p = get_tv_string(&argvars[0]);
8824 { 9279 rettv->vval.v_string = vim_strsave(p);
8825 if (lnum > curbuf->b_ml.ml_line_count) 9280 simplify_filename(rettv->vval.v_string); /* simplify in place */
8826 { 9281 rettv->v_type = VAR_STRING;
8827 lnum = 0; 9282 }
8828 break; 9283
8829 } 9284 static int
8830 if (*skipwhite(ml_get(lnum)) != NUL) 9285 #ifdef __BORLANDC__
8831 break; 9286 _RTLENTRYF
8832 } 9287 #endif
8833 rettv->vval.v_number = lnum; 9288 item_compare __ARGS((const void *s1, const void *s2));
8834 } 9289 static int
8835 9290 #ifdef __BORLANDC__
8836 /* 9291 _RTLENTRYF
8837 * "prevnonblank()" function 9292 #endif
8838 */ 9293 item_compare2 __ARGS((const void *s1, const void *s2));
8839 static void 9294
8840 f_prevnonblank(argvars, rettv) 9295 static int item_compare_ic;
8841 typeval *argvars; 9296 static char_u *item_compare_func;
8842 typeval *rettv; 9297 #define ITEM_COMPARE_FAIL 999
8843 { 9298
8844 linenr_T lnum; 9299 /*
8845 9300 * Compare functions for f_sort() below.
8846 lnum = get_tv_lnum(argvars); 9301 */
8847 if (lnum < 1 || lnum > curbuf->b_ml.ml_line_count) 9302 static int
8848 lnum = 0; 9303 #ifdef __BORLANDC__
9304 _RTLENTRYF
9305 #endif
9306 item_compare(s1, s2)
9307 const void *s1;
9308 const void *s2;
9309 {
9310 char_u *p1, *p2;
9311 char_u *tofree1, *tofree2;
9312 int res;
9313 char_u numbuf1[NUMBUFLEN];
9314 char_u numbuf2[NUMBUFLEN];
9315
9316 p1 = tv2string(&(*(listitem **)s1)->li_tv, &tofree1, numbuf1);
9317 p2 = tv2string(&(*(listitem **)s2)->li_tv, &tofree2, numbuf2);
9318 if (item_compare_ic)
9319 res = STRICMP(p1, p2);
8849 else 9320 else
8850 while (lnum >= 1 && *skipwhite(ml_get(lnum)) == NUL) 9321 res = STRCMP(p1, p2);
8851 --lnum; 9322 vim_free(tofree1);
8852 rettv->vval.v_number = lnum; 9323 vim_free(tofree2);
8853 } 9324 return res;
8854
8855 #if defined(FEAT_CLIENTSERVER) && defined(FEAT_X11)
8856 static void make_connection __ARGS((void));
8857 static int check_connection __ARGS((void));
8858
8859 static void
8860 make_connection()
8861 {
8862 if (X_DISPLAY == NULL
8863 # ifdef FEAT_GUI
8864 && !gui.in_use
8865 # endif
8866 )
8867 {
8868 x_force_connect = TRUE;
8869 setup_term_clip();
8870 x_force_connect = FALSE;
8871 }
8872 } 9325 }
8873 9326
8874 static int 9327 static int
8875 check_connection() 9328 #ifdef __BORLANDC__
8876 { 9329 _RTLENTRYF
8877 make_connection(); 9330 #endif
8878 if (X_DISPLAY == NULL) 9331 item_compare2(s1, s2)
8879 { 9332 const void *s1;
8880 EMSG(_("E240: No connection to Vim server")); 9333 const void *s2;
8881 return FAIL; 9334 {
8882 } 9335 int res;
8883 return OK; 9336 typeval rettv;
8884 } 9337 typeval argv[2];
8885 #endif 9338 int dummy;
8886 9339
8887 /*ARGSUSED*/ 9340 /* copy the values (is this really needed?) */
8888 static void 9341 copy_tv(&(*(listitem **)s1)->li_tv, &argv[0]);
8889 f_serverlist(argvars, rettv) 9342 copy_tv(&(*(listitem **)s2)->li_tv, &argv[1]);
8890 typeval *argvars; 9343
8891 typeval *rettv; 9344 rettv.v_type = VAR_UNKNOWN; /* clear_tv() uses this */
8892 { 9345 res = call_func(item_compare_func, STRLEN(item_compare_func),
8893 char_u *r = NULL; 9346 &rettv, 2, argv, 0L, 0L, &dummy, TRUE);
8894 9347 clear_tv(&argv[0]);
8895 #ifdef FEAT_CLIENTSERVER 9348 clear_tv(&argv[1]);
8896 # ifdef WIN32 9349
8897 r = serverGetVimNames(); 9350 if (res == FAIL)
8898 # else 9351 res = ITEM_COMPARE_FAIL;
8899 make_connection(); 9352 else
8900 if (X_DISPLAY != NULL) 9353 res = get_tv_number(&rettv);
8901 r = serverGetVimNames(X_DISPLAY); 9354 clear_tv(&rettv);
8902 # endif 9355 return res;
8903 #endif 9356 }
8904 rettv->v_type = VAR_STRING; 9357
8905 rettv->vval.v_string = r; 9358 /*
8906 } 9359 * "sort({list})" function
8907 9360 */
8908 /*ARGSUSED*/ 9361 static void
8909 static void 9362 f_sort(argvars, rettv)
8910 f_remote_peek(argvars, rettv) 9363 typeval *argvars;
8911 typeval *argvars; 9364 typeval *rettv;
8912 typeval *rettv; 9365 {
8913 { 9366 listvar *l;
8914 #ifdef FEAT_CLIENTSERVER 9367 listitem *li;
8915 var v; 9368 listitem **ptrs;
8916 char_u *s = NULL; 9369 long len;
8917 # ifdef WIN32 9370 long i;
8918 int n = 0; 9371
8919 # endif 9372 rettv->vval.v_number = 0;
8920 9373 if (argvars[0].v_type != VAR_LIST)
8921 if (check_restricted() || check_secure()) 9374 EMSG2(_(e_listarg), "sort()");
8922 { 9375 else
8923 rettv->vval.v_number = -1; 9376 {
9377 l = argvars[0].vval.v_list;
9378 if (l == NULL)
9379 return;
9380 rettv->vval.v_list = l;
9381 rettv->v_type = VAR_LIST;
9382 ++l->lv_refcount;
9383
9384 len = list_len(l);
9385 if (len <= 1)
9386 return; /* short list sorts pretty quickly */
9387
9388 item_compare_ic = FALSE;
9389 item_compare_func = NULL;
9390 if (argvars[1].v_type != VAR_UNKNOWN)
9391 {
9392 if (argvars[1].v_type == VAR_FUNC)
9393 item_compare_func = argvars[0].vval.v_string;
9394 else
9395 {
9396 i = get_tv_number(&argvars[1]);
9397 if (i == 1)
9398 item_compare_ic = TRUE;
9399 else
9400 item_compare_func = get_tv_string(&argvars[1]);
9401 }
9402 }
9403
9404 /* Make an array with each entry pointing to an item in the List. */
9405 ptrs = (listitem **)alloc((int)(len * sizeof(listitem *)));
9406 if (ptrs == NULL)
9407 return;
9408 i = 0;
9409 for (li = l->lv_first; li != NULL; li = li->li_next)
9410 ptrs[i++] = li;
9411
9412 /* test the compare function */
9413 if (item_compare_func != NULL
9414 && item_compare2((void *)&ptrs[0], (void *)&ptrs[1])
9415 == ITEM_COMPARE_FAIL)
9416 EMSG(_("E999: Sort compare function failed"));
9417 else
9418 {
9419 /* Sort the array with item pointers. */
9420 qsort((void *)ptrs, (size_t)len, sizeof(listitem *),
9421 item_compare_func == NULL ? item_compare : item_compare2);
9422
9423 /* Clear the List and append the items in the sorted order. */
9424 l->lv_first = l->lv_last = NULL;
9425 for (i = 0; i < len; ++i)
9426 list_append(l, ptrs[i]);
9427 }
9428
9429 vim_free(ptrs);
9430 }
9431 }
9432
9433 static void
9434 f_str2list(argvars, rettv)
9435 typeval *argvars;
9436 typeval *rettv;
9437 {
9438 char_u *str;
9439 char_u *end;
9440 char_u *pat;
9441 regmatch_T regmatch;
9442 char_u patbuf[NUMBUFLEN];
9443 char_u *save_cpo;
9444 int match;
9445 listitem *ni;
9446 listvar *l;
9447 colnr_T col = 0;
9448
9449 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */
9450 save_cpo = p_cpo;
9451 p_cpo = (char_u *)"";
9452
9453 str = get_tv_string(&argvars[0]);
9454 if (argvars[1].v_type == VAR_UNKNOWN)
9455 pat = (char_u *)"[\\x01- ]\\+";
9456 else
9457 pat = get_tv_string_buf(&argvars[1], patbuf);
9458
9459 l = list_alloc();
9460 if (l == NULL)
8924 return; 9461 return;
8925 } 9462 rettv->v_type = VAR_LIST;
8926 # ifdef WIN32 9463 rettv->vval.v_list = l;
8927 sscanf(get_tv_string(&argvars[0]), "%x", &n); 9464 ++l->lv_refcount;
8928 if (n == 0) 9465
8929 rettv->vval.v_number = -1; 9466 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
8930 else 9467 if (regmatch.regprog != NULL)
8931 { 9468 {
8932 s = serverGetReply((HWND)n, FALSE, FALSE, FALSE); 9469 regmatch.rm_ic = FALSE;
8933 rettv->vval.v_number = (s != NULL); 9470 while (*str != NUL)
8934 } 9471 {
8935 # else 9472 match = vim_regexec_nl(&regmatch, str, col);
8936 rettv->vval.v_number = 0; 9473 if (match)
8937 if (check_connection() == FAIL) 9474 end = regmatch.startp[0];
8938 return; 9475 else
8939 9476 end = str + STRLEN(str);
8940 rettv->vval.v_number = serverPeekReply(X_DISPLAY, 9477 if (end > str)
8941 serverStrToWin(get_tv_string(&argvars[0])), &s); 9478 {
8942 # endif 9479 ni = listitem_alloc();
8943 9480 if (ni == NULL)
8944 if (argvars[1].v_type != VAR_UNKNOWN && rettv->vval.v_number > 0) 9481 break;
8945 { 9482 ni->li_tv.v_type = VAR_STRING;
8946 v.tv.v_type = VAR_STRING; 9483 ni->li_tv.vval.v_string = vim_strnsave(str, end - str);
8947 v.tv.vval.v_string = vim_strsave(s); 9484 list_append(l, ni);
8948 set_var(get_tv_string(&argvars[1]), &v.tv, FALSE); 9485 }
8949 vim_free(v.tv.vval.v_string); 9486 if (!match)
8950 } 9487 break;
9488 /* Advance to just after the match. */
9489 if (regmatch.endp[0] > str)
9490 col = 0;
9491 else
9492 {
9493 /* Don't get stuck at the same match. */
9494 #ifdef FEAT_MBYTE
9495 col = mb_ptr2len_check(regmatch.endp[0]);
8951 #else 9496 #else
8952 rettv->vval.v_number = -1; 9497 col = 1;
8953 #endif 9498 #endif
8954 } 9499 }
8955 9500 str = regmatch.endp[0];
8956 /*ARGSUSED*/ 9501 }
8957 static void 9502
8958 f_remote_read(argvars, rettv) 9503 vim_free(regmatch.regprog);
8959 typeval *argvars; 9504 }
8960 typeval *rettv; 9505
8961 { 9506 p_cpo = save_cpo;
8962 char_u *r = NULL;
8963
8964 #ifdef FEAT_CLIENTSERVER
8965 if (!check_restricted() && !check_secure())
8966 {
8967 # ifdef WIN32
8968 /* The server's HWND is encoded in the 'id' parameter */
8969 int n = 0;
8970
8971 sscanf(get_tv_string(&argvars[0]), "%x", &n);
8972 if (n != 0)
8973 r = serverGetReply((HWND)n, FALSE, TRUE, TRUE);
8974 if (r == NULL)
8975 # else
8976 if (check_connection() == FAIL || serverReadReply(X_DISPLAY,
8977 serverStrToWin(get_tv_string(&argvars[0])), &r, FALSE) < 0)
8978 # endif
8979 EMSG(_("E277: Unable to read a server reply"));
8980 }
8981 #endif
8982 rettv->v_type = VAR_STRING;
8983 rettv->vval.v_string = r;
8984 }
8985
8986 /*ARGSUSED*/
8987 static void
8988 f_server2client(argvars, rettv)
8989 typeval *argvars;
8990 typeval *rettv;
8991 {
8992 #ifdef FEAT_CLIENTSERVER
8993 char_u buf[NUMBUFLEN];
8994 char_u *server = get_tv_string(&argvars[0]);
8995 char_u *reply = get_tv_string_buf(&argvars[1], buf);
8996
8997 rettv->vval.v_number = -1;
8998 if (check_restricted() || check_secure())
8999 return;
9000 # ifdef FEAT_X11
9001 if (check_connection() == FAIL)
9002 return;
9003 # endif
9004
9005 if (serverSendReply(server, reply) < 0)
9006 {
9007 EMSG(_("E258: Unable to send to client"));
9008 return;
9009 }
9010 rettv->vval.v_number = 0;
9011 #else
9012 rettv->vval.v_number = -1;
9013 #endif
9014 }
9015
9016 #ifdef FEAT_CLIENTSERVER
9017 static void remote_common __ARGS((typeval *argvars, typeval *rettv, int expr));
9018
9019 static void
9020 remote_common(argvars, rettv, expr)
9021 typeval *argvars;
9022 typeval *rettv;
9023 int expr;
9024 {
9025 char_u *server_name;
9026 char_u *keys;
9027 char_u *r = NULL;
9028 char_u buf[NUMBUFLEN];
9029 # ifdef WIN32
9030 HWND w;
9031 # else
9032 Window w;
9033 # endif
9034
9035 if (check_restricted() || check_secure())
9036 return;
9037
9038 # ifdef FEAT_X11
9039 if (check_connection() == FAIL)
9040 return;
9041 # endif
9042
9043 server_name = get_tv_string(&argvars[0]);
9044 keys = get_tv_string_buf(&argvars[1], buf);
9045 # ifdef WIN32
9046 if (serverSendToVim(server_name, keys, &r, &w, expr, TRUE) < 0)
9047 # else
9048 if (serverSendToVim(X_DISPLAY, server_name, keys, &r, &w, expr, 0, TRUE)
9049 < 0)
9050 # endif
9051 {
9052 if (r != NULL)
9053 EMSG(r); /* sending worked but evaluation failed */
9054 else
9055 EMSG2(_("E241: Unable to send to %s"), server_name);
9056 return;
9057 }
9058
9059 rettv->vval.v_string = r;
9060
9061 if (argvars[2].v_type != VAR_UNKNOWN)
9062 {
9063 var v;
9064 char_u str[30];
9065
9066 sprintf((char *)str, "0x%x", (unsigned int)w);
9067 v.tv.v_type = VAR_STRING;
9068 v.tv.vval.v_string = vim_strsave(str);
9069 set_var(get_tv_string(&argvars[2]), &v.tv, FALSE);
9070 vim_free(v.tv.vval.v_string);
9071 }
9072 }
9073 #endif
9074
9075 /*
9076 * "remote_expr()" function
9077 */
9078 /*ARGSUSED*/
9079 static void
9080 f_remote_expr(argvars, rettv)
9081 typeval *argvars;
9082 typeval *rettv;
9083 {
9084 rettv->v_type = VAR_STRING;
9085 rettv->vval.v_string = NULL;
9086 #ifdef FEAT_CLIENTSERVER
9087 remote_common(argvars, rettv, TRUE);
9088 #endif
9089 }
9090
9091 /*
9092 * "remote_send()" function
9093 */
9094 /*ARGSUSED*/
9095 static void
9096 f_remote_send(argvars, rettv)
9097 typeval *argvars;
9098 typeval *rettv;
9099 {
9100 rettv->v_type = VAR_STRING;
9101 rettv->vval.v_string = NULL;
9102 #ifdef FEAT_CLIENTSERVER
9103 remote_common(argvars, rettv, FALSE);
9104 #endif
9105 }
9106
9107 /*
9108 * "remote_foreground()" function
9109 */
9110 /*ARGSUSED*/
9111 static void
9112 f_remote_foreground(argvars, rettv)
9113 typeval *argvars;
9114 typeval *rettv;
9115 {
9116 rettv->vval.v_number = 0;
9117 #ifdef FEAT_CLIENTSERVER
9118 # ifdef WIN32
9119 /* On Win32 it's done in this application. */
9120 serverForeground(get_tv_string(&argvars[0]));
9121 # else
9122 /* Send a foreground() expression to the server. */
9123 argvars[1].v_type = VAR_STRING;
9124 argvars[1].vval.v_string = vim_strsave((char_u *)"foreground()");
9125 argvars[2].v_type = VAR_UNKNOWN;
9126 remote_common(argvars, rettv, TRUE);
9127 vim_free(argvars[1].vval.v_string);
9128 # endif
9129 #endif
9130 } 9507 }
9131 9508
9132 #ifdef HAVE_STRFTIME 9509 #ifdef HAVE_STRFTIME
9133 /* 9510 /*
9134 * "strftime({format}[, {time}])" function 9511 * "strftime({format}[, {time}])" function
9213 else 9590 else
9214 rettv->vval.v_number = (varnumber_T) (pos - haystack); 9591 rettv->vval.v_number = (varnumber_T) (pos - haystack);
9215 } 9592 }
9216 9593
9217 /* 9594 /*
9595 * "string()" function
9596 */
9597 static void
9598 f_string(argvars, rettv)
9599 typeval *argvars;
9600 typeval *rettv;
9601 {
9602 char_u *tofree;
9603 char_u numbuf[NUMBUFLEN];
9604
9605 rettv->v_type = VAR_STRING;
9606 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf);
9607 if (tofree == NULL)
9608 rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
9609 }
9610
9611 /*
9612 * "strlen()" function
9613 */
9614 static void
9615 f_strlen(argvars, rettv)
9616 typeval *argvars;
9617 typeval *rettv;
9618 {
9619 rettv->vval.v_number = (varnumber_T)(STRLEN(
9620 get_tv_string(&argvars[0])));
9621 }
9622
9623 /*
9624 * "strpart()" function
9625 */
9626 static void
9627 f_strpart(argvars, rettv)
9628 typeval *argvars;
9629 typeval *rettv;
9630 {
9631 char_u *p;
9632 int n;
9633 int len;
9634 int slen;
9635
9636 p = get_tv_string(&argvars[0]);
9637 slen = (int)STRLEN(p);
9638
9639 n = get_tv_number(&argvars[1]);
9640 if (argvars[2].v_type != VAR_UNKNOWN)
9641 len = get_tv_number(&argvars[2]);
9642 else
9643 len = slen - n; /* default len: all bytes that are available. */
9644
9645 /*
9646 * Only return the overlap between the specified part and the actual
9647 * string.
9648 */
9649 if (n < 0)
9650 {
9651 len += n;
9652 n = 0;
9653 }
9654 else if (n > slen)
9655 n = slen;
9656 if (len < 0)
9657 len = 0;
9658 else if (n + len > slen)
9659 len = slen - n;
9660
9661 rettv->v_type = VAR_STRING;
9662 rettv->vval.v_string = vim_strnsave(p + n, len);
9663 }
9664
9665 /*
9218 * "strridx()" function 9666 * "strridx()" function
9219 */ 9667 */
9220 static void 9668 static void
9221 f_strridx(argvars, rettv) 9669 f_strridx(argvars, rettv)
9222 typeval *argvars; 9670 typeval *argvars;
9247 else 9695 else
9248 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack); 9696 rettv->vval.v_number = (varnumber_T)(lastmatch - haystack);
9249 } 9697 }
9250 9698
9251 /* 9699 /*
9252 * "string()" function
9253 */
9254 static void
9255 f_string(argvars, rettv)
9256 typeval *argvars;
9257 typeval *rettv;
9258 {
9259 char_u *tofree;
9260 char_u numbuf[NUMBUFLEN];
9261
9262 rettv->v_type = VAR_STRING;
9263 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf);
9264 if (tofree == NULL)
9265 rettv->vval.v_string = vim_strsave(rettv->vval.v_string);
9266 }
9267
9268 /*
9269 * "strlen()" function
9270 */
9271 static void
9272 f_strlen(argvars, rettv)
9273 typeval *argvars;
9274 typeval *rettv;
9275 {
9276 rettv->vval.v_number = (varnumber_T)(STRLEN(
9277 get_tv_string(&argvars[0])));
9278 }
9279
9280 /*
9281 * "strpart()" function
9282 */
9283 static void
9284 f_strpart(argvars, rettv)
9285 typeval *argvars;
9286 typeval *rettv;
9287 {
9288 char_u *p;
9289 int n;
9290 int len;
9291 int slen;
9292
9293 p = get_tv_string(&argvars[0]);
9294 slen = (int)STRLEN(p);
9295
9296 n = get_tv_number(&argvars[1]);
9297 if (argvars[2].v_type != VAR_UNKNOWN)
9298 len = get_tv_number(&argvars[2]);
9299 else
9300 len = slen - n; /* default len: all bytes that are available. */
9301
9302 /*
9303 * Only return the overlap between the specified part and the actual
9304 * string.
9305 */
9306 if (n < 0)
9307 {
9308 len += n;
9309 n = 0;
9310 }
9311 else if (n > slen)
9312 n = slen;
9313 if (len < 0)
9314 len = 0;
9315 else if (n + len > slen)
9316 len = slen - n;
9317
9318 rettv->v_type = VAR_STRING;
9319 rettv->vval.v_string = vim_strnsave(p + n, len);
9320 }
9321
9322 /*
9323 * "strtrans()" function 9700 * "strtrans()" function
9324 */ 9701 */
9325 static void 9702 static void
9326 f_strtrans(argvars, rettv) 9703 f_strtrans(argvars, rettv)
9327 typeval *argvars; 9704 typeval *argvars;
9328 typeval *rettv; 9705 typeval *rettv;
9329 { 9706 {
9330 rettv->v_type = VAR_STRING; 9707 rettv->v_type = VAR_STRING;
9331 rettv->vval.v_string = transstr(get_tv_string(&argvars[0])); 9708 rettv->vval.v_string = transstr(get_tv_string(&argvars[0]));
9709 }
9710
9711 /*
9712 * "submatch()" function
9713 */
9714 static void
9715 f_submatch(argvars, rettv)
9716 typeval *argvars;
9717 typeval *rettv;
9718 {
9719 rettv->v_type = VAR_STRING;
9720 rettv->vval.v_string = reg_submatch((int)get_tv_number(&argvars[0]));
9721 }
9722
9723 /*
9724 * "substitute()" function
9725 */
9726 static void
9727 f_substitute(argvars, rettv)
9728 typeval *argvars;
9729 typeval *rettv;
9730 {
9731 char_u patbuf[NUMBUFLEN];
9732 char_u subbuf[NUMBUFLEN];
9733 char_u flagsbuf[NUMBUFLEN];
9734
9735 rettv->v_type = VAR_STRING;
9736 rettv->vval.v_string = do_string_sub(
9737 get_tv_string(&argvars[0]),
9738 get_tv_string_buf(&argvars[1], patbuf),
9739 get_tv_string_buf(&argvars[2], subbuf),
9740 get_tv_string_buf(&argvars[3], flagsbuf));
9332 } 9741 }
9333 9742
9334 /* 9743 /*
9335 * "synID(line, col, trans)" function 9744 * "synID(line, col, trans)" function
9336 */ 9745 */
9553 mch_remove(infile); 9962 mch_remove(infile);
9554 vim_free(infile); 9963 vim_free(infile);
9555 } 9964 }
9556 rettv->v_type = VAR_STRING; 9965 rettv->v_type = VAR_STRING;
9557 rettv->vval.v_string = res; 9966 rettv->vval.v_string = res;
9558 }
9559
9560 /*
9561 * "submatch()" function
9562 */
9563 static void
9564 f_submatch(argvars, rettv)
9565 typeval *argvars;
9566 typeval *rettv;
9567 {
9568 rettv->v_type = VAR_STRING;
9569 rettv->vval.v_string = reg_submatch((int)get_tv_number(&argvars[0]));
9570 }
9571
9572 /*
9573 * "substitute()" function
9574 */
9575 static void
9576 f_substitute(argvars, rettv)
9577 typeval *argvars;
9578 typeval *rettv;
9579 {
9580 char_u patbuf[NUMBUFLEN];
9581 char_u subbuf[NUMBUFLEN];
9582 char_u flagsbuf[NUMBUFLEN];
9583
9584 rettv->v_type = VAR_STRING;
9585 rettv->vval.v_string = do_string_sub(
9586 get_tv_string(&argvars[0]),
9587 get_tv_string_buf(&argvars[1], patbuf),
9588 get_tv_string_buf(&argvars[2], subbuf),
9589 get_tv_string_buf(&argvars[3], flagsbuf));
9590 } 9967 }
9591 9968
9592 /* 9969 /*
9593 * "tempname()" function 9970 * "tempname()" function
9594 */ 9971 */