Mercurial > vim
comparison src/eval.c @ 97:d4f3db33d782 v7.0037
updated for version 7.0037
author | vimboss |
---|---|
date | Tue, 11 Jan 2005 21:34:41 +0000 |
parents | a9e90b3356b6 |
children | 1f3902f3eb5c |
comparison
equal
deleted
inserted
replaced
96:8f25c0d2210f | 97:d4f3db33d782 |
---|---|
189 int fi_varcount; /* nr of variables in the list */ | 189 int fi_varcount; /* nr of variables in the list */ |
190 listwatch fi_lw; /* keep an eye on the item used. */ | 190 listwatch fi_lw; /* keep an eye on the item used. */ |
191 listvar *fi_list; /* list being used */ | 191 listvar *fi_list; /* list being used */ |
192 } forinfo; | 192 } forinfo; |
193 | 193 |
194 /* used for map() */ | |
195 static typeval amp_tv; | |
194 | 196 |
195 /* | 197 /* |
196 * Return the name of the executed function. | 198 * Return the name of the executed function. |
197 */ | 199 */ |
198 char_u * | 200 char_u * |
312 static int eval7 __ARGS((char_u **arg, typeval *rettv, int evaluate)); | 314 static int eval7 __ARGS((char_u **arg, typeval *rettv, int evaluate)); |
313 static int eval_index __ARGS((char_u **arg, typeval *rettv, int evaluate)); | 315 static int eval_index __ARGS((char_u **arg, typeval *rettv, int evaluate)); |
314 static int get_option_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); | 316 static int get_option_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); |
315 static int get_string_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); | 317 static int get_string_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); |
316 static int get_lit_string_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); | 318 static int get_lit_string_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); |
319 static int get_sharp_string_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); | |
317 static int get_list_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); | 320 static int get_list_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); |
318 static listvar *list_alloc __ARGS((void)); | 321 static listvar *list_alloc __ARGS((void)); |
319 static void list_unref __ARGS((listvar *l)); | 322 static void list_unref __ARGS((listvar *l)); |
320 static void list_free __ARGS((listvar *l)); | 323 static void list_free __ARGS((listvar *l)); |
321 static listitem *listitem_alloc __ARGS((void)); | 324 static listitem *listitem_alloc __ARGS((void)); |
322 static void listitem_free __ARGS((listitem *item)); | 325 static void listitem_free __ARGS((listitem *item)); |
323 static long list_len __ARGS((listvar *l)); | 326 static long list_len __ARGS((listvar *l)); |
324 static int list_equal __ARGS((listvar *l1, listvar *l2, int ic)); | 327 static int list_equal __ARGS((listvar *l1, listvar *l2, int ic)); |
325 static int tv_equal __ARGS((typeval *tv1, typeval *tv2, int ic)); | 328 static int tv_equal __ARGS((typeval *tv1, typeval *tv2, int ic)); |
329 static int string_isa_number __ARGS((char_u *s)); | |
326 static listitem *list_find __ARGS((listvar *l, long n)); | 330 static listitem *list_find __ARGS((listvar *l, long n)); |
327 static long list_idx_of_item __ARGS((listvar *l, listitem *item)); | 331 static long list_idx_of_item __ARGS((listvar *l, listitem *item)); |
328 static listitem *list_find_ext __ARGS((listvar *l, long *ip)); | 332 static listitem *list_find_ext __ARGS((listvar *l, long *ip)); |
329 static void list_append __ARGS((listvar *l, listitem *item)); | 333 static void list_append __ARGS((listvar *l, listitem *item)); |
330 static int list_append_tv __ARGS((listvar *l, typeval *tv)); | 334 static int list_append_tv __ARGS((listvar *l, typeval *tv)); |
332 static int list_extend __ARGS((listvar *l1, listvar *l2, listitem *bef)); | 336 static int list_extend __ARGS((listvar *l1, listvar *l2, listitem *bef)); |
333 static int list_concat __ARGS((listvar *l1, listvar *l2, typeval *tv)); | 337 static int list_concat __ARGS((listvar *l1, listvar *l2, typeval *tv)); |
334 static listvar *list_copy __ARGS((listvar *orig, int deep)); | 338 static listvar *list_copy __ARGS((listvar *orig, int deep)); |
335 static void list_getrem __ARGS((listvar *l, listitem *item, listitem *item2)); | 339 static void list_getrem __ARGS((listvar *l, listitem *item, listitem *item2)); |
336 static char_u *list2string __ARGS((typeval *tv)); | 340 static char_u *list2string __ARGS((typeval *tv)); |
341 static void list_join __ARGS((garray_T *gap, listvar *l, char_u *sep, int echo)); | |
342 | |
343 static char_u *echo_string __ARGS((typeval *tv, char_u **tofree, char_u *numbuf)); | |
337 static char_u *tv2string __ARGS((typeval *tv, char_u **tofree, char_u *numbuf)); | 344 static char_u *tv2string __ARGS((typeval *tv, char_u **tofree, char_u *numbuf)); |
345 static char_u *string_quote __ARGS((char_u *str, int function)); | |
338 static int get_env_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); | 346 static int get_env_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); |
339 static int find_internal_func __ARGS((char_u *name)); | 347 static int find_internal_func __ARGS((char_u *name)); |
340 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); | 348 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); |
341 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)); | 349 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)); |
342 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)); | 350 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)); |
370 static void f_did_filetype __ARGS((typeval *argvars, typeval *rettv)); | 378 static void f_did_filetype __ARGS((typeval *argvars, typeval *rettv)); |
371 static void f_diff_filler __ARGS((typeval *argvars, typeval *rettv)); | 379 static void f_diff_filler __ARGS((typeval *argvars, typeval *rettv)); |
372 static void f_diff_hlID __ARGS((typeval *argvars, typeval *rettv)); | 380 static void f_diff_hlID __ARGS((typeval *argvars, typeval *rettv)); |
373 static void f_empty __ARGS((typeval *argvars, typeval *rettv)); | 381 static void f_empty __ARGS((typeval *argvars, typeval *rettv)); |
374 static void f_escape __ARGS((typeval *argvars, typeval *rettv)); | 382 static void f_escape __ARGS((typeval *argvars, typeval *rettv)); |
383 static void f_eval __ARGS((typeval *argvars, typeval *rettv)); | |
375 static void f_eventhandler __ARGS((typeval *argvars, typeval *rettv)); | 384 static void f_eventhandler __ARGS((typeval *argvars, typeval *rettv)); |
376 static void f_executable __ARGS((typeval *argvars, typeval *rettv)); | 385 static void f_executable __ARGS((typeval *argvars, typeval *rettv)); |
377 static void f_exists __ARGS((typeval *argvars, typeval *rettv)); | 386 static void f_exists __ARGS((typeval *argvars, typeval *rettv)); |
378 static void f_expand __ARGS((typeval *argvars, typeval *rettv)); | 387 static void f_expand __ARGS((typeval *argvars, typeval *rettv)); |
379 static void f_extend __ARGS((typeval *argvars, typeval *rettv)); | 388 static void f_extend __ARGS((typeval *argvars, typeval *rettv)); |
380 static void f_filereadable __ARGS((typeval *argvars, typeval *rettv)); | 389 static void f_filereadable __ARGS((typeval *argvars, typeval *rettv)); |
381 static void f_filewritable __ARGS((typeval *argvars, typeval *rettv)); | 390 static void f_filewritable __ARGS((typeval *argvars, typeval *rettv)); |
391 static void f_filter __ARGS((typeval *argvars, typeval *rettv)); | |
382 static void f_finddir __ARGS((typeval *argvars, typeval *rettv)); | 392 static void f_finddir __ARGS((typeval *argvars, typeval *rettv)); |
383 static void f_findfile __ARGS((typeval *argvars, typeval *rettv)); | 393 static void f_findfile __ARGS((typeval *argvars, typeval *rettv)); |
384 static void f_fnamemodify __ARGS((typeval *argvars, typeval *rettv)); | 394 static void f_fnamemodify __ARGS((typeval *argvars, typeval *rettv)); |
385 static void f_foldclosed __ARGS((typeval *argvars, typeval *rettv)); | 395 static void f_foldclosed __ARGS((typeval *argvars, typeval *rettv)); |
386 static void f_foldclosedend __ARGS((typeval *argvars, typeval *rettv)); | 396 static void f_foldclosedend __ARGS((typeval *argvars, typeval *rettv)); |
426 static void f_inputrestore __ARGS((typeval *argvars, typeval *rettv)); | 436 static void f_inputrestore __ARGS((typeval *argvars, typeval *rettv)); |
427 static void f_inputsave __ARGS((typeval *argvars, typeval *rettv)); | 437 static void f_inputsave __ARGS((typeval *argvars, typeval *rettv)); |
428 static void f_inputsecret __ARGS((typeval *argvars, typeval *rettv)); | 438 static void f_inputsecret __ARGS((typeval *argvars, typeval *rettv)); |
429 static void f_insert __ARGS((typeval *argvars, typeval *rettv)); | 439 static void f_insert __ARGS((typeval *argvars, typeval *rettv)); |
430 static void f_isdirectory __ARGS((typeval *argvars, typeval *rettv)); | 440 static void f_isdirectory __ARGS((typeval *argvars, typeval *rettv)); |
441 static void f_join __ARGS((typeval *argvars, typeval *rettv)); | |
431 static void f_last_buffer_nr __ARGS((typeval *argvars, typeval *rettv)); | 442 static void f_last_buffer_nr __ARGS((typeval *argvars, typeval *rettv)); |
432 static void f_len __ARGS((typeval *argvars, typeval *rettv)); | 443 static void f_len __ARGS((typeval *argvars, typeval *rettv)); |
433 static void f_libcall __ARGS((typeval *argvars, typeval *rettv)); | 444 static void f_libcall __ARGS((typeval *argvars, typeval *rettv)); |
434 static void f_libcallnr __ARGS((typeval *argvars, typeval *rettv)); | 445 static void f_libcallnr __ARGS((typeval *argvars, typeval *rettv)); |
435 static void f_line __ARGS((typeval *argvars, typeval *rettv)); | 446 static void f_line __ARGS((typeval *argvars, typeval *rettv)); |
436 static void f_line2byte __ARGS((typeval *argvars, typeval *rettv)); | 447 static void f_line2byte __ARGS((typeval *argvars, typeval *rettv)); |
437 static void f_lispindent __ARGS((typeval *argvars, typeval *rettv)); | 448 static void f_lispindent __ARGS((typeval *argvars, typeval *rettv)); |
438 static void f_localtime __ARGS((typeval *argvars, typeval *rettv)); | 449 static void f_localtime __ARGS((typeval *argvars, typeval *rettv)); |
450 static void f_map __ARGS((typeval *argvars, typeval *rettv)); | |
439 static void f_maparg __ARGS((typeval *argvars, typeval *rettv)); | 451 static void f_maparg __ARGS((typeval *argvars, typeval *rettv)); |
440 static void f_mapcheck __ARGS((typeval *argvars, typeval *rettv)); | 452 static void f_mapcheck __ARGS((typeval *argvars, typeval *rettv)); |
441 static void f_match __ARGS((typeval *argvars, typeval *rettv)); | 453 static void f_match __ARGS((typeval *argvars, typeval *rettv)); |
442 static void f_matchend __ARGS((typeval *argvars, typeval *rettv)); | 454 static void f_matchend __ARGS((typeval *argvars, typeval *rettv)); |
443 static void f_matchstr __ARGS((typeval *argvars, typeval *rettv)); | 455 static void f_matchstr __ARGS((typeval *argvars, typeval *rettv)); |
466 static void f_setline __ARGS((typeval *argvars, typeval *rettv)); | 478 static void f_setline __ARGS((typeval *argvars, typeval *rettv)); |
467 static void f_setreg __ARGS((typeval *argvars, typeval *rettv)); | 479 static void f_setreg __ARGS((typeval *argvars, typeval *rettv)); |
468 static void f_setwinvar __ARGS((typeval *argvars, typeval *rettv)); | 480 static void f_setwinvar __ARGS((typeval *argvars, typeval *rettv)); |
469 static void f_simplify __ARGS((typeval *argvars, typeval *rettv)); | 481 static void f_simplify __ARGS((typeval *argvars, typeval *rettv)); |
470 static void f_sort __ARGS((typeval *argvars, typeval *rettv)); | 482 static void f_sort __ARGS((typeval *argvars, typeval *rettv)); |
471 static void f_str2list __ARGS((typeval *argvars, typeval *rettv)); | 483 static void f_split __ARGS((typeval *argvars, typeval *rettv)); |
472 #ifdef HAVE_STRFTIME | 484 #ifdef HAVE_STRFTIME |
473 static void f_strftime __ARGS((typeval *argvars, typeval *rettv)); | 485 static void f_strftime __ARGS((typeval *argvars, typeval *rettv)); |
474 #endif | 486 #endif |
475 static void f_stridx __ARGS((typeval *argvars, typeval *rettv)); | 487 static void f_stridx __ARGS((typeval *argvars, typeval *rettv)); |
476 static void f_string __ARGS((typeval *argvars, typeval *rettv)); | 488 static void f_string __ARGS((typeval *argvars, typeval *rettv)); |
515 static void init_tv __ARGS((typeval *varp)); | 527 static void init_tv __ARGS((typeval *varp)); |
516 static long get_tv_number __ARGS((typeval *varp)); | 528 static long get_tv_number __ARGS((typeval *varp)); |
517 static linenr_T get_tv_lnum __ARGS((typeval *argvars)); | 529 static linenr_T get_tv_lnum __ARGS((typeval *argvars)); |
518 static char_u *get_tv_string __ARGS((typeval *varp)); | 530 static char_u *get_tv_string __ARGS((typeval *varp)); |
519 static char_u *get_tv_string_buf __ARGS((typeval *varp, char_u *buf)); | 531 static char_u *get_tv_string_buf __ARGS((typeval *varp, char_u *buf)); |
532 static int get_amp_tv __ARGS((typeval *rettv)); | |
520 static VAR find_var __ARGS((char_u *name, int writing)); | 533 static VAR find_var __ARGS((char_u *name, int writing)); |
521 static VAR find_var_in_ga __ARGS((garray_T *gap, char_u *varname)); | 534 static VAR find_var_in_ga __ARGS((garray_T *gap, char_u *varname)); |
522 static garray_T *find_var_ga __ARGS((char_u *name, char_u **varname)); | 535 static garray_T *find_var_ga __ARGS((char_u *name, char_u **varname)); |
523 static void clear_var __ARGS((VAR v)); | 536 static void clear_var __ARGS((VAR v)); |
524 static void list_one_var __ARGS((VAR v, char_u *prefix)); | 537 static void list_one_var __ARGS((VAR v, char_u *prefix)); |
822 eval_to_number(expr) | 835 eval_to_number(expr) |
823 char_u *expr; | 836 char_u *expr; |
824 { | 837 { |
825 typeval rettv; | 838 typeval rettv; |
826 int retval; | 839 int retval; |
827 char_u *p = expr; | 840 char_u *p = skipwhite(expr); |
828 | 841 |
829 ++emsg_off; | 842 ++emsg_off; |
830 | 843 |
831 if (eval1(&p, &rettv, TRUE) == FAIL) | 844 if (eval1(&p, &rettv, TRUE) == FAIL) |
832 retval = -1; | 845 retval = -1; |
1990 xp->xp_context = EXPAND_NOTHING; | 2003 xp->xp_context = EXPAND_NOTHING; |
1991 } | 2004 } |
1992 else if (c == '\'') /* literal string */ | 2005 else if (c == '\'') /* literal string */ |
1993 { | 2006 { |
1994 while ((c = *++xp->xp_pattern) != NUL && c != '\'') | 2007 while ((c = *++xp->xp_pattern) != NUL && c != '\'') |
2008 /* skip */ ; | |
2009 xp->xp_context = EXPAND_NOTHING; | |
2010 } | |
2011 else if (c == '#') /* sharp string */ | |
2012 { | |
2013 /* Trick: ## is like stopping and starting a sharp string. */ | |
2014 while ((c = *++xp->xp_pattern) != NUL && c != '#') | |
1995 /* skip */ ; | 2015 /* skip */ ; |
1996 xp->xp_context = EXPAND_NOTHING; | 2016 xp->xp_context = EXPAND_NOTHING; |
1997 } | 2017 } |
1998 else if (c == '|') | 2018 else if (c == '|') |
1999 { | 2019 { |
3111 */ | 3131 */ |
3112 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); | 3132 case '\'': ret = get_lit_string_tv(arg, rettv, evaluate); |
3113 break; | 3133 break; |
3114 | 3134 |
3115 /* | 3135 /* |
3136 * Sharp string constant: #str##ing#. | |
3137 */ | |
3138 case '#': ret = get_sharp_string_tv(arg, rettv, evaluate); | |
3139 break; | |
3140 | |
3141 /* | |
3116 * List: [expr, expr] | 3142 * List: [expr, expr] |
3117 */ | 3143 */ |
3118 case '[': ret = get_list_tv(arg, rettv, evaluate); | 3144 case '[': ret = get_list_tv(arg, rettv, evaluate); |
3119 break; | 3145 break; |
3120 | 3146 |
3121 /* | 3147 /* |
3122 * Option value: &name | 3148 * Option value: &name or map() item "&". |
3123 */ | 3149 */ |
3124 case '&': ret = get_option_tv(arg, rettv, evaluate); | 3150 case '&': if (!ASCII_ISALPHA(*(*arg + 1))) |
3151 { | |
3152 *arg = skipwhite(*arg + 1); | |
3153 if (evaluate) | |
3154 ret = get_amp_tv(rettv); | |
3155 } | |
3156 else | |
3157 ret = get_option_tv(arg, rettv, evaluate); | |
3125 break; | 3158 break; |
3126 | 3159 |
3127 /* | 3160 /* |
3128 * Environment variable: $VAR. | 3161 * Environment variable: $VAR. |
3129 */ | 3162 */ |
3507 int extra = 0; | 3540 int extra = 0; |
3508 | 3541 |
3509 /* | 3542 /* |
3510 * Find the end of the string, skipping backslashed characters. | 3543 * Find the end of the string, skipping backslashed characters. |
3511 */ | 3544 */ |
3512 for (p = *arg + 1; *p && *p != '"'; mb_ptr_adv(p)) | 3545 for (p = *arg + 1; *p != NUL && *p != '"'; mb_ptr_adv(p)) |
3513 { | 3546 { |
3514 if (*p == '\\' && p[1] != NUL) | 3547 if (*p == '\\' && p[1] != NUL) |
3515 { | 3548 { |
3516 ++p; | 3549 ++p; |
3517 /* A "\<x>" form occupies at least 4 characters, and produces up | 3550 /* A "\<x>" form occupies at least 4 characters, and produces up |
3541 name = alloc((unsigned)(p - *arg + extra)); | 3574 name = alloc((unsigned)(p - *arg + extra)); |
3542 if (name == NULL) | 3575 if (name == NULL) |
3543 return FAIL; | 3576 return FAIL; |
3544 | 3577 |
3545 i = 0; | 3578 i = 0; |
3546 for (p = *arg + 1; *p && *p != '"'; ++p) | 3579 for (p = *arg + 1; *p != NUL && *p != '"'; ++p) |
3547 { | 3580 { |
3548 if (*p == '\\') | 3581 if (*p == '\\') |
3549 { | 3582 { |
3550 switch (*++p) | 3583 switch (*++p) |
3551 { | 3584 { |
3687 | 3720 |
3688 return OK; | 3721 return OK; |
3689 } | 3722 } |
3690 | 3723 |
3691 /* | 3724 /* |
3725 * Allocate a variable for a #string# constant. | |
3726 * Return OK or FAIL. | |
3727 */ | |
3728 static int | |
3729 get_sharp_string_tv(arg, rettv, evaluate) | |
3730 char_u **arg; | |
3731 typeval *rettv; | |
3732 int evaluate; | |
3733 { | |
3734 char_u *p; | |
3735 char_u *str; | |
3736 int i; | |
3737 int reduce = 0; | |
3738 | |
3739 /* | |
3740 * Find the end of the string, skipping ##. | |
3741 */ | |
3742 for (p = *arg + 1; *p != NUL; mb_ptr_adv(p)) | |
3743 { | |
3744 if (*p == '#') | |
3745 { | |
3746 if (p[1] != '#') | |
3747 break; | |
3748 ++reduce; | |
3749 ++p; | |
3750 } | |
3751 } | |
3752 | |
3753 if (*p != '#') | |
3754 { | |
3755 EMSG2(_("E999: Missing #: %s"), *arg); | |
3756 return FAIL; | |
3757 } | |
3758 | |
3759 /* If only parsing, set *arg and return here */ | |
3760 if (!evaluate) | |
3761 { | |
3762 *arg = p + 1; | |
3763 return OK; | |
3764 } | |
3765 | |
3766 /* | |
3767 * Copy the string into allocated memory, handling ## to # reduction. | |
3768 */ | |
3769 str = alloc((unsigned)((p - *arg) - reduce)); | |
3770 if (str == NULL) | |
3771 return FAIL; | |
3772 | |
3773 i = 0; | |
3774 for (p = *arg + 1; *p != NUL; ++p) | |
3775 { | |
3776 if (*p == '#') | |
3777 { | |
3778 if (p[1] != '#') | |
3779 break; | |
3780 ++p; | |
3781 } | |
3782 str[i++] = *p; | |
3783 | |
3784 #ifdef FEAT_MBYTE | |
3785 /* For a multi-byte character copy the bytes after the first one. */ | |
3786 if (has_mbyte) | |
3787 { | |
3788 int l = (*mb_ptr2len_check)(p); | |
3789 | |
3790 while (--l > 0) | |
3791 str[i++] = *++p; | |
3792 } | |
3793 #endif | |
3794 } | |
3795 str[i] = NUL; | |
3796 *arg = p + 1; | |
3797 | |
3798 rettv->v_type = VAR_STRING; | |
3799 rettv->vval.v_string = str; | |
3800 | |
3801 return OK; | |
3802 } | |
3803 | |
3804 /* | |
3692 * Allocate a variable for a List and fill it from "*arg". | 3805 * Allocate a variable for a List and fill it from "*arg". |
3693 * Return OK or FAIL. | 3806 * Return OK or FAIL. |
3694 */ | 3807 */ |
3695 static int | 3808 static int |
3696 get_list_tv(arg, rettv, evaluate) | 3809 get_list_tv(arg, rettv, evaluate) |
3877 || STRCMP(tv1->vval.v_string, tv2->vval.v_string) != 0) | 3990 || STRCMP(tv1->vval.v_string, tv2->vval.v_string) != 0) |
3878 return FALSE; | 3991 return FALSE; |
3879 } | 3992 } |
3880 else if (tv1->v_type == VAR_NUMBER || tv2->v_type == VAR_NUMBER) | 3993 else if (tv1->v_type == VAR_NUMBER || tv2->v_type == VAR_NUMBER) |
3881 { | 3994 { |
3995 /* "4" is equal to 4. But don't consider 'a' and zero to be equal. | |
3996 * Don't consider "4x" to be equal to 4. */ | |
3997 if ((tv1->v_type == VAR_STRING | |
3998 && !string_isa_number(tv1->vval.v_string)) | |
3999 || (tv2->v_type == VAR_STRING | |
4000 && !string_isa_number(tv2->vval.v_string))) | |
4001 return FALSE; | |
3882 if (get_tv_number(tv1) != get_tv_number(tv2)) | 4002 if (get_tv_number(tv1) != get_tv_number(tv2)) |
3883 return FALSE; | 4003 return FALSE; |
3884 } | 4004 } |
3885 else if (!ic && STRCMP(get_tv_string_buf(tv1, buf1), | 4005 else if (!ic && STRCMP(get_tv_string_buf(tv1, buf1), |
3886 get_tv_string_buf(tv2, buf2)) != 0) | 4006 get_tv_string_buf(tv2, buf2)) != 0) |
3887 return FALSE; | 4007 return FALSE; |
3888 else if (ic && STRICMP(get_tv_string_buf(tv1, buf1), | 4008 else if (ic && STRICMP(get_tv_string_buf(tv1, buf1), |
3889 get_tv_string_buf(tv2, buf2)) != 0) | 4009 get_tv_string_buf(tv2, buf2)) != 0) |
3890 return FALSE; | 4010 return FALSE; |
3891 return TRUE; | 4011 return TRUE; |
4012 } | |
4013 | |
4014 /* | |
4015 * Return TRUE if "tv" is a number without other non-white characters. | |
4016 */ | |
4017 static int | |
4018 string_isa_number(s) | |
4019 char_u *s; | |
4020 { | |
4021 int len; | |
4022 | |
4023 vim_str2nr(s, NULL, &len, TRUE, TRUE, NULL, NULL); | |
4024 return len > 0 && *skipwhite(s + len) == NUL; | |
3892 } | 4025 } |
3893 | 4026 |
3894 /* | 4027 /* |
3895 * Locate item with index "n" in list "l" and return it. | 4028 * Locate item with index "n" in list "l" and return it. |
3896 * A negative index is counted from the end; -1 is the last item. | 4029 * A negative index is counted from the end; -1 is the last item. |
4185 static char_u * | 4318 static char_u * |
4186 list2string(tv) | 4319 list2string(tv) |
4187 typeval *tv; | 4320 typeval *tv; |
4188 { | 4321 { |
4189 garray_T ga; | 4322 garray_T ga; |
4190 listitem *item; | |
4191 int first = TRUE; | |
4192 char_u *tofree; | |
4193 char_u *s; | |
4194 char_u numbuf[NUMBUFLEN]; | |
4195 | 4323 |
4196 if (tv->vval.v_list == NULL) | 4324 if (tv->vval.v_list == NULL) |
4197 return NULL; | 4325 return NULL; |
4198 ga_init2(&ga, (int)sizeof(char), 80); | 4326 ga_init2(&ga, (int)sizeof(char), 80); |
4199 ga_append(&ga, '['); | 4327 ga_append(&ga, '['); |
4200 | 4328 list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE); |
4201 for (item = tv->vval.v_list->lv_first; item != NULL; item = item->li_next) | 4329 ga_append(&ga, ']'); |
4330 ga_append(&ga, NUL); | |
4331 return (char_u *)ga.ga_data; | |
4332 } | |
4333 | |
4334 /* | |
4335 * Join list "l" into a string in "*gap", using separator "sep". | |
4336 * When "echo" is TRUE use String as echoed, otherwise as inside a List. | |
4337 */ | |
4338 static void | |
4339 list_join(gap, l, sep, echo) | |
4340 garray_T *gap; | |
4341 listvar *l; | |
4342 char_u *sep; | |
4343 int echo; | |
4344 { | |
4345 int first = TRUE; | |
4346 char_u *tofree; | |
4347 char_u numbuf[NUMBUFLEN]; | |
4348 listitem *item; | |
4349 char_u *s; | |
4350 | |
4351 for (item = l->lv_first; item != NULL; item = item->li_next) | |
4202 { | 4352 { |
4203 if (first) | 4353 if (first) |
4204 first = FALSE; | 4354 first = FALSE; |
4205 else | 4355 else |
4206 ga_concat(&ga, (char_u *)", "); | 4356 ga_concat(gap, sep); |
4207 | 4357 |
4208 s = tv2string(&item->li_tv, &tofree, numbuf); | 4358 if (echo) |
4359 s = echo_string(&item->li_tv, &tofree, numbuf); | |
4360 else | |
4361 s = tv2string(&item->li_tv, &tofree, numbuf); | |
4209 if (s != NULL) | 4362 if (s != NULL) |
4210 ga_concat(&ga, s); | 4363 ga_concat(gap, s); |
4211 vim_free(tofree); | 4364 vim_free(tofree); |
4212 } | 4365 } |
4213 | |
4214 ga_append(&ga, ']'); | |
4215 ga_append(&ga, NUL); | |
4216 return (char_u *)ga.ga_data; | |
4217 } | 4366 } |
4218 | 4367 |
4219 /* | 4368 /* |
4220 * Return a string with the string representation of a variable. | 4369 * Return a string with the string representation of a variable. |
4221 * If the memory is allocated "tofree" is set to it, otherwise NULL. | 4370 * If the memory is allocated "tofree" is set to it, otherwise NULL. |
4222 * "numbuf" is used for a number. | 4371 * "numbuf" is used for a number. |
4372 * Does not put quotes around strings, as ":echo" displays values. | |
4223 * May return NULL; | 4373 * May return NULL; |
4224 */ | 4374 */ |
4225 static char_u * | 4375 static char_u * |
4226 tv2string(tv, tofree, numbuf) | 4376 echo_string(tv, tofree, numbuf) |
4227 typeval *tv; | 4377 typeval *tv; |
4228 char_u **tofree; | 4378 char_u **tofree; |
4229 char_u *numbuf; | 4379 char_u *numbuf; |
4230 { | 4380 { |
4231 switch (tv->v_type) | 4381 switch (tv->v_type) |
4238 return *tofree; | 4388 return *tofree; |
4239 case VAR_STRING: | 4389 case VAR_STRING: |
4240 case VAR_NUMBER: | 4390 case VAR_NUMBER: |
4241 break; | 4391 break; |
4242 default: | 4392 default: |
4243 EMSG2(_(e_intern2), "tv2string()"); | 4393 EMSG2(_(e_intern2), "echo_string()"); |
4244 } | 4394 } |
4245 *tofree = NULL; | 4395 *tofree = NULL; |
4246 return get_tv_string_buf(tv, numbuf); | 4396 return get_tv_string_buf(tv, numbuf); |
4397 } | |
4398 | |
4399 /* | |
4400 * Return a string with the string representation of a variable. | |
4401 * If the memory is allocated "tofree" is set to it, otherwise NULL. | |
4402 * "numbuf" is used for a number. | |
4403 * Puts quotes around strings, so that they can be parsed back by eval(). | |
4404 * May return NULL; | |
4405 */ | |
4406 static char_u * | |
4407 tv2string(tv, tofree, numbuf) | |
4408 typeval *tv; | |
4409 char_u **tofree; | |
4410 char_u *numbuf; | |
4411 { | |
4412 switch (tv->v_type) | |
4413 { | |
4414 case VAR_NUMBER: | |
4415 break; | |
4416 case VAR_FUNC: | |
4417 *tofree = string_quote(tv->vval.v_string, TRUE); | |
4418 return *tofree; | |
4419 case VAR_STRING: | |
4420 *tofree = string_quote(tv->vval.v_string, FALSE); | |
4421 return *tofree; | |
4422 case VAR_LIST: | |
4423 *tofree = list2string(tv); | |
4424 return *tofree; | |
4425 default: | |
4426 EMSG2(_(e_intern2), "tv2string()"); | |
4427 } | |
4428 *tofree = NULL; | |
4429 return get_tv_string_buf(tv, numbuf); | |
4430 } | |
4431 | |
4432 /* | |
4433 * Return a string in # quotes, doubling # characters. | |
4434 * If "function" is TRUE make it function(#string#). | |
4435 */ | |
4436 static char_u * | |
4437 string_quote(str, function) | |
4438 char_u *str; | |
4439 int function; | |
4440 { | |
4441 unsigned len = function ? 13 : 3; | |
4442 char_u *p, *r, *s; | |
4443 | |
4444 for (p = str; *p != NUL; mb_ptr_adv(p)) | |
4445 if (*p == '#') | |
4446 ++len; | |
4447 s = r = alloc(len); | |
4448 if (r != NULL) | |
4449 { | |
4450 if (function) | |
4451 { | |
4452 STRCPY(r, "function(#"); | |
4453 r += 10; | |
4454 } | |
4455 else | |
4456 *r++ = '#'; | |
4457 for (p = str; *p != NUL; ++p) | |
4458 { | |
4459 if (*p == '#') | |
4460 *r++ = '#'; | |
4461 *r++ = *p; | |
4462 #ifdef FEAT_MBYTE | |
4463 /* For a multi-byte character copy the bytes after the first one. */ | |
4464 if (has_mbyte) | |
4465 { | |
4466 int l = (*mb_ptr2len_check)(p); | |
4467 | |
4468 while (--l > 0) | |
4469 *r++ = *++p; | |
4470 } | |
4471 #endif | |
4472 } | |
4473 *r++ = '#'; | |
4474 if (function) | |
4475 *r++ = ')'; | |
4476 *r++ = NUL; | |
4477 } | |
4478 return s; | |
4247 } | 4479 } |
4248 | 4480 |
4249 /* | 4481 /* |
4250 * Get the value of an environment variable. | 4482 * Get the value of an environment variable. |
4251 * "arg" is pointing to the '$'. It is advanced to after the name. | 4483 * "arg" is pointing to the '$'. It is advanced to after the name. |
4330 {"char2nr", 1, 1, f_char2nr}, | 4562 {"char2nr", 1, 1, f_char2nr}, |
4331 {"cindent", 1, 1, f_cindent}, | 4563 {"cindent", 1, 1, f_cindent}, |
4332 {"col", 1, 1, f_col}, | 4564 {"col", 1, 1, f_col}, |
4333 {"confirm", 1, 4, f_confirm}, | 4565 {"confirm", 1, 4, f_confirm}, |
4334 {"copy", 1, 1, f_copy}, | 4566 {"copy", 1, 1, f_copy}, |
4335 {"count", 2, 3, f_count}, | 4567 {"count", 2, 4, f_count}, |
4336 {"cscope_connection",0,3, f_cscope_connection}, | 4568 {"cscope_connection",0,3, f_cscope_connection}, |
4337 {"cursor", 2, 2, f_cursor}, | 4569 {"cursor", 2, 2, f_cursor}, |
4338 {"deepcopy", 1, 1, f_deepcopy}, | 4570 {"deepcopy", 1, 1, f_deepcopy}, |
4339 {"delete", 1, 1, f_delete}, | 4571 {"delete", 1, 1, f_delete}, |
4340 {"did_filetype", 0, 0, f_did_filetype}, | 4572 {"did_filetype", 0, 0, f_did_filetype}, |
4341 {"diff_filler", 1, 1, f_diff_filler}, | 4573 {"diff_filler", 1, 1, f_diff_filler}, |
4342 {"diff_hlID", 2, 2, f_diff_hlID}, | 4574 {"diff_hlID", 2, 2, f_diff_hlID}, |
4343 {"empty", 1, 1, f_empty}, | 4575 {"empty", 1, 1, f_empty}, |
4344 {"escape", 2, 2, f_escape}, | 4576 {"escape", 2, 2, f_escape}, |
4577 {"eval", 1, 1, f_eval}, | |
4345 {"eventhandler", 0, 0, f_eventhandler}, | 4578 {"eventhandler", 0, 0, f_eventhandler}, |
4346 {"executable", 1, 1, f_executable}, | 4579 {"executable", 1, 1, f_executable}, |
4347 {"exists", 1, 1, f_exists}, | 4580 {"exists", 1, 1, f_exists}, |
4348 {"expand", 1, 2, f_expand}, | 4581 {"expand", 1, 2, f_expand}, |
4349 {"extend", 2, 3, f_extend}, | 4582 {"extend", 2, 3, f_extend}, |
4350 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ | 4583 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ |
4351 {"filereadable", 1, 1, f_filereadable}, | 4584 {"filereadable", 1, 1, f_filereadable}, |
4352 {"filewritable", 1, 1, f_filewritable}, | 4585 {"filewritable", 1, 1, f_filewritable}, |
4586 {"filter", 2, 2, f_filter}, | |
4353 {"finddir", 1, 3, f_finddir}, | 4587 {"finddir", 1, 3, f_finddir}, |
4354 {"findfile", 1, 3, f_findfile}, | 4588 {"findfile", 1, 3, f_findfile}, |
4355 {"fnamemodify", 2, 2, f_fnamemodify}, | 4589 {"fnamemodify", 2, 2, f_fnamemodify}, |
4356 {"foldclosed", 1, 1, f_foldclosed}, | 4590 {"foldclosed", 1, 1, f_foldclosed}, |
4357 {"foldclosedend", 1, 1, f_foldclosedend}, | 4591 {"foldclosedend", 1, 1, f_foldclosedend}, |
4391 {"hlID", 1, 1, f_hlID}, | 4625 {"hlID", 1, 1, f_hlID}, |
4392 {"hlexists", 1, 1, f_hlexists}, | 4626 {"hlexists", 1, 1, f_hlexists}, |
4393 {"hostname", 0, 0, f_hostname}, | 4627 {"hostname", 0, 0, f_hostname}, |
4394 {"iconv", 3, 3, f_iconv}, | 4628 {"iconv", 3, 3, f_iconv}, |
4395 {"indent", 1, 1, f_indent}, | 4629 {"indent", 1, 1, f_indent}, |
4396 {"index", 2, 3, f_index}, | 4630 {"index", 2, 4, f_index}, |
4397 {"input", 1, 2, f_input}, | 4631 {"input", 1, 2, f_input}, |
4398 {"inputdialog", 1, 3, f_inputdialog}, | 4632 {"inputdialog", 1, 3, f_inputdialog}, |
4399 {"inputrestore", 0, 0, f_inputrestore}, | 4633 {"inputrestore", 0, 0, f_inputrestore}, |
4400 {"inputsave", 0, 0, f_inputsave}, | 4634 {"inputsave", 0, 0, f_inputsave}, |
4401 {"inputsecret", 1, 2, f_inputsecret}, | 4635 {"inputsecret", 1, 2, f_inputsecret}, |
4402 {"insert", 2, 3, f_insert}, | 4636 {"insert", 2, 3, f_insert}, |
4403 {"isdirectory", 1, 1, f_isdirectory}, | 4637 {"isdirectory", 1, 1, f_isdirectory}, |
4638 {"join", 1, 2, f_join}, | |
4404 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ | 4639 {"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */ |
4405 {"len", 1, 1, f_len}, | 4640 {"len", 1, 1, f_len}, |
4406 {"libcall", 3, 3, f_libcall}, | 4641 {"libcall", 3, 3, f_libcall}, |
4407 {"libcallnr", 3, 3, f_libcallnr}, | 4642 {"libcallnr", 3, 3, f_libcallnr}, |
4408 {"line", 1, 1, f_line}, | 4643 {"line", 1, 1, f_line}, |
4409 {"line2byte", 1, 1, f_line2byte}, | 4644 {"line2byte", 1, 1, f_line2byte}, |
4410 {"lispindent", 1, 1, f_lispindent}, | 4645 {"lispindent", 1, 1, f_lispindent}, |
4411 {"localtime", 0, 0, f_localtime}, | 4646 {"localtime", 0, 0, f_localtime}, |
4647 {"map", 2, 2, f_map}, | |
4412 {"maparg", 1, 2, f_maparg}, | 4648 {"maparg", 1, 2, f_maparg}, |
4413 {"mapcheck", 1, 2, f_mapcheck}, | 4649 {"mapcheck", 1, 2, f_mapcheck}, |
4414 {"match", 2, 4, f_match}, | 4650 {"match", 2, 4, f_match}, |
4415 {"matchend", 2, 4, f_matchend}, | 4651 {"matchend", 2, 4, f_matchend}, |
4416 {"matchstr", 2, 4, f_matchstr}, | 4652 {"matchstr", 2, 4, f_matchstr}, |
4439 {"setline", 2, 2, f_setline}, | 4675 {"setline", 2, 2, f_setline}, |
4440 {"setreg", 2, 3, f_setreg}, | 4676 {"setreg", 2, 3, f_setreg}, |
4441 {"setwinvar", 3, 3, f_setwinvar}, | 4677 {"setwinvar", 3, 3, f_setwinvar}, |
4442 {"simplify", 1, 1, f_simplify}, | 4678 {"simplify", 1, 1, f_simplify}, |
4443 {"sort", 1, 2, f_sort}, | 4679 {"sort", 1, 2, f_sort}, |
4444 {"str2list", 1, 2, f_str2list}, | 4680 {"split", 1, 2, f_split}, |
4445 #ifdef HAVE_STRFTIME | 4681 #ifdef HAVE_STRFTIME |
4446 {"strftime", 1, 2, f_strftime}, | 4682 {"strftime", 1, 2, f_strftime}, |
4447 #endif | 4683 #endif |
4448 {"stridx", 2, 2, f_stridx}, | 4684 {"stridx", 2, 2, f_stridx}, |
4449 {"string", 1, 1, f_string}, | 4685 {"string", 1, 1, f_string}, |
5475 | 5711 |
5476 if (argvars[0].v_type != VAR_LIST) | 5712 if (argvars[0].v_type != VAR_LIST) |
5477 EMSG(_(e_listreq)); | 5713 EMSG(_(e_listreq)); |
5478 else if (argvars[0].vval.v_list != NULL) | 5714 else if (argvars[0].vval.v_list != NULL) |
5479 { | 5715 { |
5716 li = argvars[0].vval.v_list->lv_first; | |
5480 if (argvars[2].v_type != VAR_UNKNOWN) | 5717 if (argvars[2].v_type != VAR_UNKNOWN) |
5481 ic = get_tv_number(&argvars[2]); | 5718 { |
5482 | 5719 for (n = get_tv_number(&argvars[2]); n > 0 && li != NULL; |
5483 for (li = argvars[0].vval.v_list->lv_first; li != NULL; | |
5484 li = li->li_next) | 5720 li = li->li_next) |
5721 --n; | |
5722 if (argvars[3].v_type != VAR_UNKNOWN) | |
5723 ic = get_tv_number(&argvars[3]); | |
5724 } | |
5725 | |
5726 n = 0; | |
5727 for ( ; li != NULL; li = li->li_next) | |
5485 if (tv_equal(&li->li_tv, &argvars[1], ic)) | 5728 if (tv_equal(&li->li_tv, &argvars[1], ic)) |
5486 ++n; | 5729 ++n; |
5487 } | 5730 } |
5488 rettv->vval.v_number = n; | 5731 rettv->vval.v_number = n; |
5489 } | 5732 } |
5721 get_tv_string_buf(&argvars[1], buf)); | 5964 get_tv_string_buf(&argvars[1], buf)); |
5722 rettv->v_type = VAR_STRING; | 5965 rettv->v_type = VAR_STRING; |
5723 } | 5966 } |
5724 | 5967 |
5725 /* | 5968 /* |
5969 * "eval()" function | |
5970 */ | |
5971 /*ARGSUSED*/ | |
5972 static void | |
5973 f_eval(argvars, rettv) | |
5974 typeval *argvars; | |
5975 typeval *rettv; | |
5976 { | |
5977 char_u *s; | |
5978 | |
5979 s = get_tv_string(&argvars[0]); | |
5980 s = skipwhite(s); | |
5981 | |
5982 if (eval1(&s, rettv, TRUE) == FAIL) | |
5983 rettv->vval.v_number = 0; | |
5984 else if (*s != NUL) | |
5985 EMSG(_(e_trailing)); | |
5986 } | |
5987 | |
5988 /* | |
5726 * "eventhandler()" function | 5989 * "eventhandler()" function |
5727 */ | 5990 */ |
5728 /*ARGSUSED*/ | 5991 /*ARGSUSED*/ |
5729 static void | 5992 static void |
5730 f_eventhandler(argvars, rettv) | 5993 f_eventhandler(argvars, rettv) |
6007 rettv->vval.v_string = NULL; | 6270 rettv->vval.v_string = NULL; |
6008 #endif | 6271 #endif |
6009 rettv->v_type = VAR_STRING; | 6272 rettv->v_type = VAR_STRING; |
6010 } | 6273 } |
6011 | 6274 |
6275 static void filter_map __ARGS((typeval *argvars, typeval *rettv, int map)); | |
6276 | |
6277 /* | |
6278 * Implementation of map() and filter(). | |
6279 */ | |
6280 static void | |
6281 filter_map(argvars, rettv, map) | |
6282 typeval *argvars; | |
6283 typeval *rettv; | |
6284 int map; | |
6285 { | |
6286 char_u buf[NUMBUFLEN]; | |
6287 char_u *expr, *s; | |
6288 listitem *li, *nli; | |
6289 listvar *l; | |
6290 | |
6291 rettv->vval.v_number = 0; | |
6292 if (argvars[0].v_type != VAR_LIST) | |
6293 EMSG(_(e_listreq)); | |
6294 else if ((l = argvars[0].vval.v_list) != NULL) | |
6295 { | |
6296 expr = skipwhite(get_tv_string_buf(&argvars[1], buf)); | |
6297 for (li = l->lv_first; li != NULL; li = nli) | |
6298 { | |
6299 copy_tv(&li->li_tv, &_tv); | |
6300 s = expr; | |
6301 if (eval1(&s, rettv, TRUE) == FAIL) | |
6302 break; | |
6303 if (*s != NUL) /* check for trailing chars after expr */ | |
6304 { | |
6305 EMSG2(_(e_invexpr2), s); | |
6306 break; | |
6307 } | |
6308 nli = li->li_next; | |
6309 if (map) | |
6310 { | |
6311 /* map(): replace the list item value */ | |
6312 clear_tv(&li->li_tv); | |
6313 li->li_tv = *rettv; | |
6314 } | |
6315 else | |
6316 { | |
6317 /* filter(): when expr is zero remove the item */ | |
6318 if (get_tv_number(rettv) == 0) | |
6319 { | |
6320 list_getrem(l, li, li); | |
6321 clear_tv(&li->li_tv); | |
6322 } | |
6323 clear_tv(rettv); | |
6324 } | |
6325 clear_tv(&_tv); | |
6326 } | |
6327 | |
6328 clear_tv(&_tv); | |
6329 amp_tv.v_type = VAR_UNKNOWN; | |
6330 | |
6331 copy_tv(&argvars[0], rettv); | |
6332 } | |
6333 } | |
6334 | |
6335 /* | |
6336 * "filter()" function | |
6337 */ | |
6338 static void | |
6339 f_filter(argvars, rettv) | |
6340 typeval *argvars; | |
6341 typeval *rettv; | |
6342 { | |
6343 filter_map(argvars, rettv, FALSE); | |
6344 } | |
6345 | |
6012 /* | 6346 /* |
6013 * "finddir({fname}[, {path}[, {count}]])" function | 6347 * "finddir({fname}[, {path}[, {count}]])" function |
6014 */ | 6348 */ |
6015 static void | 6349 static void |
6016 f_finddir(argvars, rettv) | 6350 f_finddir(argvars, rettv) |
6262 typeval *rettv; | 6596 typeval *rettv; |
6263 { | 6597 { |
6264 char_u *s; | 6598 char_u *s; |
6265 | 6599 |
6266 s = get_tv_string(&argvars[0]); | 6600 s = get_tv_string(&argvars[0]); |
6267 if (s == NULL || *s == NUL || isdigit(*s)) | 6601 if (s == NULL || *s == NUL || VIM_ISDIGIT(*s)) |
6268 EMSG2(_(e_invarg2), s); | 6602 EMSG2(_(e_invarg2), s); |
6269 else if (!function_exists(s)) | 6603 else if (!function_exists(s)) |
6270 EMSG2(_("E700: Unknown function: %s"), s); | 6604 EMSG2(_("E700: Unknown function: %s"), s); |
6271 else | 6605 else |
6272 { | 6606 { |
7634 typeval *rettv; | 7968 typeval *rettv; |
7635 { | 7969 { |
7636 listvar *l; | 7970 listvar *l; |
7637 listitem *item; | 7971 listitem *item; |
7638 long idx = 0; | 7972 long idx = 0; |
7973 long min_idx = 0; | |
7639 int ic = FALSE; | 7974 int ic = FALSE; |
7640 | 7975 |
7641 rettv->vval.v_number = -1; | 7976 rettv->vval.v_number = -1; |
7642 if (argvars[0].v_type != VAR_LIST) | 7977 if (argvars[0].v_type != VAR_LIST) |
7643 { | 7978 { |
7646 } | 7981 } |
7647 l = argvars[0].vval.v_list; | 7982 l = argvars[0].vval.v_list; |
7648 if (l != NULL) | 7983 if (l != NULL) |
7649 { | 7984 { |
7650 if (argvars[2].v_type != VAR_UNKNOWN) | 7985 if (argvars[2].v_type != VAR_UNKNOWN) |
7651 ic = get_tv_number(&argvars[2]); | 7986 { |
7987 min_idx = get_tv_number(&argvars[2]); | |
7988 if (argvars[3].v_type != VAR_UNKNOWN) | |
7989 ic = get_tv_number(&argvars[3]); | |
7990 } | |
7652 | 7991 |
7653 for (item = l->lv_first; item != NULL; item = item->li_next, ++idx) | 7992 for (item = l->lv_first; item != NULL; item = item->li_next, ++idx) |
7654 if (tv_equal(&item->li_tv, &argvars[1], ic)) | 7993 if (idx >= min_idx && tv_equal(&item->li_tv, &argvars[1], ic)) |
7655 { | 7994 { |
7656 rettv->vval.v_number = idx; | 7995 rettv->vval.v_number = idx; |
7657 break; | 7996 break; |
7658 } | 7997 } |
7659 } | 7998 } |
7865 f_isdirectory(argvars, rettv) | 8204 f_isdirectory(argvars, rettv) |
7866 typeval *argvars; | 8205 typeval *argvars; |
7867 typeval *rettv; | 8206 typeval *rettv; |
7868 { | 8207 { |
7869 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); | 8208 rettv->vval.v_number = mch_isdir(get_tv_string(&argvars[0])); |
8209 } | |
8210 | |
8211 /* | |
8212 * "join()" function | |
8213 */ | |
8214 static void | |
8215 f_join(argvars, rettv) | |
8216 typeval *argvars; | |
8217 typeval *rettv; | |
8218 { | |
8219 garray_T ga; | |
8220 char_u *sep; | |
8221 | |
8222 rettv->vval.v_number = 0; | |
8223 if (argvars[0].v_type != VAR_LIST) | |
8224 { | |
8225 EMSG(_(e_listreq)); | |
8226 return; | |
8227 } | |
8228 if (argvars[0].vval.v_list == NULL) | |
8229 return; | |
8230 if (argvars[1].v_type == VAR_UNKNOWN) | |
8231 sep = (char_u *)" "; | |
8232 else | |
8233 sep = get_tv_string(&argvars[1]); | |
8234 | |
8235 ga_init2(&ga, (int)sizeof(char), 80); | |
8236 list_join(&ga, argvars[0].vval.v_list, sep, TRUE); | |
8237 ga_append(&ga, NUL); | |
8238 | |
8239 rettv->v_type = VAR_STRING; | |
8240 rettv->vval.v_string = (char_u *)ga.ga_data; | |
7870 } | 8241 } |
7871 | 8242 |
7872 /* | 8243 /* |
7873 * "last_buffer_nr()" function. | 8244 * "last_buffer_nr()" function. |
7874 */ | 8245 */ |
8105 rettv->vval.v_string = (char_u *)ga.ga_data; | 8476 rettv->vval.v_string = (char_u *)ga.ga_data; |
8106 } | 8477 } |
8107 } | 8478 } |
8108 | 8479 |
8109 /* | 8480 /* |
8481 * "map()" function | |
8482 */ | |
8483 static void | |
8484 f_map(argvars, rettv) | |
8485 typeval *argvars; | |
8486 typeval *rettv; | |
8487 { | |
8488 filter_map(argvars, rettv, TRUE); | |
8489 } | |
8490 | |
8491 /* | |
8110 * "maparg()" function | 8492 * "maparg()" function |
8111 */ | 8493 */ |
8112 static void | 8494 static void |
8113 f_maparg(argvars, rettv) | 8495 f_maparg(argvars, rettv) |
8114 typeval *argvars; | 8496 typeval *argvars; |
8134 find_some_match(argvars, rettv, type) | 8516 find_some_match(argvars, rettv, type) |
8135 typeval *argvars; | 8517 typeval *argvars; |
8136 typeval *rettv; | 8518 typeval *rettv; |
8137 int type; | 8519 int type; |
8138 { | 8520 { |
8139 char_u *str; | 8521 char_u *str = NULL; |
8140 char_u *expr; | 8522 char_u *expr = NULL; |
8141 char_u *pat; | 8523 char_u *pat; |
8142 regmatch_T regmatch; | 8524 regmatch_T regmatch; |
8143 char_u patbuf[NUMBUFLEN]; | 8525 char_u patbuf[NUMBUFLEN]; |
8526 char_u strbuf[NUMBUFLEN]; | |
8144 char_u *save_cpo; | 8527 char_u *save_cpo; |
8145 long start = 0; | 8528 long start = 0; |
8146 long nth = 1; | 8529 long nth = 1; |
8147 int match; | 8530 int match; |
8531 listvar *l = NULL; | |
8532 listitem *li = NULL; | |
8533 long idx = 0; | |
8534 char_u *tofree; | |
8148 | 8535 |
8149 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ | 8536 /* Make 'cpoptions' empty, the 'l' flag should not be used here. */ |
8150 save_cpo = p_cpo; | 8537 save_cpo = p_cpo; |
8151 p_cpo = (char_u *)""; | 8538 p_cpo = (char_u *)""; |
8152 | 8539 |
8153 expr = str = get_tv_string(&argvars[0]); | |
8154 pat = get_tv_string_buf(&argvars[1], patbuf); | |
8155 | |
8156 if (type == 2) | 8540 if (type == 2) |
8157 { | 8541 { |
8158 rettv->v_type = VAR_STRING; | 8542 rettv->v_type = VAR_STRING; |
8159 rettv->vval.v_string = NULL; | 8543 rettv->vval.v_string = NULL; |
8160 } | 8544 } |
8161 else | 8545 else |
8162 rettv->vval.v_number = -1; | 8546 rettv->vval.v_number = -1; |
8163 | 8547 |
8548 if (argvars[0].v_type == VAR_LIST) | |
8549 { | |
8550 if ((l = argvars[0].vval.v_list) == NULL) | |
8551 goto theend; | |
8552 li = l->lv_first; | |
8553 } | |
8554 else | |
8555 expr = str = get_tv_string(&argvars[0]); | |
8556 | |
8557 pat = get_tv_string_buf(&argvars[1], patbuf); | |
8558 | |
8164 if (argvars[2].v_type != VAR_UNKNOWN) | 8559 if (argvars[2].v_type != VAR_UNKNOWN) |
8165 { | 8560 { |
8166 start = get_tv_number(&argvars[2]); | 8561 start = get_tv_number(&argvars[2]); |
8167 if (start < 0) | 8562 if (l != NULL) |
8168 start = 0; | 8563 { |
8169 if (start > (long)STRLEN(str)) | 8564 li = list_find(l, start); |
8170 goto theend; | 8565 if (li == NULL) |
8171 str += start; | 8566 goto theend; |
8567 if (start < 0) | |
8568 { | |
8569 listitem *ni; | |
8570 | |
8571 /* Need to compute the index. */ | |
8572 for (ni = li; ni->li_prev != NULL; ni = ni->li_prev) | |
8573 ++idx; | |
8574 } | |
8575 else | |
8576 idx = start; | |
8577 } | |
8578 else | |
8579 { | |
8580 if (start < 0) | |
8581 start = 0; | |
8582 if (start > (long)STRLEN(str)) | |
8583 goto theend; | |
8584 str += start; | |
8585 } | |
8172 | 8586 |
8173 if (argvars[3].v_type != VAR_UNKNOWN) | 8587 if (argvars[3].v_type != VAR_UNKNOWN) |
8174 nth = get_tv_number(&argvars[3]); | 8588 nth = get_tv_number(&argvars[3]); |
8175 } | 8589 } |
8176 | 8590 |
8179 { | 8593 { |
8180 regmatch.rm_ic = p_ic; | 8594 regmatch.rm_ic = p_ic; |
8181 | 8595 |
8182 while (1) | 8596 while (1) |
8183 { | 8597 { |
8598 if (l != NULL) | |
8599 { | |
8600 if (li == NULL) | |
8601 { | |
8602 match = FALSE; | |
8603 break; | |
8604 } | |
8605 str = echo_string(&li->li_tv, &tofree, strbuf); | |
8606 } | |
8607 | |
8184 match = vim_regexec_nl(®match, str, (colnr_T)0); | 8608 match = vim_regexec_nl(®match, str, (colnr_T)0); |
8185 if (!match || --nth <= 0) | 8609 |
8610 if (l != NULL) | |
8611 vim_free(tofree); | |
8612 if (match && --nth <= 0) | |
8186 break; | 8613 break; |
8614 if (l == NULL && !match) | |
8615 break; | |
8616 | |
8187 /* Advance to just after the match. */ | 8617 /* Advance to just after the match. */ |
8618 if (l != NULL) | |
8619 { | |
8620 li = li->li_next; | |
8621 ++idx; | |
8622 } | |
8623 else | |
8624 { | |
8188 #ifdef FEAT_MBYTE | 8625 #ifdef FEAT_MBYTE |
8189 str = regmatch.startp[0] + mb_ptr2len_check(regmatch.startp[0]); | 8626 str = regmatch.startp[0] + mb_ptr2len_check(regmatch.startp[0]); |
8190 #else | 8627 #else |
8191 str = regmatch.startp[0] + 1; | 8628 str = regmatch.startp[0] + 1; |
8192 #endif | 8629 #endif |
8630 } | |
8193 } | 8631 } |
8194 | 8632 |
8195 if (match) | 8633 if (match) |
8196 { | 8634 { |
8197 if (type == 2) | 8635 if (type == 2) |
8198 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], | 8636 { |
8637 if (l != NULL) | |
8638 copy_tv(&li->li_tv, rettv); | |
8639 else | |
8640 rettv->vval.v_string = vim_strnsave(regmatch.startp[0], | |
8199 (int)(regmatch.endp[0] - regmatch.startp[0])); | 8641 (int)(regmatch.endp[0] - regmatch.startp[0])); |
8642 } | |
8643 else if (l != NULL) | |
8644 rettv->vval.v_number = idx; | |
8200 else | 8645 else |
8201 { | 8646 { |
8202 if (type != 0) | 8647 if (type != 0) |
8203 rettv->vval.v_number = | 8648 rettv->vval.v_number = |
8204 (varnumber_T)(regmatch.startp[0] - str); | 8649 (varnumber_T)(regmatch.startp[0] - str); |
9687 vim_free(ptrs); | 10132 vim_free(ptrs); |
9688 } | 10133 } |
9689 } | 10134 } |
9690 | 10135 |
9691 static void | 10136 static void |
9692 f_str2list(argvars, rettv) | 10137 f_split(argvars, rettv) |
9693 typeval *argvars; | 10138 typeval *argvars; |
9694 typeval *rettv; | 10139 typeval *rettv; |
9695 { | 10140 { |
9696 char_u *str; | 10141 char_u *str; |
9697 char_u *end; | 10142 char_u *end; |
11311 { | 11756 { |
11312 case VAR_NUMBER: | 11757 case VAR_NUMBER: |
11313 n = (long)(varp->vval.v_number); | 11758 n = (long)(varp->vval.v_number); |
11314 break; | 11759 break; |
11315 case VAR_FUNC: | 11760 case VAR_FUNC: |
11316 EMSG(_("E703: Using function reference as a number")); | 11761 EMSG(_("E703: Using a Funcref as a number")); |
11317 break; | 11762 break; |
11318 case VAR_STRING: | 11763 case VAR_STRING: |
11319 if (varp->vval.v_string != NULL) | 11764 if (varp->vval.v_string != NULL) |
11320 vim_str2nr(varp->vval.v_string, NULL, NULL, | 11765 vim_str2nr(varp->vval.v_string, NULL, NULL, |
11321 TRUE, TRUE, &n, NULL); | 11766 TRUE, TRUE, &n, NULL); |
11767 break; | |
11768 case VAR_LIST: | |
11769 EMSG(_("E703: Using a List as a number")); | |
11322 break; | 11770 break; |
11323 default: | 11771 default: |
11324 break; | 11772 break; |
11325 } | 11773 } |
11326 return n; | 11774 return n; |
11390 } | 11838 } |
11391 return (char_u *)""; | 11839 return (char_u *)""; |
11392 } | 11840 } |
11393 | 11841 |
11394 /* | 11842 /* |
11843 * Get value for "&", as used in map() and filter(). | |
11844 */ | |
11845 static int | |
11846 get_amp_tv(rettv) | |
11847 typeval *rettv; | |
11848 { | |
11849 if (amp_tv.v_type == VAR_UNKNOWN) | |
11850 { | |
11851 EMSG(_("E712: Using & outside of map() or filter()")); | |
11852 return FAIL; | |
11853 } | |
11854 copy_tv(&_tv, rettv); | |
11855 return OK; | |
11856 } | |
11857 | |
11858 /* | |
11395 * Find variable "name" in the list of variables. | 11859 * Find variable "name" in the list of variables. |
11396 * Return a pointer to it if found, NULL if not found. | 11860 * Return a pointer to it if found, NULL if not found. |
11397 * Careful: "a:0" variables don't have a name. | 11861 * Careful: "a:0" variables don't have a name. |
11398 */ | 11862 */ |
11399 static VAR | 11863 static VAR |
11571 { | 12035 { |
11572 char_u *tofree; | 12036 char_u *tofree; |
11573 char_u *s; | 12037 char_u *s; |
11574 char_u numbuf[NUMBUFLEN]; | 12038 char_u numbuf[NUMBUFLEN]; |
11575 | 12039 |
11576 s = tv2string(&v->tv, &tofree, numbuf); | 12040 s = echo_string(&v->tv, &tofree, numbuf); |
11577 list_one_var_a(prefix, v->v_name, v->tv.v_type, | 12041 list_one_var_a(prefix, v->v_name, v->tv.v_type, |
11578 s == NULL ? (char_u *)"" : s); | 12042 s == NULL ? (char_u *)"" : s); |
11579 vim_free(tofree); | 12043 vim_free(tofree); |
11580 } | 12044 } |
11581 | 12045 |
11824 if (eap->cmdidx == CMD_echo) | 12288 if (eap->cmdidx == CMD_echo) |
11825 msg_start(); | 12289 msg_start(); |
11826 } | 12290 } |
11827 else if (eap->cmdidx == CMD_echo) | 12291 else if (eap->cmdidx == CMD_echo) |
11828 msg_puts_attr((char_u *)" ", echo_attr); | 12292 msg_puts_attr((char_u *)" ", echo_attr); |
11829 for (p = tv2string(&rettv, &tofree, numbuf); | 12293 for (p = echo_string(&rettv, &tofree, numbuf); |
11830 *p != NUL && !got_int; ++p) | 12294 *p != NUL && !got_int; ++p) |
11831 if (*p == '\n' || *p == '\r' || *p == TAB) | 12295 if (*p == '\n' || *p == '\r' || *p == TAB) |
11832 { | 12296 { |
11833 if (*p != TAB && needclr) | 12297 if (*p != TAB && needclr) |
11834 { | 12298 { |
12247 { | 12711 { |
12248 /* skip ':' and blanks*/ | 12712 /* skip ':' and blanks*/ |
12249 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) | 12713 for (p = theline; vim_iswhite(*p) || *p == ':'; ++p) |
12250 ; | 12714 ; |
12251 | 12715 |
12252 /* Check for "endfunction" (should be more strict...). */ | 12716 /* Check for "endfunction". */ |
12253 if (STRNCMP(p, "endf", 4) == 0 && nesting-- == 0) | 12717 if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) |
12254 { | 12718 { |
12255 vim_free(theline); | 12719 vim_free(theline); |
12256 break; | 12720 break; |
12257 } | 12721 } |
12258 | 12722 |
12259 /* Increase indent inside "if", "while", and "try", decrease | 12723 /* Increase indent inside "if", "while", "for" and "try", decrease |
12260 * at "end". */ | 12724 * at "end". */ |
12261 if (indent > 2 && STRNCMP(p, "end", 3) == 0) | 12725 if (indent > 2 && STRNCMP(p, "end", 3) == 0) |
12262 indent -= 2; | 12726 indent -= 2; |
12263 else if (STRNCMP(p, "if", 2) == 0 || STRNCMP(p, "wh", 2) == 0 | 12727 else if (STRNCMP(p, "if", 2) == 0 |
12728 || STRNCMP(p, "wh", 2) == 0 | |
12729 || STRNCMP(p, "for", 3) == 0 | |
12264 || STRNCMP(p, "try", 3) == 0) | 12730 || STRNCMP(p, "try", 3) == 0) |
12265 indent += 2; | 12731 indent += 2; |
12266 | 12732 |
12267 /* Check for defining a function inside this function. */ | 12733 /* Check for defining a function inside this function. */ |
12268 if (STRNCMP(p, "fu", 2) == 0) | 12734 if (checkforcmd(&p, "function", 2)) |
12269 { | 12735 { |
12270 p = skipwhite(skiptowhite(p)); | 12736 if (*p == '!') |
12737 p = skipwhite(p + 1); | |
12271 p += eval_fname_script(p); | 12738 p += eval_fname_script(p); |
12272 if (ASCII_ISALPHA(*p)) | 12739 if (ASCII_ISALPHA(*p)) |
12273 { | 12740 { |
12274 vim_free(trans_function_name(&p, TRUE, FALSE)); | 12741 vim_free(trans_function_name(&p, TRUE, FALSE)); |
12275 if (*skipwhite(p) == '(') | 12742 if (*skipwhite(p) == '(') |
13040 char_u numbuf[NUMBUFLEN]; | 13507 char_u numbuf[NUMBUFLEN]; |
13041 | 13508 |
13042 if (rettv == NULL) | 13509 if (rettv == NULL) |
13043 s = (char_u *)""; | 13510 s = (char_u *)""; |
13044 else | 13511 else |
13045 s = tv2string((typeval *)rettv, &tofree, numbuf); | 13512 s = echo_string((typeval *)rettv, &tofree, numbuf); |
13046 | 13513 |
13047 STRCPY(IObuff, ":return "); | 13514 STRCPY(IObuff, ":return "); |
13048 STRNCPY(IObuff + 8, s, IOSIZE - 8); | 13515 STRNCPY(IObuff + 8, s, IOSIZE - 8); |
13049 if (STRLEN(s) + 8 >= IOSIZE) | 13516 if (STRLEN(s) + 8 >= IOSIZE) |
13050 STRCPY(IObuff + IOSIZE - 4, "..."); | 13517 STRCPY(IObuff + IOSIZE - 4, "..."); |
13229 case VAR_STRING: s = "STR"; break; | 13696 case VAR_STRING: s = "STR"; break; |
13230 case VAR_NUMBER: s = "NUM"; break; | 13697 case VAR_NUMBER: s = "NUM"; break; |
13231 default: continue; | 13698 default: continue; |
13232 } | 13699 } |
13233 fprintf(fp, "!%s\t%s\t", this_var->v_name, s); | 13700 fprintf(fp, "!%s\t%s\t", this_var->v_name, s); |
13234 viminfo_writestring(fp, tv2string(&this_var->tv, &tofree, numbuf)); | 13701 viminfo_writestring(fp, echo_string(&this_var->tv, |
13702 &tofree, numbuf)); | |
13235 vim_free(tofree); | 13703 vim_free(tofree); |
13236 } | 13704 } |
13237 } | 13705 } |
13238 } | 13706 } |
13239 #endif | 13707 #endif |