Mercurial > vim
comparison src/eval.c @ 18777:3a68dc2a1bc1 v8.1.2378
patch 8.1.2378: using old C style comments
Commit: https://github.com/vim/vim/commit/5d18efecfd6c45d69f55268948a22cd0465bb955
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Dec 1 21:11:22 2019 +0100
patch 8.1.2378: using old C style comments
Problem: Using old C style comments.
Solution: Use // comments where appropriate.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 01 Dec 2019 21:15:03 +0100 |
parents | 49b78d6465e5 |
children | 3cf9529b3a4a |
comparison
equal
deleted
inserted
replaced
18776:90a6831d6cd7 | 18777:3a68dc2a1bc1 |
---|---|
34 * have done to avoid endless recursiveness. This unique ID is used for that. | 34 * have done to avoid endless recursiveness. This unique ID is used for that. |
35 * The last bit is used for previous_funccal, ignored when comparing. | 35 * The last bit is used for previous_funccal, ignored when comparing. |
36 */ | 36 */ |
37 static int current_copyID = 0; | 37 static int current_copyID = 0; |
38 | 38 |
39 static int echo_attr = 0; /* attributes used for ":echo" */ | 39 static int echo_attr = 0; // attributes used for ":echo" |
40 | 40 |
41 /* | 41 /* |
42 * Info used by a ":for" loop. | 42 * Info used by a ":for" loop. |
43 */ | 43 */ |
44 typedef struct | 44 typedef struct |
45 { | 45 { |
46 int fi_semicolon; /* TRUE if ending in '; var]' */ | 46 int fi_semicolon; // TRUE if ending in '; var]' |
47 int fi_varcount; /* nr of variables in the list */ | 47 int fi_varcount; // nr of variables in the list |
48 listwatch_T fi_lw; /* keep an eye on the item used. */ | 48 listwatch_T fi_lw; // keep an eye on the item used. |
49 list_T *fi_list; /* list being used */ | 49 list_T *fi_list; // list being used |
50 int fi_bi; /* index of blob */ | 50 int fi_bi; // index of blob |
51 blob_T *fi_blob; /* blob being used */ | 51 blob_T *fi_blob; // blob being used |
52 } forinfo_T; | 52 } forinfo_T; |
53 | 53 |
54 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op); | 54 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op); |
55 static int eval2(char_u **arg, typval_T *rettv, int evaluate); | 55 static int eval2(char_u **arg, typval_T *rettv, int evaluate); |
56 static int eval3(char_u **arg, typval_T *rettv, int evaluate); | 56 static int eval3(char_u **arg, typval_T *rettv, int evaluate); |
172 int | 172 int |
173 eval_to_bool( | 173 eval_to_bool( |
174 char_u *arg, | 174 char_u *arg, |
175 int *error, | 175 int *error, |
176 char_u **nextcmd, | 176 char_u **nextcmd, |
177 int skip) /* only parse, don't execute */ | 177 int skip) // only parse, don't execute |
178 { | 178 { |
179 typval_T tv; | 179 typval_T tv; |
180 varnumber_T retval = FALSE; | 180 varnumber_T retval = FALSE; |
181 | 181 |
182 if (skip) | 182 if (skip) |
259 if (s == NULL) | 259 if (s == NULL) |
260 return FAIL; | 260 return FAIL; |
261 s = skipwhite(s); | 261 s = skipwhite(s); |
262 if (eval1_emsg(&s, rettv, TRUE) == FAIL) | 262 if (eval1_emsg(&s, rettv, TRUE) == FAIL) |
263 return FAIL; | 263 return FAIL; |
264 if (*s != NUL) /* check for trailing chars after expr */ | 264 if (*s != NUL) // check for trailing chars after expr |
265 { | 265 { |
266 clear_tv(rettv); | 266 clear_tv(rettv); |
267 semsg(_(e_invexpr2), s); | 267 semsg(_(e_invexpr2), s); |
268 return FAIL; | 268 return FAIL; |
269 } | 269 } |
298 */ | 298 */ |
299 char_u * | 299 char_u * |
300 eval_to_string_skip( | 300 eval_to_string_skip( |
301 char_u *arg, | 301 char_u *arg, |
302 char_u **nextcmd, | 302 char_u **nextcmd, |
303 int skip) /* only parse, don't execute */ | 303 int skip) // only parse, don't execute |
304 { | 304 { |
305 typval_T tv; | 305 typval_T tv; |
306 char_u *retval; | 306 char_u *retval; |
307 | 307 |
308 if (skip) | 308 if (skip) |
465 typval_T *rettv) | 465 typval_T *rettv) |
466 { | 466 { |
467 int ret; | 467 int ret; |
468 funcexe_T funcexe; | 468 funcexe_T funcexe; |
469 | 469 |
470 rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */ | 470 rettv->v_type = VAR_UNKNOWN; // clear_tv() uses this |
471 vim_memset(&funcexe, 0, sizeof(funcexe)); | 471 vim_memset(&funcexe, 0, sizeof(funcexe)); |
472 funcexe.firstline = curwin->w_cursor.lnum; | 472 funcexe.firstline = curwin->w_cursor.lnum; |
473 funcexe.lastline = curwin->w_cursor.lnum; | 473 funcexe.lastline = curwin->w_cursor.lnum; |
474 funcexe.evaluate = TRUE; | 474 funcexe.evaluate = TRUE; |
475 ret = call_func(func, -1, rettv, argc, argv, &funcexe); | 475 ret = call_func(func, -1, rettv, argc, argv, &funcexe); |
572 *cp = NUL; | 572 *cp = NUL; |
573 if (eval0(arg, &tv, NULL, TRUE) == FAIL) | 573 if (eval0(arg, &tv, NULL, TRUE) == FAIL) |
574 retval = 0; | 574 retval = 0; |
575 else | 575 else |
576 { | 576 { |
577 /* If the result is a number, just return the number. */ | 577 // If the result is a number, just return the number. |
578 if (tv.v_type == VAR_NUMBER) | 578 if (tv.v_type == VAR_NUMBER) |
579 retval = tv.vval.v_number; | 579 retval = tv.vval.v_number; |
580 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) | 580 else if (tv.v_type != VAR_STRING || tv.vval.v_string == NULL) |
581 retval = 0; | 581 retval = 0; |
582 else | 582 else |
583 { | 583 { |
584 /* If the result is a string, check if there is a non-digit before | 584 // If the result is a string, check if there is a non-digit before |
585 * the number. */ | 585 // the number. |
586 s = tv.vval.v_string; | 586 s = tv.vval.v_string; |
587 if (!VIM_ISDIGIT(*s) && *s != '-') | 587 if (!VIM_ISDIGIT(*s) && *s != '-') |
588 *cp = *s++; | 588 *cp = *s++; |
589 retval = atol((char *)s); | 589 retval = atol((char *)s); |
590 } | 590 } |
623 char_u *name, | 623 char_u *name, |
624 typval_T *rettv, | 624 typval_T *rettv, |
625 lval_T *lp, | 625 lval_T *lp, |
626 int unlet, | 626 int unlet, |
627 int skip, | 627 int skip, |
628 int flags, /* GLV_ values */ | 628 int flags, // GLV_ values |
629 int fne_flags) /* flags for find_name_end() */ | 629 int fne_flags) // flags for find_name_end() |
630 { | 630 { |
631 char_u *p; | 631 char_u *p; |
632 char_u *expr_start, *expr_end; | 632 char_u *expr_start, *expr_end; |
633 int cc; | 633 int cc; |
634 dictitem_T *v; | 634 dictitem_T *v; |
639 char_u *key = NULL; | 639 char_u *key = NULL; |
640 int len; | 640 int len; |
641 hashtab_T *ht; | 641 hashtab_T *ht; |
642 int quiet = flags & GLV_QUIET; | 642 int quiet = flags & GLV_QUIET; |
643 | 643 |
644 /* Clear everything in "lp". */ | 644 // Clear everything in "lp". |
645 vim_memset(lp, 0, sizeof(lval_T)); | 645 vim_memset(lp, 0, sizeof(lval_T)); |
646 | 646 |
647 if (skip) | 647 if (skip) |
648 { | 648 { |
649 /* When skipping just find the end of the name. */ | 649 // When skipping just find the end of the name. |
650 lp->ll_name = name; | 650 lp->ll_name = name; |
651 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); | 651 return find_name_end(name, NULL, NULL, FNE_INCL_BR | fne_flags); |
652 } | 652 } |
653 | 653 |
654 /* Find the end of the name. */ | 654 // Find the end of the name. |
655 p = find_name_end(name, &expr_start, &expr_end, fne_flags); | 655 p = find_name_end(name, &expr_start, &expr_end, fne_flags); |
656 if (expr_start != NULL) | 656 if (expr_start != NULL) |
657 { | 657 { |
658 /* Don't expand the name when we already know there is an error. */ | 658 // Don't expand the name when we already know there is an error. |
659 if (unlet && !VIM_ISWHITE(*p) && !ends_excmd(*p) | 659 if (unlet && !VIM_ISWHITE(*p) && !ends_excmd(*p) |
660 && *p != '[' && *p != '.') | 660 && *p != '[' && *p != '.') |
661 { | 661 { |
662 emsg(_(e_trailing)); | 662 emsg(_(e_trailing)); |
663 return NULL; | 663 return NULL; |
664 } | 664 } |
665 | 665 |
666 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); | 666 lp->ll_exp_name = make_expanded_name(name, expr_start, expr_end, p); |
667 if (lp->ll_exp_name == NULL) | 667 if (lp->ll_exp_name == NULL) |
668 { | 668 { |
669 /* Report an invalid expression in braces, unless the | 669 // Report an invalid expression in braces, unless the |
670 * expression evaluation has been cancelled due to an | 670 // expression evaluation has been cancelled due to an |
671 * aborting error, an interrupt, or an exception. */ | 671 // aborting error, an interrupt, or an exception. |
672 if (!aborting() && !quiet) | 672 if (!aborting() && !quiet) |
673 { | 673 { |
674 emsg_severe = TRUE; | 674 emsg_severe = TRUE; |
675 semsg(_(e_invarg2), name); | 675 semsg(_(e_invarg2), name); |
676 return NULL; | 676 return NULL; |
679 lp->ll_name = lp->ll_exp_name; | 679 lp->ll_name = lp->ll_exp_name; |
680 } | 680 } |
681 else | 681 else |
682 lp->ll_name = name; | 682 lp->ll_name = name; |
683 | 683 |
684 /* Without [idx] or .key we are done. */ | 684 // Without [idx] or .key we are done. |
685 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) | 685 if ((*p != '[' && *p != '.') || lp->ll_name == NULL) |
686 return p; | 686 return p; |
687 | 687 |
688 cc = *p; | 688 cc = *p; |
689 *p = NUL; | 689 *p = NUL; |
690 /* Only pass &ht when we would write to the variable, it prevents autoload | 690 // Only pass &ht when we would write to the variable, it prevents autoload |
691 * as well. */ | 691 // as well. |
692 v = find_var(lp->ll_name, (flags & GLV_READ_ONLY) ? NULL : &ht, | 692 v = find_var(lp->ll_name, (flags & GLV_READ_ONLY) ? NULL : &ht, |
693 flags & GLV_NO_AUTOLOAD); | 693 flags & GLV_NO_AUTOLOAD); |
694 if (v == NULL && !quiet) | 694 if (v == NULL && !quiet) |
695 semsg(_(e_undefvar), lp->ll_name); | 695 semsg(_(e_undefvar), lp->ll_name); |
696 *p = cc; | 696 *p = cc; |
736 } | 736 } |
737 p = key + len; | 737 p = key + len; |
738 } | 738 } |
739 else | 739 else |
740 { | 740 { |
741 /* Get the index [expr] or the first index [expr: ]. */ | 741 // Get the index [expr] or the first index [expr: ]. |
742 p = skipwhite(p + 1); | 742 p = skipwhite(p + 1); |
743 if (*p == ':') | 743 if (*p == ':') |
744 empty1 = TRUE; | 744 empty1 = TRUE; |
745 else | 745 else |
746 { | 746 { |
747 empty1 = FALSE; | 747 empty1 = FALSE; |
748 if (eval1(&p, &var1, TRUE) == FAIL) /* recursive! */ | 748 if (eval1(&p, &var1, TRUE) == FAIL) // recursive! |
749 return NULL; | 749 return NULL; |
750 if (tv_get_string_chk(&var1) == NULL) | 750 if (tv_get_string_chk(&var1) == NULL) |
751 { | 751 { |
752 /* not a number or string */ | 752 // not a number or string |
753 clear_tv(&var1); | 753 clear_tv(&var1); |
754 return NULL; | 754 return NULL; |
755 } | 755 } |
756 } | 756 } |
757 | 757 |
758 /* Optionally get the second index [ :expr]. */ | 758 // Optionally get the second index [ :expr]. |
759 if (*p == ':') | 759 if (*p == ':') |
760 { | 760 { |
761 if (lp->ll_tv->v_type == VAR_DICT) | 761 if (lp->ll_tv->v_type == VAR_DICT) |
762 { | 762 { |
763 if (!quiet) | 763 if (!quiet) |
780 if (*p == ']') | 780 if (*p == ']') |
781 lp->ll_empty2 = TRUE; | 781 lp->ll_empty2 = TRUE; |
782 else | 782 else |
783 { | 783 { |
784 lp->ll_empty2 = FALSE; | 784 lp->ll_empty2 = FALSE; |
785 if (eval1(&p, &var2, TRUE) == FAIL) /* recursive! */ | 785 if (eval1(&p, &var2, TRUE) == FAIL) // recursive! |
786 { | 786 { |
787 clear_tv(&var1); | 787 clear_tv(&var1); |
788 return NULL; | 788 return NULL; |
789 } | 789 } |
790 if (tv_get_string_chk(&var2) == NULL) | 790 if (tv_get_string_chk(&var2) == NULL) |
791 { | 791 { |
792 /* not a number or string */ | 792 // not a number or string |
793 clear_tv(&var1); | 793 clear_tv(&var1); |
794 clear_tv(&var2); | 794 clear_tv(&var2); |
795 return NULL; | 795 return NULL; |
796 } | 796 } |
797 } | 797 } |
807 clear_tv(&var1); | 807 clear_tv(&var1); |
808 clear_tv(&var2); | 808 clear_tv(&var2); |
809 return NULL; | 809 return NULL; |
810 } | 810 } |
811 | 811 |
812 /* Skip to past ']'. */ | 812 // Skip to past ']'. |
813 ++p; | 813 ++p; |
814 } | 814 } |
815 | 815 |
816 if (lp->ll_tv->v_type == VAR_DICT) | 816 if (lp->ll_tv->v_type == VAR_DICT) |
817 { | 817 { |
818 if (len == -1) | 818 if (len == -1) |
819 { | 819 { |
820 /* "[key]": get key from "var1" */ | 820 // "[key]": get key from "var1" |
821 key = tv_get_string_chk(&var1); /* is number or string */ | 821 key = tv_get_string_chk(&var1); // is number or string |
822 if (key == NULL) | 822 if (key == NULL) |
823 { | 823 { |
824 clear_tv(&var1); | 824 clear_tv(&var1); |
825 return NULL; | 825 return NULL; |
826 } | 826 } |
827 } | 827 } |
828 lp->ll_list = NULL; | 828 lp->ll_list = NULL; |
829 lp->ll_dict = lp->ll_tv->vval.v_dict; | 829 lp->ll_dict = lp->ll_tv->vval.v_dict; |
830 lp->ll_di = dict_find(lp->ll_dict, key, len); | 830 lp->ll_di = dict_find(lp->ll_dict, key, len); |
831 | 831 |
832 /* When assigning to a scope dictionary check that a function and | 832 // When assigning to a scope dictionary check that a function and |
833 * variable name is valid (only variable name unless it is l: or | 833 // variable name is valid (only variable name unless it is l: or |
834 * g: dictionary). Disallow overwriting a builtin function. */ | 834 // g: dictionary). Disallow overwriting a builtin function. |
835 if (rettv != NULL && lp->ll_dict->dv_scope != 0) | 835 if (rettv != NULL && lp->ll_dict->dv_scope != 0) |
836 { | 836 { |
837 int prevval; | 837 int prevval; |
838 int wrong; | 838 int wrong; |
839 | 839 |
841 { | 841 { |
842 prevval = key[len]; | 842 prevval = key[len]; |
843 key[len] = NUL; | 843 key[len] = NUL; |
844 } | 844 } |
845 else | 845 else |
846 prevval = 0; /* avoid compiler warning */ | 846 prevval = 0; // avoid compiler warning |
847 wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE | 847 wrong = (lp->ll_dict->dv_scope == VAR_DEF_SCOPE |
848 && rettv->v_type == VAR_FUNC | 848 && rettv->v_type == VAR_FUNC |
849 && var_check_func_name(key, lp->ll_di == NULL)) | 849 && var_check_func_name(key, lp->ll_di == NULL)) |
850 || !valid_varname(key); | 850 || !valid_varname(key); |
851 if (len != -1) | 851 if (len != -1) |
880 clear_tv(&var1); | 880 clear_tv(&var1); |
881 if (lp->ll_newkey == NULL) | 881 if (lp->ll_newkey == NULL) |
882 p = NULL; | 882 p = NULL; |
883 break; | 883 break; |
884 } | 884 } |
885 /* existing variable, need to check if it can be changed */ | 885 // existing variable, need to check if it can be changed |
886 else if ((flags & GLV_READ_ONLY) == 0 | 886 else if ((flags & GLV_READ_ONLY) == 0 |
887 && var_check_ro(lp->ll_di->di_flags, name, FALSE)) | 887 && var_check_ro(lp->ll_di->di_flags, name, FALSE)) |
888 { | 888 { |
889 clear_tv(&var1); | 889 clear_tv(&var1); |
890 return NULL; | 890 return NULL; |
939 * Get the number and item for the only or first index of the List. | 939 * Get the number and item for the only or first index of the List. |
940 */ | 940 */ |
941 if (empty1) | 941 if (empty1) |
942 lp->ll_n1 = 0; | 942 lp->ll_n1 = 0; |
943 else | 943 else |
944 /* is number or string */ | 944 // is number or string |
945 lp->ll_n1 = (long)tv_get_number(&var1); | 945 lp->ll_n1 = (long)tv_get_number(&var1); |
946 clear_tv(&var1); | 946 clear_tv(&var1); |
947 | 947 |
948 lp->ll_dict = NULL; | 948 lp->ll_dict = NULL; |
949 lp->ll_list = lp->ll_tv->vval.v_list; | 949 lp->ll_list = lp->ll_tv->vval.v_list; |
971 * Otherwise "lp->ll_n2" is set to the second index. | 971 * Otherwise "lp->ll_n2" is set to the second index. |
972 */ | 972 */ |
973 if (lp->ll_range && !lp->ll_empty2) | 973 if (lp->ll_range && !lp->ll_empty2) |
974 { | 974 { |
975 lp->ll_n2 = (long)tv_get_number(&var2); | 975 lp->ll_n2 = (long)tv_get_number(&var2); |
976 /* is number or string */ | 976 // is number or string |
977 clear_tv(&var2); | 977 clear_tv(&var2); |
978 if (lp->ll_n2 < 0) | 978 if (lp->ll_n2 < 0) |
979 { | 979 { |
980 ni = list_find(lp->ll_list, lp->ll_n2); | 980 ni = list_find(lp->ll_list, lp->ll_n2); |
981 if (ni == NULL) | 981 if (ni == NULL) |
985 return NULL; | 985 return NULL; |
986 } | 986 } |
987 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); | 987 lp->ll_n2 = list_idx_of_item(lp->ll_list, ni); |
988 } | 988 } |
989 | 989 |
990 /* Check that lp->ll_n2 isn't before lp->ll_n1. */ | 990 // Check that lp->ll_n2 isn't before lp->ll_n1. |
991 if (lp->ll_n1 < 0) | 991 if (lp->ll_n1 < 0) |
992 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); | 992 lp->ll_n1 = list_idx_of_item(lp->ll_list, lp->ll_li); |
993 if (lp->ll_n2 < lp->ll_n1) | 993 if (lp->ll_n2 < lp->ll_n1) |
994 { | 994 { |
995 if (!quiet) | 995 if (!quiet) |
1162 ri = ri->li_next; | 1162 ri = ri->li_next; |
1163 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) | 1163 if (ri == NULL || (!lp->ll_empty2 && lp->ll_n2 == lp->ll_n1)) |
1164 break; | 1164 break; |
1165 if (lp->ll_li->li_next == NULL) | 1165 if (lp->ll_li->li_next == NULL) |
1166 { | 1166 { |
1167 /* Need to add an empty item. */ | 1167 // Need to add an empty item. |
1168 if (list_append_number(lp->ll_list, 0) == FAIL) | 1168 if (list_append_number(lp->ll_list, 0) == FAIL) |
1169 { | 1169 { |
1170 ri = NULL; | 1170 ri = NULL; |
1171 break; | 1171 break; |
1172 } | 1172 } |
1197 { | 1197 { |
1198 semsg(_(e_letwrong), op); | 1198 semsg(_(e_letwrong), op); |
1199 return; | 1199 return; |
1200 } | 1200 } |
1201 | 1201 |
1202 /* Need to add an item to the Dictionary. */ | 1202 // Need to add an item to the Dictionary. |
1203 di = dictitem_alloc(lp->ll_newkey); | 1203 di = dictitem_alloc(lp->ll_newkey); |
1204 if (di == NULL) | 1204 if (di == NULL) |
1205 return; | 1205 return; |
1206 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) | 1206 if (dict_add(lp->ll_tv->vval.v_dict, di) == FAIL) |
1207 { | 1207 { |
1242 { | 1242 { |
1243 varnumber_T n; | 1243 varnumber_T n; |
1244 char_u numbuf[NUMBUFLEN]; | 1244 char_u numbuf[NUMBUFLEN]; |
1245 char_u *s; | 1245 char_u *s; |
1246 | 1246 |
1247 /* Can't do anything with a Funcref, Dict, v:true on the right. */ | 1247 // Can't do anything with a Funcref, Dict, v:true on the right. |
1248 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT | 1248 if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT |
1249 && tv2->v_type != VAR_SPECIAL) | 1249 && tv2->v_type != VAR_SPECIAL) |
1250 { | 1250 { |
1251 switch (tv1->v_type) | 1251 switch (tv1->v_type) |
1252 { | 1252 { |
1384 forinfo_T *fi; | 1384 forinfo_T *fi; |
1385 char_u *expr; | 1385 char_u *expr; |
1386 typval_T tv; | 1386 typval_T tv; |
1387 list_T *l; | 1387 list_T *l; |
1388 | 1388 |
1389 *errp = TRUE; /* default: there is an error */ | 1389 *errp = TRUE; // default: there is an error |
1390 | 1390 |
1391 fi = ALLOC_CLEAR_ONE(forinfo_T); | 1391 fi = ALLOC_CLEAR_ONE(forinfo_T); |
1392 if (fi == NULL) | 1392 if (fi == NULL) |
1393 return NULL; | 1393 return NULL; |
1394 | 1394 |
1524 if (cmdidx == CMD_let || cmdidx == CMD_const) | 1524 if (cmdidx == CMD_let || cmdidx == CMD_const) |
1525 { | 1525 { |
1526 xp->xp_context = EXPAND_USER_VARS; | 1526 xp->xp_context = EXPAND_USER_VARS; |
1527 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) | 1527 if (vim_strpbrk(arg, (char_u *)"\"'+-*/%.=!?~|&$([<>,#") == NULL) |
1528 { | 1528 { |
1529 /* ":let var1 var2 ...": find last space. */ | 1529 // ":let var1 var2 ...": find last space. |
1530 for (p = arg + STRLEN(arg); p >= arg; ) | 1530 for (p = arg + STRLEN(arg); p >= arg; ) |
1531 { | 1531 { |
1532 xp->xp_pattern = p; | 1532 xp->xp_pattern = p; |
1533 MB_PTR_BACK(arg, p); | 1533 MB_PTR_BACK(arg, p); |
1534 if (VIM_ISWHITE(*p)) | 1534 if (VIM_ISWHITE(*p)) |
1561 | 1561 |
1562 } | 1562 } |
1563 } | 1563 } |
1564 else if (c == '$') | 1564 else if (c == '$') |
1565 { | 1565 { |
1566 /* environment variable */ | 1566 // environment variable |
1567 xp->xp_context = EXPAND_ENV_VARS; | 1567 xp->xp_context = EXPAND_ENV_VARS; |
1568 } | 1568 } |
1569 else if (c == '=') | 1569 else if (c == '=') |
1570 { | 1570 { |
1571 got_eq = TRUE; | 1571 got_eq = TRUE; |
1572 xp->xp_context = EXPAND_EXPRESSION; | 1572 xp->xp_context = EXPAND_EXPRESSION; |
1573 } | 1573 } |
1574 else if (c == '#' | 1574 else if (c == '#' |
1575 && xp->xp_context == EXPAND_EXPRESSION) | 1575 && xp->xp_context == EXPAND_EXPRESSION) |
1576 { | 1576 { |
1577 /* Autoload function/variable contains '#'. */ | 1577 // Autoload function/variable contains '#'. |
1578 break; | 1578 break; |
1579 } | 1579 } |
1580 else if ((c == '<' || c == '#') | 1580 else if ((c == '<' || c == '#') |
1581 && xp->xp_context == EXPAND_FUNCTIONS | 1581 && xp->xp_context == EXPAND_FUNCTIONS |
1582 && vim_strchr(xp->xp_pattern, '(') == NULL) | 1582 && vim_strchr(xp->xp_pattern, '(') == NULL) |
1583 { | 1583 { |
1584 /* Function name can start with "<SNR>" and contain '#'. */ | 1584 // Function name can start with "<SNR>" and contain '#'. |
1585 break; | 1585 break; |
1586 } | 1586 } |
1587 else if (cmdidx != CMD_let || got_eq) | 1587 else if (cmdidx != CMD_let || got_eq) |
1588 { | 1588 { |
1589 if (c == '"') /* string */ | 1589 if (c == '"') // string |
1590 { | 1590 { |
1591 while ((c = *++xp->xp_pattern) != NUL && c != '"') | 1591 while ((c = *++xp->xp_pattern) != NUL && c != '"') |
1592 if (c == '\\' && xp->xp_pattern[1] != NUL) | 1592 if (c == '\\' && xp->xp_pattern[1] != NUL) |
1593 ++xp->xp_pattern; | 1593 ++xp->xp_pattern; |
1594 xp->xp_context = EXPAND_NOTHING; | 1594 xp->xp_context = EXPAND_NOTHING; |
1595 } | 1595 } |
1596 else if (c == '\'') /* literal string */ | 1596 else if (c == '\'') // literal string |
1597 { | 1597 { |
1598 /* Trick: '' is like stopping and starting a literal string. */ | 1598 // Trick: '' is like stopping and starting a literal string. |
1599 while ((c = *++xp->xp_pattern) != NUL && c != '\'') | 1599 while ((c = *++xp->xp_pattern) != NUL && c != '\'') |
1600 /* skip */ ; | 1600 /* skip */ ; |
1601 xp->xp_context = EXPAND_NOTHING; | 1601 xp->xp_context = EXPAND_NOTHING; |
1602 } | 1602 } |
1603 else if (c == '|') | 1603 else if (c == '|') |
1612 } | 1612 } |
1613 else | 1613 else |
1614 xp->xp_context = EXPAND_EXPRESSION; | 1614 xp->xp_context = EXPAND_EXPRESSION; |
1615 } | 1615 } |
1616 else | 1616 else |
1617 /* Doesn't look like something valid, expand as an expression | 1617 // Doesn't look like something valid, expand as an expression |
1618 * anyway. */ | 1618 // anyway. |
1619 xp->xp_context = EXPAND_EXPRESSION; | 1619 xp->xp_context = EXPAND_EXPRESSION; |
1620 arg = xp->xp_pattern; | 1620 arg = xp->xp_pattern; |
1621 if (*arg != NUL) | 1621 if (*arg != NUL) |
1622 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) | 1622 while ((c = *++arg) != NUL && (c == ' ' || c == '\t')) |
1623 /* skip */ ; | 1623 /* skip */ ; |
1634 { | 1634 { |
1635 int matches = FALSE; | 1635 int matches = FALSE; |
1636 char_u *save_cpo; | 1636 char_u *save_cpo; |
1637 regmatch_T regmatch; | 1637 regmatch_T regmatch; |
1638 | 1638 |
1639 /* avoid 'l' flag in 'cpoptions' */ | 1639 // avoid 'l' flag in 'cpoptions' |
1640 save_cpo = p_cpo; | 1640 save_cpo = p_cpo; |
1641 p_cpo = (char_u *)""; | 1641 p_cpo = (char_u *)""; |
1642 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); | 1642 regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); |
1643 if (regmatch.regprog != NULL) | 1643 if (regmatch.regprog != NULL) |
1644 { | 1644 { |
1670 int ret = OK; | 1670 int ret = OK; |
1671 | 1671 |
1672 if (!evaluate) | 1672 if (!evaluate) |
1673 check_vars(s, len); | 1673 check_vars(s, len); |
1674 | 1674 |
1675 /* If "s" is the name of a variable of type VAR_FUNC | 1675 // If "s" is the name of a variable of type VAR_FUNC |
1676 * use its contents. */ | 1676 // use its contents. |
1677 s = deref_func_name(s, &len, &partial, !evaluate); | 1677 s = deref_func_name(s, &len, &partial, !evaluate); |
1678 | 1678 |
1679 /* Need to make a copy, in case evaluating the arguments makes | 1679 // Need to make a copy, in case evaluating the arguments makes |
1680 * the name invalid. */ | 1680 // the name invalid. |
1681 s = vim_strsave(s); | 1681 s = vim_strsave(s); |
1682 if (s == NULL) | 1682 if (s == NULL) |
1683 ret = FAIL; | 1683 ret = FAIL; |
1684 else | 1684 else |
1685 { | 1685 { |
1694 funcexe.basetv = basetv; | 1694 funcexe.basetv = basetv; |
1695 ret = get_func_tv(s, len, rettv, arg, &funcexe); | 1695 ret = get_func_tv(s, len, rettv, arg, &funcexe); |
1696 } | 1696 } |
1697 vim_free(s); | 1697 vim_free(s); |
1698 | 1698 |
1699 /* If evaluate is FALSE rettv->v_type was not set in | 1699 // If evaluate is FALSE rettv->v_type was not set in |
1700 * get_func_tv, but it's needed in handle_subscript() to parse | 1700 // get_func_tv, but it's needed in handle_subscript() to parse |
1701 * what follows. So set it here. */ | 1701 // what follows. So set it here. |
1702 if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') | 1702 if (rettv->v_type == VAR_UNKNOWN && !evaluate && **arg == '(') |
1703 { | 1703 { |
1704 rettv->vval.v_string = NULL; | 1704 rettv->vval.v_string = NULL; |
1705 rettv->v_type = VAR_FUNC; | 1705 rettv->v_type = VAR_FUNC; |
1706 } | 1706 } |
1707 | 1707 |
1708 /* Stop the expression evaluation when immediately | 1708 // Stop the expression evaluation when immediately |
1709 * aborting on error, or when an interrupt occurred or | 1709 // aborting on error, or when an interrupt occurred or |
1710 * an exception was thrown but not caught. */ | 1710 // an exception was thrown but not caught. |
1711 if (evaluate && aborting()) | 1711 if (evaluate && aborting()) |
1712 { | 1712 { |
1713 if (ret == OK) | 1713 if (ret == OK) |
1714 clear_tv(rettv); | 1714 clear_tv(rettv); |
1715 ret = FAIL; | 1715 ret = FAIL; |
1804 | 1804 |
1805 /* | 1805 /* |
1806 * Get the second variable. | 1806 * Get the second variable. |
1807 */ | 1807 */ |
1808 *arg = skipwhite(*arg + 1); | 1808 *arg = skipwhite(*arg + 1); |
1809 if (eval1(arg, rettv, evaluate && result) == FAIL) /* recursive! */ | 1809 if (eval1(arg, rettv, evaluate && result) == FAIL) // recursive! |
1810 return FAIL; | 1810 return FAIL; |
1811 | 1811 |
1812 /* | 1812 /* |
1813 * Check for the ":". | 1813 * Check for the ":". |
1814 */ | 1814 */ |
1822 | 1822 |
1823 /* | 1823 /* |
1824 * Get the third variable. | 1824 * Get the third variable. |
1825 */ | 1825 */ |
1826 *arg = skipwhite(*arg + 1); | 1826 *arg = skipwhite(*arg + 1); |
1827 if (eval1(arg, &var2, evaluate && !result) == FAIL) /* recursive! */ | 1827 if (eval1(arg, &var2, evaluate && !result) == FAIL) // recursive! |
1828 { | 1828 { |
1829 if (evaluate && result) | 1829 if (evaluate && result) |
1830 clear_tv(rettv); | 1830 clear_tv(rettv); |
1831 return FAIL; | 1831 return FAIL; |
1832 } | 1832 } |
1996 { | 1996 { |
1997 typval_T var2; | 1997 typval_T var2; |
1998 char_u *p; | 1998 char_u *p; |
1999 int i; | 1999 int i; |
2000 exptype_T type = TYPE_UNKNOWN; | 2000 exptype_T type = TYPE_UNKNOWN; |
2001 int type_is = FALSE; /* TRUE for "is" and "isnot" */ | 2001 int type_is = FALSE; // TRUE for "is" and "isnot" |
2002 int len = 2; | 2002 int len = 2; |
2003 int ic; | 2003 int ic; |
2004 | 2004 |
2005 /* | 2005 /* |
2006 * Get the first variable. | 2006 * Get the first variable. |
2054 /* | 2054 /* |
2055 * If there is a comparative operator, use it. | 2055 * If there is a comparative operator, use it. |
2056 */ | 2056 */ |
2057 if (type != TYPE_UNKNOWN) | 2057 if (type != TYPE_UNKNOWN) |
2058 { | 2058 { |
2059 /* extra question mark appended: ignore case */ | 2059 // extra question mark appended: ignore case |
2060 if (p[len] == '?') | 2060 if (p[len] == '?') |
2061 { | 2061 { |
2062 ic = TRUE; | 2062 ic = TRUE; |
2063 ++len; | 2063 ++len; |
2064 } | 2064 } |
2065 /* extra '#' appended: match case */ | 2065 // extra '#' appended: match case |
2066 else if (p[len] == '#') | 2066 else if (p[len] == '#') |
2067 { | 2067 { |
2068 ic = FALSE; | 2068 ic = FALSE; |
2069 ++len; | 2069 ++len; |
2070 } | 2070 } |
2071 /* nothing appended: use 'ignorecase' */ | 2071 // nothing appended: use 'ignorecase' |
2072 else | 2072 else |
2073 ic = p_ic; | 2073 ic = p_ic; |
2074 | 2074 |
2075 /* | 2075 /* |
2076 * Get the second variable. | 2076 * Get the second variable. |
2143 #ifdef FEAT_FLOAT | 2143 #ifdef FEAT_FLOAT |
2144 && (op == '.' || rettv->v_type != VAR_FLOAT) | 2144 && (op == '.' || rettv->v_type != VAR_FLOAT) |
2145 #endif | 2145 #endif |
2146 ) | 2146 ) |
2147 { | 2147 { |
2148 /* For "list + ...", an illegal use of the first operand as | 2148 // For "list + ...", an illegal use of the first operand as |
2149 * a number cannot be determined before evaluating the 2nd | 2149 // a number cannot be determined before evaluating the 2nd |
2150 * operand: if this is also a list, all is ok. | 2150 // operand: if this is also a list, all is ok. |
2151 * For "something . ...", "something - ..." or "non-list + ...", | 2151 // For "something . ...", "something - ..." or "non-list + ...", |
2152 * we know that the first operand needs to be a string or number | 2152 // we know that the first operand needs to be a string or number |
2153 * without evaluating the 2nd operand. So check before to avoid | 2153 // without evaluating the 2nd operand. So check before to avoid |
2154 * side effects after an error. */ | 2154 // side effects after an error. |
2155 if (evaluate && tv_get_string_chk(rettv) == NULL) | 2155 if (evaluate && tv_get_string_chk(rettv) == NULL) |
2156 { | 2156 { |
2157 clear_tv(rettv); | 2157 clear_tv(rettv); |
2158 return FAIL; | 2158 return FAIL; |
2159 } | 2159 } |
2176 /* | 2176 /* |
2177 * Compute the result. | 2177 * Compute the result. |
2178 */ | 2178 */ |
2179 if (op == '.') | 2179 if (op == '.') |
2180 { | 2180 { |
2181 s1 = tv_get_string_buf(rettv, buf1); /* already checked */ | 2181 s1 = tv_get_string_buf(rettv, buf1); // already checked |
2182 s2 = tv_get_string_buf_chk(&var2, buf2); | 2182 s2 = tv_get_string_buf_chk(&var2, buf2); |
2183 if (s2 == NULL) /* type error ? */ | 2183 if (s2 == NULL) // type error ? |
2184 { | 2184 { |
2185 clear_tv(rettv); | 2185 clear_tv(rettv); |
2186 clear_tv(&var2); | 2186 clear_tv(&var2); |
2187 return FAIL; | 2187 return FAIL; |
2188 } | 2188 } |
2211 } | 2211 } |
2212 } | 2212 } |
2213 else if (op == '+' && rettv->v_type == VAR_LIST | 2213 else if (op == '+' && rettv->v_type == VAR_LIST |
2214 && var2.v_type == VAR_LIST) | 2214 && var2.v_type == VAR_LIST) |
2215 { | 2215 { |
2216 /* concatenate Lists */ | 2216 // concatenate Lists |
2217 if (list_concat(rettv->vval.v_list, var2.vval.v_list, | 2217 if (list_concat(rettv->vval.v_list, var2.vval.v_list, |
2218 &var3) == FAIL) | 2218 &var3) == FAIL) |
2219 { | 2219 { |
2220 clear_tv(rettv); | 2220 clear_tv(rettv); |
2221 clear_tv(&var2); | 2221 clear_tv(&var2); |
2238 #endif | 2238 #endif |
2239 { | 2239 { |
2240 n1 = tv_get_number_chk(rettv, &error); | 2240 n1 = tv_get_number_chk(rettv, &error); |
2241 if (error) | 2241 if (error) |
2242 { | 2242 { |
2243 /* This can only happen for "list + non-list". For | 2243 // This can only happen for "list + non-list". For |
2244 * "non-list + ..." or "something - ...", we returned | 2244 // "non-list + ..." or "something - ...", we returned |
2245 * before evaluating the 2nd operand. */ | 2245 // before evaluating the 2nd operand. |
2246 clear_tv(rettv); | 2246 clear_tv(rettv); |
2247 return FAIL; | 2247 return FAIL; |
2248 } | 2248 } |
2249 #ifdef FEAT_FLOAT | 2249 #ifdef FEAT_FLOAT |
2250 if (var2.v_type == VAR_FLOAT) | 2250 if (var2.v_type == VAR_FLOAT) |
2273 #endif | 2273 #endif |
2274 } | 2274 } |
2275 clear_tv(rettv); | 2275 clear_tv(rettv); |
2276 | 2276 |
2277 #ifdef FEAT_FLOAT | 2277 #ifdef FEAT_FLOAT |
2278 /* If there is a float on either side the result is a float. */ | 2278 // If there is a float on either side the result is a float. |
2279 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) | 2279 if (rettv->v_type == VAR_FLOAT || var2.v_type == VAR_FLOAT) |
2280 { | 2280 { |
2281 if (op == '+') | 2281 if (op == '+') |
2282 f1 = f1 + f2; | 2282 f1 = f1 + f2; |
2283 else | 2283 else |
2316 static int | 2316 static int |
2317 eval6( | 2317 eval6( |
2318 char_u **arg, | 2318 char_u **arg, |
2319 typval_T *rettv, | 2319 typval_T *rettv, |
2320 int evaluate, | 2320 int evaluate, |
2321 int want_string) /* after "." operator */ | 2321 int want_string) // after "." operator |
2322 { | 2322 { |
2323 typval_T var2; | 2323 typval_T var2; |
2324 int op; | 2324 int op; |
2325 varnumber_T n1, n2; | 2325 varnumber_T n1, n2; |
2326 #ifdef FEAT_FLOAT | 2326 #ifdef FEAT_FLOAT |
2406 if (op == '*') | 2406 if (op == '*') |
2407 f1 = f1 * f2; | 2407 f1 = f1 * f2; |
2408 else if (op == '/') | 2408 else if (op == '/') |
2409 { | 2409 { |
2410 # ifdef VMS | 2410 # ifdef VMS |
2411 /* VMS crashes on divide by zero, work around it */ | 2411 // VMS crashes on divide by zero, work around it |
2412 if (f2 == 0.0) | 2412 if (f2 == 0.0) |
2413 { | 2413 { |
2414 if (f1 == 0) | 2414 if (f1 == 0) |
2415 f1 = -1 * __F_FLT_MAX - 1L; /* similar to NaN */ | 2415 f1 = -1 * __F_FLT_MAX - 1L; // similar to NaN |
2416 else if (f1 < 0) | 2416 else if (f1 < 0) |
2417 f1 = -1 * __F_FLT_MAX; | 2417 f1 = -1 * __F_FLT_MAX; |
2418 else | 2418 else |
2419 f1 = __F_FLT_MAX; | 2419 f1 = __F_FLT_MAX; |
2420 } | 2420 } |
2421 else | 2421 else |
2422 f1 = f1 / f2; | 2422 f1 = f1 / f2; |
2423 # else | 2423 # else |
2424 /* We rely on the floating point library to handle divide | 2424 // We rely on the floating point library to handle divide |
2425 * by zero to result in "inf" and not a crash. */ | 2425 // by zero to result in "inf" and not a crash. |
2426 f1 = f1 / f2; | 2426 f1 = f1 / f2; |
2427 # endif | 2427 # endif |
2428 } | 2428 } |
2429 else | 2429 else |
2430 { | 2430 { |
2485 static int | 2485 static int |
2486 eval7( | 2486 eval7( |
2487 char_u **arg, | 2487 char_u **arg, |
2488 typval_T *rettv, | 2488 typval_T *rettv, |
2489 int evaluate, | 2489 int evaluate, |
2490 int want_string UNUSED) /* after "." operator */ | 2490 int want_string UNUSED) // after "." operator |
2491 { | 2491 { |
2492 varnumber_T n; | 2492 varnumber_T n; |
2493 int len; | 2493 int len; |
2494 char_u *s; | 2494 char_u *s; |
2495 char_u *start_leader, *end_leader; | 2495 char_u *start_leader, *end_leader; |
2540 { | 2540 { |
2541 #ifdef FEAT_FLOAT | 2541 #ifdef FEAT_FLOAT |
2542 char_u *p; | 2542 char_u *p; |
2543 int get_float = FALSE; | 2543 int get_float = FALSE; |
2544 | 2544 |
2545 /* We accept a float when the format matches | 2545 // We accept a float when the format matches |
2546 * "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very | 2546 // "[0-9]\+\.[0-9]\+\([eE][+-]\?[0-9]\+\)\?". This is very |
2547 * strict to avoid backwards compatibility problems. | 2547 // strict to avoid backwards compatibility problems. |
2548 * With script version 2 and later the leading digit can be | 2548 // With script version 2 and later the leading digit can be |
2549 * omitted. | 2549 // omitted. |
2550 * Don't look for a float after the "." operator, so that | 2550 // Don't look for a float after the "." operator, so that |
2551 * ":let vers = 1.2.3" doesn't fail. */ | 2551 // ":let vers = 1.2.3" doesn't fail. |
2552 if (**arg == '.') | 2552 if (**arg == '.') |
2553 p = *arg; | 2553 p = *arg; |
2554 else | 2554 else |
2555 p = skipdigits(*arg + 1); | 2555 p = skipdigits(*arg + 1); |
2556 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) | 2556 if (!want_string && p[0] == '.' && vim_isdigit(p[1])) |
2703 | 2703 |
2704 /* | 2704 /* |
2705 * nested expression: (expression). | 2705 * nested expression: (expression). |
2706 */ | 2706 */ |
2707 case '(': *arg = skipwhite(*arg + 1); | 2707 case '(': *arg = skipwhite(*arg + 1); |
2708 ret = eval1(arg, rettv, evaluate); /* recursive! */ | 2708 ret = eval1(arg, rettv, evaluate); // recursive! |
2709 if (**arg == ')') | 2709 if (**arg == ')') |
2710 ++*arg; | 2710 ++*arg; |
2711 else if (ret == OK) | 2711 else if (ret == OK) |
2712 { | 2712 { |
2713 emsg(_("E110: Missing ')'")); | 2713 emsg(_("E110: Missing ')'")); |
2733 | 2733 |
2734 if (len <= 0) | 2734 if (len <= 0) |
2735 ret = FAIL; | 2735 ret = FAIL; |
2736 else | 2736 else |
2737 { | 2737 { |
2738 if (**arg == '(') /* recursive! */ | 2738 if (**arg == '(') // recursive! |
2739 ret = eval_func(arg, s, len, rettv, evaluate, NULL); | 2739 ret = eval_func(arg, s, len, rettv, evaluate, NULL); |
2740 else if (evaluate) | 2740 else if (evaluate) |
2741 ret = get_var_tv(s, len, rettv, NULL, TRUE, FALSE); | 2741 ret = get_var_tv(s, len, rettv, NULL, TRUE, FALSE); |
2742 else | 2742 else |
2743 { | 2743 { |
2748 vim_free(alias); | 2748 vim_free(alias); |
2749 } | 2749 } |
2750 | 2750 |
2751 *arg = skipwhite(*arg); | 2751 *arg = skipwhite(*arg); |
2752 | 2752 |
2753 /* Handle following '[', '(' and '.' for expr[expr], expr.name, | 2753 // Handle following '[', '(' and '.' for expr[expr], expr.name, |
2754 * expr(expr), expr->name(expr) */ | 2754 // expr(expr), expr->name(expr) |
2755 if (ret == OK) | 2755 if (ret == OK) |
2756 ret = handle_subscript(arg, rettv, evaluate, TRUE, | 2756 ret = handle_subscript(arg, rettv, evaluate, TRUE, |
2757 start_leader, &end_leader); | 2757 start_leader, &end_leader); |
2758 | 2758 |
2759 /* | 2759 /* |
2851 if (evaluate) | 2851 if (evaluate) |
2852 { | 2852 { |
2853 functv = *rettv; | 2853 functv = *rettv; |
2854 rettv->v_type = VAR_UNKNOWN; | 2854 rettv->v_type = VAR_UNKNOWN; |
2855 | 2855 |
2856 /* Invoke the function. Recursive! */ | 2856 // Invoke the function. Recursive! |
2857 if (functv.v_type == VAR_PARTIAL) | 2857 if (functv.v_type == VAR_PARTIAL) |
2858 { | 2858 { |
2859 pt = functv.vval.v_partial; | 2859 pt = functv.vval.v_partial; |
2860 s = partial_name(pt); | 2860 s = partial_name(pt); |
2861 } | 2861 } |
2872 funcexe.partial = pt; | 2872 funcexe.partial = pt; |
2873 funcexe.selfdict = selfdict; | 2873 funcexe.selfdict = selfdict; |
2874 funcexe.basetv = basetv; | 2874 funcexe.basetv = basetv; |
2875 ret = get_func_tv(s, -1, rettv, arg, &funcexe); | 2875 ret = get_func_tv(s, -1, rettv, arg, &funcexe); |
2876 | 2876 |
2877 /* Clear the funcref afterwards, so that deleting it while | 2877 // Clear the funcref afterwards, so that deleting it while |
2878 * evaluating the arguments is possible (see test55). */ | 2878 // evaluating the arguments is possible (see test55). |
2879 if (evaluate) | 2879 if (evaluate) |
2880 clear_tv(&functv); | 2880 clear_tv(&functv); |
2881 | 2881 |
2882 return ret; | 2882 return ret; |
2883 } | 2883 } |
2890 static int | 2890 static int |
2891 eval_lambda( | 2891 eval_lambda( |
2892 char_u **arg, | 2892 char_u **arg, |
2893 typval_T *rettv, | 2893 typval_T *rettv, |
2894 int evaluate, | 2894 int evaluate, |
2895 int verbose) /* give error messages */ | 2895 int verbose) // give error messages |
2896 { | 2896 { |
2897 typval_T base = *rettv; | 2897 typval_T base = *rettv; |
2898 int ret; | 2898 int ret; |
2899 | 2899 |
2900 // Skip over the ->. | 2900 // Skip over the ->. |
2935 static int | 2935 static int |
2936 eval_method( | 2936 eval_method( |
2937 char_u **arg, | 2937 char_u **arg, |
2938 typval_T *rettv, | 2938 typval_T *rettv, |
2939 int evaluate, | 2939 int evaluate, |
2940 int verbose) /* give error messages */ | 2940 int verbose) // give error messages |
2941 { | 2941 { |
2942 char_u *name; | 2942 char_u *name; |
2943 long len; | 2943 long len; |
2944 char_u *alias; | 2944 char_u *alias; |
2945 typval_T base = *rettv; | 2945 typval_T base = *rettv; |
2994 static int | 2994 static int |
2995 eval_index( | 2995 eval_index( |
2996 char_u **arg, | 2996 char_u **arg, |
2997 typval_T *rettv, | 2997 typval_T *rettv, |
2998 int evaluate, | 2998 int evaluate, |
2999 int verbose) /* give error messages */ | 2999 int verbose) // give error messages |
3000 { | 3000 { |
3001 int empty1 = FALSE, empty2 = FALSE; | 3001 int empty1 = FALSE, empty2 = FALSE; |
3002 typval_T var1, var2; | 3002 typval_T var1, var2; |
3003 long i; | 3003 long i; |
3004 long n1, n2 = 0; | 3004 long n1, n2 = 0; |
3027 emsg(_("E909: Cannot index a special variable")); | 3027 emsg(_("E909: Cannot index a special variable")); |
3028 return FAIL; | 3028 return FAIL; |
3029 case VAR_UNKNOWN: | 3029 case VAR_UNKNOWN: |
3030 if (evaluate) | 3030 if (evaluate) |
3031 return FAIL; | 3031 return FAIL; |
3032 /* FALLTHROUGH */ | 3032 // FALLTHROUGH |
3033 | 3033 |
3034 case VAR_STRING: | 3034 case VAR_STRING: |
3035 case VAR_NUMBER: | 3035 case VAR_NUMBER: |
3036 case VAR_LIST: | 3036 case VAR_LIST: |
3037 case VAR_DICT: | 3037 case VAR_DICT: |
3061 * Get the (first) variable from inside the []. | 3061 * Get the (first) variable from inside the []. |
3062 */ | 3062 */ |
3063 *arg = skipwhite(*arg + 1); | 3063 *arg = skipwhite(*arg + 1); |
3064 if (**arg == ':') | 3064 if (**arg == ':') |
3065 empty1 = TRUE; | 3065 empty1 = TRUE; |
3066 else if (eval1(arg, &var1, evaluate) == FAIL) /* recursive! */ | 3066 else if (eval1(arg, &var1, evaluate) == FAIL) // recursive! |
3067 return FAIL; | 3067 return FAIL; |
3068 else if (evaluate && tv_get_string_chk(&var1) == NULL) | 3068 else if (evaluate && tv_get_string_chk(&var1) == NULL) |
3069 { | 3069 { |
3070 /* not a number or string */ | 3070 // not a number or string |
3071 clear_tv(&var1); | 3071 clear_tv(&var1); |
3072 return FAIL; | 3072 return FAIL; |
3073 } | 3073 } |
3074 | 3074 |
3075 /* | 3075 /* |
3079 { | 3079 { |
3080 range = TRUE; | 3080 range = TRUE; |
3081 *arg = skipwhite(*arg + 1); | 3081 *arg = skipwhite(*arg + 1); |
3082 if (**arg == ']') | 3082 if (**arg == ']') |
3083 empty2 = TRUE; | 3083 empty2 = TRUE; |
3084 else if (eval1(arg, &var2, evaluate) == FAIL) /* recursive! */ | 3084 else if (eval1(arg, &var2, evaluate) == FAIL) // recursive! |
3085 { | 3085 { |
3086 if (!empty1) | 3086 if (!empty1) |
3087 clear_tv(&var1); | 3087 clear_tv(&var1); |
3088 return FAIL; | 3088 return FAIL; |
3089 } | 3089 } |
3090 else if (evaluate && tv_get_string_chk(&var2) == NULL) | 3090 else if (evaluate && tv_get_string_chk(&var2) == NULL) |
3091 { | 3091 { |
3092 /* not a number or string */ | 3092 // not a number or string |
3093 if (!empty1) | 3093 if (!empty1) |
3094 clear_tv(&var1); | 3094 clear_tv(&var1); |
3095 clear_tv(&var2); | 3095 clear_tv(&var2); |
3096 return FAIL; | 3096 return FAIL; |
3097 } | 3097 } |
3098 } | 3098 } |
3099 | 3099 |
3100 /* Check for the ']'. */ | 3100 // Check for the ']'. |
3101 if (**arg != ']') | 3101 if (**arg != ']') |
3102 { | 3102 { |
3103 if (verbose) | 3103 if (verbose) |
3104 emsg(_(e_missbrac)); | 3104 emsg(_(e_missbrac)); |
3105 clear_tv(&var1); | 3105 clear_tv(&var1); |
3106 if (range) | 3106 if (range) |
3107 clear_tv(&var2); | 3107 clear_tv(&var2); |
3108 return FAIL; | 3108 return FAIL; |
3109 } | 3109 } |
3110 *arg = skipwhite(*arg + 1); /* skip the ']' */ | 3110 *arg = skipwhite(*arg + 1); // skip the ']' |
3111 } | 3111 } |
3112 | 3112 |
3113 if (evaluate) | 3113 if (evaluate) |
3114 { | 3114 { |
3115 n1 = 0; | 3115 n1 = 0; |
3136 case VAR_PARTIAL: | 3136 case VAR_PARTIAL: |
3137 case VAR_FLOAT: | 3137 case VAR_FLOAT: |
3138 case VAR_SPECIAL: | 3138 case VAR_SPECIAL: |
3139 case VAR_JOB: | 3139 case VAR_JOB: |
3140 case VAR_CHANNEL: | 3140 case VAR_CHANNEL: |
3141 break; /* not evaluating, skipping over subscript */ | 3141 break; // not evaluating, skipping over subscript |
3142 | 3142 |
3143 case VAR_NUMBER: | 3143 case VAR_NUMBER: |
3144 case VAR_STRING: | 3144 case VAR_STRING: |
3145 s = tv_get_string(rettv); | 3145 s = tv_get_string(rettv); |
3146 len = (long)STRLEN(s); | 3146 len = (long)STRLEN(s); |
3147 if (range) | 3147 if (range) |
3148 { | 3148 { |
3149 /* The resulting variable is a substring. If the indexes | 3149 // The resulting variable is a substring. If the indexes |
3150 * are out of range the result is empty. */ | 3150 // are out of range the result is empty. |
3151 if (n1 < 0) | 3151 if (n1 < 0) |
3152 { | 3152 { |
3153 n1 = len + n1; | 3153 n1 = len + n1; |
3154 if (n1 < 0) | 3154 if (n1 < 0) |
3155 n1 = 0; | 3155 n1 = 0; |
3163 else | 3163 else |
3164 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); | 3164 s = vim_strnsave(s + n1, (int)(n2 - n1 + 1)); |
3165 } | 3165 } |
3166 else | 3166 else |
3167 { | 3167 { |
3168 /* The resulting variable is a string of a single | 3168 // The resulting variable is a string of a single |
3169 * character. If the index is too big or negative the | 3169 // character. If the index is too big or negative the |
3170 * result is empty. */ | 3170 // result is empty. |
3171 if (n1 >= len || n1 < 0) | 3171 if (n1 >= len || n1 < 0) |
3172 s = NULL; | 3172 s = NULL; |
3173 else | 3173 else |
3174 s = vim_strnsave(s + n1, 1); | 3174 s = vim_strnsave(s + n1, 1); |
3175 } | 3175 } |
3244 len = list_len(rettv->vval.v_list); | 3244 len = list_len(rettv->vval.v_list); |
3245 if (n1 < 0) | 3245 if (n1 < 0) |
3246 n1 = len + n1; | 3246 n1 = len + n1; |
3247 if (!empty1 && (n1 < 0 || n1 >= len)) | 3247 if (!empty1 && (n1 < 0 || n1 >= len)) |
3248 { | 3248 { |
3249 /* For a range we allow invalid values and return an empty | 3249 // For a range we allow invalid values and return an empty |
3250 * list. A list index out of range is an error. */ | 3250 // list. A list index out of range is an error. |
3251 if (!range) | 3251 if (!range) |
3252 { | 3252 { |
3253 if (verbose) | 3253 if (verbose) |
3254 semsg(_(e_listidx), n1); | 3254 semsg(_(e_listidx), n1); |
3255 return FAIL; | 3255 return FAIL; |
3340 * Return OK or FAIL. | 3340 * Return OK or FAIL. |
3341 */ | 3341 */ |
3342 int | 3342 int |
3343 get_option_tv( | 3343 get_option_tv( |
3344 char_u **arg, | 3344 char_u **arg, |
3345 typval_T *rettv, /* when NULL, only check if option exists */ | 3345 typval_T *rettv, // when NULL, only check if option exists |
3346 int evaluate) | 3346 int evaluate) |
3347 { | 3347 { |
3348 char_u *option_end; | 3348 char_u *option_end; |
3349 long numval; | 3349 long numval; |
3350 char_u *stringval; | 3350 char_u *stringval; |
3351 int opt_type; | 3351 int opt_type; |
3352 int c; | 3352 int c; |
3353 int working = (**arg == '+'); /* has("+option") */ | 3353 int working = (**arg == '+'); // has("+option") |
3354 int ret = OK; | 3354 int ret = OK; |
3355 int opt_flags; | 3355 int opt_flags; |
3356 | 3356 |
3357 /* | 3357 /* |
3358 * Isolate the option name and find its value. | 3358 * Isolate the option name and find its value. |
3374 c = *option_end; | 3374 c = *option_end; |
3375 *option_end = NUL; | 3375 *option_end = NUL; |
3376 opt_type = get_option_value(*arg, &numval, | 3376 opt_type = get_option_value(*arg, &numval, |
3377 rettv == NULL ? NULL : &stringval, opt_flags); | 3377 rettv == NULL ? NULL : &stringval, opt_flags); |
3378 | 3378 |
3379 if (opt_type == -3) /* invalid name */ | 3379 if (opt_type == -3) // invalid name |
3380 { | 3380 { |
3381 if (rettv != NULL) | 3381 if (rettv != NULL) |
3382 semsg(_("E113: Unknown option: %s"), *arg); | 3382 semsg(_("E113: Unknown option: %s"), *arg); |
3383 ret = FAIL; | 3383 ret = FAIL; |
3384 } | 3384 } |
3385 else if (rettv != NULL) | 3385 else if (rettv != NULL) |
3386 { | 3386 { |
3387 if (opt_type == -2) /* hidden string option */ | 3387 if (opt_type == -2) // hidden string option |
3388 { | 3388 { |
3389 rettv->v_type = VAR_STRING; | 3389 rettv->v_type = VAR_STRING; |
3390 rettv->vval.v_string = NULL; | 3390 rettv->vval.v_string = NULL; |
3391 } | 3391 } |
3392 else if (opt_type == -1) /* hidden number option */ | 3392 else if (opt_type == -1) // hidden number option |
3393 { | 3393 { |
3394 rettv->v_type = VAR_NUMBER; | 3394 rettv->v_type = VAR_NUMBER; |
3395 rettv->vval.v_number = 0; | 3395 rettv->vval.v_number = 0; |
3396 } | 3396 } |
3397 else if (opt_type == 1) /* number option */ | 3397 else if (opt_type == 1) // number option |
3398 { | 3398 { |
3399 rettv->v_type = VAR_NUMBER; | 3399 rettv->v_type = VAR_NUMBER; |
3400 rettv->vval.v_number = numval; | 3400 rettv->vval.v_number = numval; |
3401 } | 3401 } |
3402 else /* string option */ | 3402 else // string option |
3403 { | 3403 { |
3404 rettv->v_type = VAR_STRING; | 3404 rettv->v_type = VAR_STRING; |
3405 rettv->vval.v_string = stringval; | 3405 rettv->vval.v_string = stringval; |
3406 } | 3406 } |
3407 } | 3407 } |
3408 else if (working && (opt_type == -2 || opt_type == -1)) | 3408 else if (working && (opt_type == -2 || opt_type == -1)) |
3409 ret = FAIL; | 3409 ret = FAIL; |
3410 | 3410 |
3411 *option_end = c; /* put back for error messages */ | 3411 *option_end = c; // put back for error messages |
3412 *arg = option_end; | 3412 *arg = option_end; |
3413 | 3413 |
3414 return ret; | 3414 return ret; |
3415 } | 3415 } |
3416 | 3416 |
3431 for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p)) | 3431 for (p = *arg + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p)) |
3432 { | 3432 { |
3433 if (*p == '\\' && p[1] != NUL) | 3433 if (*p == '\\' && p[1] != NUL) |
3434 { | 3434 { |
3435 ++p; | 3435 ++p; |
3436 /* A "\<x>" form occupies at least 4 characters, and produces up | 3436 // A "\<x>" form occupies at least 4 characters, and produces up |
3437 * to 6 characters: reserve space for 2 extra */ | 3437 // to 6 characters: reserve space for 2 extra |
3438 if (*p == '<') | 3438 if (*p == '<') |
3439 extra += 2; | 3439 extra += 2; |
3440 } | 3440 } |
3441 } | 3441 } |
3442 | 3442 |
3444 { | 3444 { |
3445 semsg(_("E114: Missing quote: %s"), *arg); | 3445 semsg(_("E114: Missing quote: %s"), *arg); |
3446 return FAIL; | 3446 return FAIL; |
3447 } | 3447 } |
3448 | 3448 |
3449 /* If only parsing, set *arg and return here */ | 3449 // If only parsing, set *arg and return here |
3450 if (!evaluate) | 3450 if (!evaluate) |
3451 { | 3451 { |
3452 *arg = p + 1; | 3452 *arg = p + 1; |
3453 return OK; | 3453 return OK; |
3454 } | 3454 } |
3474 case 'f': *name++ = FF; ++p; break; | 3474 case 'f': *name++ = FF; ++p; break; |
3475 case 'n': *name++ = NL; ++p; break; | 3475 case 'n': *name++ = NL; ++p; break; |
3476 case 'r': *name++ = CAR; ++p; break; | 3476 case 'r': *name++ = CAR; ++p; break; |
3477 case 't': *name++ = TAB; ++p; break; | 3477 case 't': *name++ = TAB; ++p; break; |
3478 | 3478 |
3479 case 'X': /* hex: "\x1", "\x12" */ | 3479 case 'X': // hex: "\x1", "\x12" |
3480 case 'x': | 3480 case 'x': |
3481 case 'u': /* Unicode: "\u0023" */ | 3481 case 'u': // Unicode: "\u0023" |
3482 case 'U': | 3482 case 'U': |
3483 if (vim_isxdigit(p[1])) | 3483 if (vim_isxdigit(p[1])) |
3484 { | 3484 { |
3485 int n, nr; | 3485 int n, nr; |
3486 int c = toupper(*p); | 3486 int c = toupper(*p); |
3496 { | 3496 { |
3497 ++p; | 3497 ++p; |
3498 nr = (nr << 4) + hex2nr(*p); | 3498 nr = (nr << 4) + hex2nr(*p); |
3499 } | 3499 } |
3500 ++p; | 3500 ++p; |
3501 /* For "\u" store the number according to | 3501 // For "\u" store the number according to |
3502 * 'encoding'. */ | 3502 // 'encoding'. |
3503 if (c != 'X') | 3503 if (c != 'X') |
3504 name += (*mb_char2bytes)(nr, name); | 3504 name += (*mb_char2bytes)(nr, name); |
3505 else | 3505 else |
3506 *name++ = nr; | 3506 *name++ = nr; |
3507 } | 3507 } |
3508 break; | 3508 break; |
3509 | 3509 |
3510 /* octal: "\1", "\12", "\123" */ | 3510 // octal: "\1", "\12", "\123" |
3511 case '0': | 3511 case '0': |
3512 case '1': | 3512 case '1': |
3513 case '2': | 3513 case '2': |
3514 case '3': | 3514 case '3': |
3515 case '4': | 3515 case '4': |
3523 *name = (*name << 3) + *p++ - '0'; | 3523 *name = (*name << 3) + *p++ - '0'; |
3524 } | 3524 } |
3525 ++name; | 3525 ++name; |
3526 break; | 3526 break; |
3527 | 3527 |
3528 /* Special key, e.g.: "\<C-W>" */ | 3528 // Special key, e.g.: "\<C-W>" |
3529 case '<': extra = trans_special(&p, name, TRUE, TRUE, | 3529 case '<': extra = trans_special(&p, name, TRUE, TRUE, |
3530 TRUE, NULL); | 3530 TRUE, NULL); |
3531 if (extra != 0) | 3531 if (extra != 0) |
3532 { | 3532 { |
3533 name += extra; | 3533 name += extra; |
3534 break; | 3534 break; |
3535 } | 3535 } |
3536 /* FALLTHROUGH */ | 3536 // FALLTHROUGH |
3537 | 3537 |
3538 default: MB_COPY_CHAR(p, name); | 3538 default: MB_COPY_CHAR(p, name); |
3539 break; | 3539 break; |
3540 } | 3540 } |
3541 } | 3541 } |
3542 else | 3542 else |
3543 MB_COPY_CHAR(p, name); | 3543 MB_COPY_CHAR(p, name); |
3544 | 3544 |
3545 } | 3545 } |
3546 *name = NUL; | 3546 *name = NUL; |
3547 if (*p != NUL) /* just in case */ | 3547 if (*p != NUL) // just in case |
3548 ++p; | 3548 ++p; |
3549 *arg = p; | 3549 *arg = p; |
3550 | 3550 |
3551 return OK; | 3551 return OK; |
3552 } | 3552 } |
3580 { | 3580 { |
3581 semsg(_("E115: Missing quote: %s"), *arg); | 3581 semsg(_("E115: Missing quote: %s"), *arg); |
3582 return FAIL; | 3582 return FAIL; |
3583 } | 3583 } |
3584 | 3584 |
3585 /* If only parsing return after setting "*arg" */ | 3585 // If only parsing return after setting "*arg" |
3586 if (!evaluate) | 3586 if (!evaluate) |
3587 { | 3587 { |
3588 *arg = p + 1; | 3588 *arg = p + 1; |
3589 return OK; | 3589 return OK; |
3590 } | 3590 } |
3659 | 3659 |
3660 static int | 3660 static int |
3661 func_equal( | 3661 func_equal( |
3662 typval_T *tv1, | 3662 typval_T *tv1, |
3663 typval_T *tv2, | 3663 typval_T *tv2, |
3664 int ic) /* ignore case */ | 3664 int ic) // ignore case |
3665 { | 3665 { |
3666 char_u *s1, *s2; | 3666 char_u *s1, *s2; |
3667 dict_T *d1, *d2; | 3667 dict_T *d1, *d2; |
3668 int a1, a2; | 3668 int a1, a2; |
3669 int i; | 3669 int i; |
3670 | 3670 |
3671 /* empty and NULL function name considered the same */ | 3671 // empty and NULL function name considered the same |
3672 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string | 3672 s1 = tv1->v_type == VAR_FUNC ? tv1->vval.v_string |
3673 : partial_name(tv1->vval.v_partial); | 3673 : partial_name(tv1->vval.v_partial); |
3674 if (s1 != NULL && *s1 == NUL) | 3674 if (s1 != NULL && *s1 == NUL) |
3675 s1 = NULL; | 3675 s1 = NULL; |
3676 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string | 3676 s2 = tv2->v_type == VAR_FUNC ? tv2->vval.v_string |
3683 return FALSE; | 3683 return FALSE; |
3684 } | 3684 } |
3685 else if (STRCMP(s1, s2) != 0) | 3685 else if (STRCMP(s1, s2) != 0) |
3686 return FALSE; | 3686 return FALSE; |
3687 | 3687 |
3688 /* empty dict and NULL dict is different */ | 3688 // empty dict and NULL dict is different |
3689 d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict; | 3689 d1 = tv1->v_type == VAR_FUNC ? NULL : tv1->vval.v_partial->pt_dict; |
3690 d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict; | 3690 d2 = tv2->v_type == VAR_FUNC ? NULL : tv2->vval.v_partial->pt_dict; |
3691 if (d1 == NULL || d2 == NULL) | 3691 if (d1 == NULL || d2 == NULL) |
3692 { | 3692 { |
3693 if (d1 != d2) | 3693 if (d1 != d2) |
3694 return FALSE; | 3694 return FALSE; |
3695 } | 3695 } |
3696 else if (!dict_equal(d1, d2, ic, TRUE)) | 3696 else if (!dict_equal(d1, d2, ic, TRUE)) |
3697 return FALSE; | 3697 return FALSE; |
3698 | 3698 |
3699 /* empty list and no list considered the same */ | 3699 // empty list and no list considered the same |
3700 a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc; | 3700 a1 = tv1->v_type == VAR_FUNC ? 0 : tv1->vval.v_partial->pt_argc; |
3701 a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc; | 3701 a2 = tv2->v_type == VAR_FUNC ? 0 : tv2->vval.v_partial->pt_argc; |
3702 if (a1 != a2) | 3702 if (a1 != a2) |
3703 return FALSE; | 3703 return FALSE; |
3704 for (i = 0; i < a1; ++i) | 3704 for (i = 0; i < a1; ++i) |
3716 */ | 3716 */ |
3717 int | 3717 int |
3718 tv_equal( | 3718 tv_equal( |
3719 typval_T *tv1, | 3719 typval_T *tv1, |
3720 typval_T *tv2, | 3720 typval_T *tv2, |
3721 int ic, /* ignore case */ | 3721 int ic, // ignore case |
3722 int recursive) /* TRUE when used recursively */ | 3722 int recursive) // TRUE when used recursively |
3723 { | 3723 { |
3724 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; | 3724 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; |
3725 char_u *s1, *s2; | 3725 char_u *s1, *s2; |
3726 static int recursive_cnt = 0; /* catch recursive loops */ | 3726 static int recursive_cnt = 0; // catch recursive loops |
3727 int r; | 3727 int r; |
3728 | 3728 |
3729 /* Catch lists and dicts that have an endless loop by limiting | 3729 // Catch lists and dicts that have an endless loop by limiting |
3730 * recursiveness to a limit. We guess they are equal then. | 3730 // recursiveness to a limit. We guess they are equal then. |
3731 * A fixed limit has the problem of still taking an awful long time. | 3731 // A fixed limit has the problem of still taking an awful long time. |
3732 * Reduce the limit every time running into it. That should work fine for | 3732 // Reduce the limit every time running into it. That should work fine for |
3733 * deeply linked structures that are not recursively linked and catch | 3733 // deeply linked structures that are not recursively linked and catch |
3734 * recursiveness quickly. */ | 3734 // recursiveness quickly. |
3735 if (!recursive) | 3735 if (!recursive) |
3736 tv_equal_recurse_limit = 1000; | 3736 tv_equal_recurse_limit = 1000; |
3737 if (recursive_cnt >= tv_equal_recurse_limit) | 3737 if (recursive_cnt >= tv_equal_recurse_limit) |
3738 { | 3738 { |
3739 --tv_equal_recurse_limit; | 3739 --tv_equal_recurse_limit; |
3740 return TRUE; | 3740 return TRUE; |
3741 } | 3741 } |
3742 | 3742 |
3743 /* For VAR_FUNC and VAR_PARTIAL compare the function name, bound dict and | 3743 // For VAR_FUNC and VAR_PARTIAL compare the function name, bound dict and |
3744 * arguments. */ | 3744 // arguments. |
3745 if ((tv1->v_type == VAR_FUNC | 3745 if ((tv1->v_type == VAR_FUNC |
3746 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL)) | 3746 || (tv1->v_type == VAR_PARTIAL && tv1->vval.v_partial != NULL)) |
3747 && (tv2->v_type == VAR_FUNC | 3747 && (tv2->v_type == VAR_FUNC |
3748 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) | 3748 || (tv2->v_type == VAR_PARTIAL && tv2->vval.v_partial != NULL))) |
3749 { | 3749 { |
3800 case VAR_PARTIAL: | 3800 case VAR_PARTIAL: |
3801 case VAR_UNKNOWN: | 3801 case VAR_UNKNOWN: |
3802 break; | 3802 break; |
3803 } | 3803 } |
3804 | 3804 |
3805 /* VAR_UNKNOWN can be the result of a invalid expression, let's say it | 3805 // VAR_UNKNOWN can be the result of a invalid expression, let's say it |
3806 * does not equal anything, not even itself. */ | 3806 // does not equal anything, not even itself. |
3807 return FALSE; | 3807 return FALSE; |
3808 } | 3808 } |
3809 | 3809 |
3810 /* | 3810 /* |
3811 * Return the next (unique) copy ID. | 3811 * Return the next (unique) copy ID. |
3853 int did_free = FALSE; | 3853 int did_free = FALSE; |
3854 tabpage_T *tp; | 3854 tabpage_T *tp; |
3855 | 3855 |
3856 if (!testing) | 3856 if (!testing) |
3857 { | 3857 { |
3858 /* Only do this once. */ | 3858 // Only do this once. |
3859 want_garbage_collect = FALSE; | 3859 want_garbage_collect = FALSE; |
3860 may_garbage_collect = FALSE; | 3860 may_garbage_collect = FALSE; |
3861 garbage_collect_at_exit = FALSE; | 3861 garbage_collect_at_exit = FALSE; |
3862 } | 3862 } |
3863 | 3863 |
3864 /* We advance by two because we add one for items referenced through | 3864 // We advance by two because we add one for items referenced through |
3865 * previous_funccal. */ | 3865 // previous_funccal. |
3866 copyID = get_copyID(); | 3866 copyID = get_copyID(); |
3867 | 3867 |
3868 /* | 3868 /* |
3869 * 1. Go through all accessible variables and mark all lists and dicts | 3869 * 1. Go through all accessible variables and mark all lists and dicts |
3870 * with copyID. | 3870 * with copyID. |
3871 */ | 3871 */ |
3872 | 3872 |
3873 /* Don't free variables in the previous_funccal list unless they are only | 3873 // Don't free variables in the previous_funccal list unless they are only |
3874 * referenced through previous_funccal. This must be first, because if | 3874 // referenced through previous_funccal. This must be first, because if |
3875 * the item is referenced elsewhere the funccal must not be freed. */ | 3875 // the item is referenced elsewhere the funccal must not be freed. |
3876 abort = abort || set_ref_in_previous_funccal(copyID); | 3876 abort = abort || set_ref_in_previous_funccal(copyID); |
3877 | 3877 |
3878 /* script-local variables */ | 3878 // script-local variables |
3879 abort = abort || garbage_collect_scriptvars(copyID); | 3879 abort = abort || garbage_collect_scriptvars(copyID); |
3880 | 3880 |
3881 /* buffer-local variables */ | 3881 // buffer-local variables |
3882 FOR_ALL_BUFFERS(buf) | 3882 FOR_ALL_BUFFERS(buf) |
3883 abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID, | 3883 abort = abort || set_ref_in_item(&buf->b_bufvar.di_tv, copyID, |
3884 NULL, NULL); | 3884 NULL, NULL); |
3885 | 3885 |
3886 /* window-local variables */ | 3886 // window-local variables |
3887 FOR_ALL_TAB_WINDOWS(tp, wp) | 3887 FOR_ALL_TAB_WINDOWS(tp, wp) |
3888 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, | 3888 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, |
3889 NULL, NULL); | 3889 NULL, NULL); |
3890 if (aucmd_win != NULL) | 3890 if (aucmd_win != NULL) |
3891 abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID, | 3891 abort = abort || set_ref_in_item(&aucmd_win->w_winvar.di_tv, copyID, |
3898 for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) | 3898 for (wp = tp->tp_first_popupwin; wp != NULL; wp = wp->w_next) |
3899 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, | 3899 abort = abort || set_ref_in_item(&wp->w_winvar.di_tv, copyID, |
3900 NULL, NULL); | 3900 NULL, NULL); |
3901 #endif | 3901 #endif |
3902 | 3902 |
3903 /* tabpage-local variables */ | 3903 // tabpage-local variables |
3904 FOR_ALL_TABPAGES(tp) | 3904 FOR_ALL_TABPAGES(tp) |
3905 abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID, | 3905 abort = abort || set_ref_in_item(&tp->tp_winvar.di_tv, copyID, |
3906 NULL, NULL); | 3906 NULL, NULL); |
3907 /* global variables */ | 3907 // global variables |
3908 abort = abort || garbage_collect_globvars(copyID); | 3908 abort = abort || garbage_collect_globvars(copyID); |
3909 | 3909 |
3910 /* function-local variables */ | 3910 // function-local variables |
3911 abort = abort || set_ref_in_call_stack(copyID); | 3911 abort = abort || set_ref_in_call_stack(copyID); |
3912 | 3912 |
3913 /* named functions (matters for closures) */ | 3913 // named functions (matters for closures) |
3914 abort = abort || set_ref_in_functions(copyID); | 3914 abort = abort || set_ref_in_functions(copyID); |
3915 | 3915 |
3916 /* function call arguments, if v:testing is set. */ | 3916 // function call arguments, if v:testing is set. |
3917 abort = abort || set_ref_in_func_args(copyID); | 3917 abort = abort || set_ref_in_func_args(copyID); |
3918 | 3918 |
3919 /* v: vars */ | 3919 // v: vars |
3920 abort = abort || garbage_collect_vimvars(copyID); | 3920 abort = abort || garbage_collect_vimvars(copyID); |
3921 | 3921 |
3922 // callbacks in buffers | 3922 // callbacks in buffers |
3923 abort = abort || set_ref_in_buffers(copyID); | 3923 abort = abort || set_ref_in_buffers(copyID); |
3924 | 3924 |
3985 static int | 3985 static int |
3986 free_unref_items(int copyID) | 3986 free_unref_items(int copyID) |
3987 { | 3987 { |
3988 int did_free = FALSE; | 3988 int did_free = FALSE; |
3989 | 3989 |
3990 /* Let all "free" functions know that we are here. This means no | 3990 // Let all "free" functions know that we are here. This means no |
3991 * dictionaries, lists, channels or jobs are to be freed, because we will | 3991 // dictionaries, lists, channels or jobs are to be freed, because we will |
3992 * do that here. */ | 3992 // do that here. |
3993 in_free_unref_items = TRUE; | 3993 in_free_unref_items = TRUE; |
3994 | 3994 |
3995 /* | 3995 /* |
3996 * PASS 1: free the contents of the items. We don't free the items | 3996 * PASS 1: free the contents of the items. We don't free the items |
3997 * themselves yet, so that it is possible to decrement refcount counters | 3997 * themselves yet, so that it is possible to decrement refcount counters |
3998 */ | 3998 */ |
3999 | 3999 |
4000 /* Go through the list of dicts and free items without the copyID. */ | 4000 // Go through the list of dicts and free items without the copyID. |
4001 did_free |= dict_free_nonref(copyID); | 4001 did_free |= dict_free_nonref(copyID); |
4002 | 4002 |
4003 /* Go through the list of lists and free items without the copyID. */ | 4003 // Go through the list of lists and free items without the copyID. |
4004 did_free |= list_free_nonref(copyID); | 4004 did_free |= list_free_nonref(copyID); |
4005 | 4005 |
4006 #ifdef FEAT_JOB_CHANNEL | 4006 #ifdef FEAT_JOB_CHANNEL |
4007 /* Go through the list of jobs and free items without the copyID. This | 4007 // Go through the list of jobs and free items without the copyID. This |
4008 * must happen before doing channels, because jobs refer to channels, but | 4008 // must happen before doing channels, because jobs refer to channels, but |
4009 * the reference from the channel to the job isn't tracked. */ | 4009 // the reference from the channel to the job isn't tracked. |
4010 did_free |= free_unused_jobs_contents(copyID, COPYID_MASK); | 4010 did_free |= free_unused_jobs_contents(copyID, COPYID_MASK); |
4011 | 4011 |
4012 /* Go through the list of channels and free items without the copyID. */ | 4012 // Go through the list of channels and free items without the copyID. |
4013 did_free |= free_unused_channels_contents(copyID, COPYID_MASK); | 4013 did_free |= free_unused_channels_contents(copyID, COPYID_MASK); |
4014 #endif | 4014 #endif |
4015 | 4015 |
4016 /* | 4016 /* |
4017 * PASS 2: free the items themselves. | 4017 * PASS 2: free the items themselves. |
4018 */ | 4018 */ |
4019 dict_free_items(copyID); | 4019 dict_free_items(copyID); |
4020 list_free_items(copyID); | 4020 list_free_items(copyID); |
4021 | 4021 |
4022 #ifdef FEAT_JOB_CHANNEL | 4022 #ifdef FEAT_JOB_CHANNEL |
4023 /* Go through the list of jobs and free items without the copyID. This | 4023 // Go through the list of jobs and free items without the copyID. This |
4024 * must happen before doing channels, because jobs refer to channels, but | 4024 // must happen before doing channels, because jobs refer to channels, but |
4025 * the reference from the channel to the job isn't tracked. */ | 4025 // the reference from the channel to the job isn't tracked. |
4026 free_unused_jobs(copyID, COPYID_MASK); | 4026 free_unused_jobs(copyID, COPYID_MASK); |
4027 | 4027 |
4028 /* Go through the list of channels and free items without the copyID. */ | 4028 // Go through the list of channels and free items without the copyID. |
4029 free_unused_channels(copyID, COPYID_MASK); | 4029 free_unused_channels(copyID, COPYID_MASK); |
4030 #endif | 4030 #endif |
4031 | 4031 |
4032 in_free_unref_items = FALSE; | 4032 in_free_unref_items = FALSE; |
4033 | 4033 |
4053 cur_ht = ht; | 4053 cur_ht = ht; |
4054 for (;;) | 4054 for (;;) |
4055 { | 4055 { |
4056 if (!abort) | 4056 if (!abort) |
4057 { | 4057 { |
4058 /* Mark each item in the hashtab. If the item contains a hashtab | 4058 // Mark each item in the hashtab. If the item contains a hashtab |
4059 * it is added to ht_stack, if it contains a list it is added to | 4059 // it is added to ht_stack, if it contains a list it is added to |
4060 * list_stack. */ | 4060 // list_stack. |
4061 todo = (int)cur_ht->ht_used; | 4061 todo = (int)cur_ht->ht_used; |
4062 for (hi = cur_ht->ht_array; todo > 0; ++hi) | 4062 for (hi = cur_ht->ht_array; todo > 0; ++hi) |
4063 if (!HASHITEM_EMPTY(hi)) | 4063 if (!HASHITEM_EMPTY(hi)) |
4064 { | 4064 { |
4065 --todo; | 4065 --todo; |
4069 } | 4069 } |
4070 | 4070 |
4071 if (ht_stack == NULL) | 4071 if (ht_stack == NULL) |
4072 break; | 4072 break; |
4073 | 4073 |
4074 /* take an item from the stack */ | 4074 // take an item from the stack |
4075 cur_ht = ht_stack->ht; | 4075 cur_ht = ht_stack->ht; |
4076 tempitem = ht_stack; | 4076 tempitem = ht_stack; |
4077 ht_stack = ht_stack->prev; | 4077 ht_stack = ht_stack->prev; |
4078 free(tempitem); | 4078 free(tempitem); |
4079 } | 4079 } |
4128 | 4128 |
4129 cur_l = l; | 4129 cur_l = l; |
4130 for (;;) | 4130 for (;;) |
4131 { | 4131 { |
4132 if (!abort) | 4132 if (!abort) |
4133 /* Mark each item in the list. If the item contains a hashtab | 4133 // Mark each item in the list. If the item contains a hashtab |
4134 * it is added to ht_stack, if it contains a list it is added to | 4134 // it is added to ht_stack, if it contains a list it is added to |
4135 * list_stack. */ | 4135 // list_stack. |
4136 for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next) | 4136 for (li = cur_l->lv_first; !abort && li != NULL; li = li->li_next) |
4137 abort = abort || set_ref_in_item(&li->li_tv, copyID, | 4137 abort = abort || set_ref_in_item(&li->li_tv, copyID, |
4138 ht_stack, &list_stack); | 4138 ht_stack, &list_stack); |
4139 if (list_stack == NULL) | 4139 if (list_stack == NULL) |
4140 break; | 4140 break; |
4141 | 4141 |
4142 /* take an item from the stack */ | 4142 // take an item from the stack |
4143 cur_l = list_stack->list; | 4143 cur_l = list_stack->list; |
4144 tempitem = list_stack; | 4144 tempitem = list_stack; |
4145 list_stack = list_stack->prev; | 4145 list_stack = list_stack->prev; |
4146 free(tempitem); | 4146 free(tempitem); |
4147 } | 4147 } |
4169 { | 4169 { |
4170 dict_T *dd = tv->vval.v_dict; | 4170 dict_T *dd = tv->vval.v_dict; |
4171 | 4171 |
4172 if (dd != NULL && dd->dv_copyID != copyID) | 4172 if (dd != NULL && dd->dv_copyID != copyID) |
4173 { | 4173 { |
4174 /* Didn't see this dict yet. */ | 4174 // Didn't see this dict yet. |
4175 dd->dv_copyID = copyID; | 4175 dd->dv_copyID = copyID; |
4176 if (ht_stack == NULL) | 4176 if (ht_stack == NULL) |
4177 { | 4177 { |
4178 abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); | 4178 abort = set_ref_in_ht(&dd->dv_hashtab, copyID, list_stack); |
4179 } | 4179 } |
4195 { | 4195 { |
4196 list_T *ll = tv->vval.v_list; | 4196 list_T *ll = tv->vval.v_list; |
4197 | 4197 |
4198 if (ll != NULL && ll->lv_copyID != copyID) | 4198 if (ll != NULL && ll->lv_copyID != copyID) |
4199 { | 4199 { |
4200 /* Didn't see this list yet. */ | 4200 // Didn't see this list yet. |
4201 ll->lv_copyID = copyID; | 4201 ll->lv_copyID = copyID; |
4202 if (list_stack == NULL) | 4202 if (list_stack == NULL) |
4203 { | 4203 { |
4204 abort = set_ref_in_list_items(ll, copyID, ht_stack); | 4204 abort = set_ref_in_list_items(ll, copyID, ht_stack); |
4205 } | 4205 } |
4225 else if (tv->v_type == VAR_PARTIAL) | 4225 else if (tv->v_type == VAR_PARTIAL) |
4226 { | 4226 { |
4227 partial_T *pt = tv->vval.v_partial; | 4227 partial_T *pt = tv->vval.v_partial; |
4228 int i; | 4228 int i; |
4229 | 4229 |
4230 /* A partial does not have a copyID, because it cannot contain itself. | 4230 // A partial does not have a copyID, because it cannot contain itself. |
4231 */ | |
4232 if (pt != NULL) | 4231 if (pt != NULL) |
4233 { | 4232 { |
4234 abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID); | 4233 abort = set_ref_in_func(pt->pt_name, pt->pt_func, copyID); |
4235 | 4234 |
4236 if (pt->pt_dict != NULL) | 4235 if (pt->pt_dict != NULL) |
4347 | 4346 |
4348 if (recurse >= DICT_MAXNEST) | 4347 if (recurse >= DICT_MAXNEST) |
4349 { | 4348 { |
4350 if (!did_echo_string_emsg) | 4349 if (!did_echo_string_emsg) |
4351 { | 4350 { |
4352 /* Only give this message once for a recursive call to avoid | 4351 // Only give this message once for a recursive call to avoid |
4353 * flooding the user with errors. And stop iterating over lists | 4352 // flooding the user with errors. And stop iterating over lists |
4354 * and dicts. */ | 4353 // and dicts. |
4355 did_echo_string_emsg = TRUE; | 4354 did_echo_string_emsg = TRUE; |
4356 emsg(_("E724: variable nested too deep for displaying")); | 4355 emsg(_("E724: variable nested too deep for displaying")); |
4357 } | 4356 } |
4358 *tofree = NULL; | 4357 *tofree = NULL; |
4359 return (char_u *)"{E724}"; | 4358 return (char_u *)"{E724}"; |
4610 * Returns the length of the text that was consumed. | 4609 * Returns the length of the text that was consumed. |
4611 */ | 4610 */ |
4612 int | 4611 int |
4613 string2float( | 4612 string2float( |
4614 char_u *text, | 4613 char_u *text, |
4615 float_T *value) /* result stored here */ | 4614 float_T *value) // result stored here |
4616 { | 4615 { |
4617 char *s = (char *)text; | 4616 char *s = (char *)text; |
4618 float_T f; | 4617 float_T f; |
4619 | 4618 |
4620 /* MS-Windows does not deal with "inf" and "nan" properly. */ | 4619 // MS-Windows does not deal with "inf" and "nan" properly. |
4621 if (STRNICMP(text, "inf", 3) == 0) | 4620 if (STRNICMP(text, "inf", 3) == 0) |
4622 { | 4621 { |
4623 *value = INFINITY; | 4622 *value = INFINITY; |
4624 return 3; | 4623 return 3; |
4625 } | 4624 } |
4658 name = *arg; | 4657 name = *arg; |
4659 len = get_env_len(arg); | 4658 len = get_env_len(arg); |
4660 if (evaluate) | 4659 if (evaluate) |
4661 { | 4660 { |
4662 if (len == 0) | 4661 if (len == 0) |
4663 return FAIL; /* invalid empty name */ | 4662 return FAIL; // invalid empty name |
4664 | 4663 |
4665 cc = name[len]; | 4664 cc = name[len]; |
4666 name[len] = NUL; | 4665 name[len] = NUL; |
4667 /* first try vim_getenv(), fast for normal environment vars */ | 4666 // first try vim_getenv(), fast for normal environment vars |
4668 string = vim_getenv(name, &mustfree); | 4667 string = vim_getenv(name, &mustfree); |
4669 if (string != NULL && *string != NUL) | 4668 if (string != NULL && *string != NUL) |
4670 { | 4669 { |
4671 if (!mustfree) | 4670 if (!mustfree) |
4672 string = vim_strsave(string); | 4671 string = vim_strsave(string); |
4674 else | 4673 else |
4675 { | 4674 { |
4676 if (mustfree) | 4675 if (mustfree) |
4677 vim_free(string); | 4676 vim_free(string); |
4678 | 4677 |
4679 /* next try expanding things like $VIM and ${HOME} */ | 4678 // next try expanding things like $VIM and ${HOME} |
4680 string = expand_env_save(name - 1); | 4679 string = expand_env_save(name - 1); |
4681 if (string != NULL && *string == '$') | 4680 if (string != NULL && *string == '$') |
4682 VIM_CLEAR(string); | 4681 VIM_CLEAR(string); |
4683 } | 4682 } |
4684 name[len] = cc; | 4683 name[len] = cc; |
4695 * Returns NULL when there is an error. | 4694 * Returns NULL when there is an error. |
4696 */ | 4695 */ |
4697 pos_T * | 4696 pos_T * |
4698 var2fpos( | 4697 var2fpos( |
4699 typval_T *varp, | 4698 typval_T *varp, |
4700 int dollar_lnum, /* TRUE when $ is last line */ | 4699 int dollar_lnum, // TRUE when $ is last line |
4701 int *fnum) /* set to fnum for '0, 'A, etc. */ | 4700 int *fnum) // set to fnum for '0, 'A, etc. |
4702 { | 4701 { |
4703 char_u *name; | 4702 char_u *name; |
4704 static pos_T pos; | 4703 static pos_T pos; |
4705 pos_T *pp; | 4704 pos_T *pp; |
4706 | 4705 |
4707 /* Argument can be [lnum, col, coladd]. */ | 4706 // Argument can be [lnum, col, coladd]. |
4708 if (varp->v_type == VAR_LIST) | 4707 if (varp->v_type == VAR_LIST) |
4709 { | 4708 { |
4710 list_T *l; | 4709 list_T *l; |
4711 int len; | 4710 int len; |
4712 int error = FALSE; | 4711 int error = FALSE; |
4714 | 4713 |
4715 l = varp->vval.v_list; | 4714 l = varp->vval.v_list; |
4716 if (l == NULL) | 4715 if (l == NULL) |
4717 return NULL; | 4716 return NULL; |
4718 | 4717 |
4719 /* Get the line number */ | 4718 // Get the line number |
4720 pos.lnum = list_find_nr(l, 0L, &error); | 4719 pos.lnum = list_find_nr(l, 0L, &error); |
4721 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) | 4720 if (error || pos.lnum <= 0 || pos.lnum > curbuf->b_ml.ml_line_count) |
4722 return NULL; /* invalid line number */ | 4721 return NULL; // invalid line number |
4723 | 4722 |
4724 /* Get the column number */ | 4723 // Get the column number |
4725 pos.col = list_find_nr(l, 1L, &error); | 4724 pos.col = list_find_nr(l, 1L, &error); |
4726 if (error) | 4725 if (error) |
4727 return NULL; | 4726 return NULL; |
4728 len = (long)STRLEN(ml_get(pos.lnum)); | 4727 len = (long)STRLEN(ml_get(pos.lnum)); |
4729 | 4728 |
4730 /* We accept "$" for the column number: last column. */ | 4729 // We accept "$" for the column number: last column. |
4731 li = list_find(l, 1L); | 4730 li = list_find(l, 1L); |
4732 if (li != NULL && li->li_tv.v_type == VAR_STRING | 4731 if (li != NULL && li->li_tv.v_type == VAR_STRING |
4733 && li->li_tv.vval.v_string != NULL | 4732 && li->li_tv.vval.v_string != NULL |
4734 && STRCMP(li->li_tv.vval.v_string, "$") == 0) | 4733 && STRCMP(li->li_tv.vval.v_string, "$") == 0) |
4735 pos.col = len + 1; | 4734 pos.col = len + 1; |
4736 | 4735 |
4737 /* Accept a position up to the NUL after the line. */ | 4736 // Accept a position up to the NUL after the line. |
4738 if (pos.col == 0 || (int)pos.col > len + 1) | 4737 if (pos.col == 0 || (int)pos.col > len + 1) |
4739 return NULL; /* invalid column number */ | 4738 return NULL; // invalid column number |
4740 --pos.col; | 4739 --pos.col; |
4741 | 4740 |
4742 /* Get the virtual offset. Defaults to zero. */ | 4741 // Get the virtual offset. Defaults to zero. |
4743 pos.coladd = list_find_nr(l, 2L, &error); | 4742 pos.coladd = list_find_nr(l, 2L, &error); |
4744 if (error) | 4743 if (error) |
4745 pos.coladd = 0; | 4744 pos.coladd = 0; |
4746 | 4745 |
4747 return &pos; | 4746 return &pos; |
4748 } | 4747 } |
4749 | 4748 |
4750 name = tv_get_string_chk(varp); | 4749 name = tv_get_string_chk(varp); |
4751 if (name == NULL) | 4750 if (name == NULL) |
4752 return NULL; | 4751 return NULL; |
4753 if (name[0] == '.') /* cursor */ | 4752 if (name[0] == '.') // cursor |
4754 return &curwin->w_cursor; | 4753 return &curwin->w_cursor; |
4755 if (name[0] == 'v' && name[1] == NUL) /* Visual start */ | 4754 if (name[0] == 'v' && name[1] == NUL) // Visual start |
4756 { | 4755 { |
4757 if (VIsual_active) | 4756 if (VIsual_active) |
4758 return &VIsual; | 4757 return &VIsual; |
4759 return &curwin->w_cursor; | 4758 return &curwin->w_cursor; |
4760 } | 4759 } |
4761 if (name[0] == '\'') /* mark */ | 4760 if (name[0] == '\'') // mark |
4762 { | 4761 { |
4763 pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum); | 4762 pp = getmark_buf_fnum(curbuf, name[1], FALSE, fnum); |
4764 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) | 4763 if (pp == NULL || pp == (pos_T *)-1 || pp->lnum <= 0) |
4765 return NULL; | 4764 return NULL; |
4766 return pp; | 4765 return pp; |
4769 pos.coladd = 0; | 4768 pos.coladd = 0; |
4770 | 4769 |
4771 if (name[0] == 'w' && dollar_lnum) | 4770 if (name[0] == 'w' && dollar_lnum) |
4772 { | 4771 { |
4773 pos.col = 0; | 4772 pos.col = 0; |
4774 if (name[1] == '0') /* "w0": first visible line */ | 4773 if (name[1] == '0') // "w0": first visible line |
4775 { | 4774 { |
4776 update_topline(); | 4775 update_topline(); |
4777 /* In silent Ex mode topline is zero, but that's not a valid line | 4776 // In silent Ex mode topline is zero, but that's not a valid line |
4778 * number; use one instead. */ | 4777 // number; use one instead. |
4779 pos.lnum = curwin->w_topline > 0 ? curwin->w_topline : 1; | 4778 pos.lnum = curwin->w_topline > 0 ? curwin->w_topline : 1; |
4780 return &pos; | 4779 return &pos; |
4781 } | 4780 } |
4782 else if (name[1] == '$') /* "w$": last visible line */ | 4781 else if (name[1] == '$') // "w$": last visible line |
4783 { | 4782 { |
4784 validate_botline(); | 4783 validate_botline(); |
4785 /* In silent Ex mode botline is zero, return zero then. */ | 4784 // In silent Ex mode botline is zero, return zero then. |
4786 pos.lnum = curwin->w_botline > 0 ? curwin->w_botline - 1 : 0; | 4785 pos.lnum = curwin->w_botline > 0 ? curwin->w_botline - 1 : 0; |
4787 return &pos; | 4786 return &pos; |
4788 } | 4787 } |
4789 } | 4788 } |
4790 else if (name[0] == '$') /* last column or line */ | 4789 else if (name[0] == '$') // last column or line |
4791 { | 4790 { |
4792 if (dollar_lnum) | 4791 if (dollar_lnum) |
4793 { | 4792 { |
4794 pos.lnum = curbuf->b_ml.ml_line_count; | 4793 pos.lnum = curbuf->b_ml.ml_line_count; |
4795 pos.col = 0; | 4794 pos.col = 0; |
4821 { | 4820 { |
4822 list_T *l = arg->vval.v_list; | 4821 list_T *l = arg->vval.v_list; |
4823 long i = 0; | 4822 long i = 0; |
4824 long n; | 4823 long n; |
4825 | 4824 |
4826 /* List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only | 4825 // List must be: [fnum, lnum, col, coladd, curswant], where "fnum" is only |
4827 * there when "fnump" isn't NULL; "coladd" and "curswant" are optional. */ | 4826 // there when "fnump" isn't NULL; "coladd" and "curswant" are optional. |
4828 if (arg->v_type != VAR_LIST | 4827 if (arg->v_type != VAR_LIST |
4829 || l == NULL | 4828 || l == NULL |
4830 || l->lv_len < (fnump == NULL ? 2 : 3) | 4829 || l->lv_len < (fnump == NULL ? 2 : 3) |
4831 || l->lv_len > (fnump == NULL ? 4 : 5)) | 4830 || l->lv_len > (fnump == NULL ? 4 : 5)) |
4832 return FAIL; | 4831 return FAIL; |
4833 | 4832 |
4834 if (fnump != NULL) | 4833 if (fnump != NULL) |
4835 { | 4834 { |
4836 n = list_find_nr(l, i++, NULL); /* fnum */ | 4835 n = list_find_nr(l, i++, NULL); // fnum |
4837 if (n < 0) | 4836 if (n < 0) |
4838 return FAIL; | 4837 return FAIL; |
4839 if (n == 0) | 4838 if (n == 0) |
4840 n = curbuf->b_fnum; /* current buffer */ | 4839 n = curbuf->b_fnum; // current buffer |
4841 *fnump = n; | 4840 *fnump = n; |
4842 } | 4841 } |
4843 | 4842 |
4844 n = list_find_nr(l, i++, NULL); /* lnum */ | 4843 n = list_find_nr(l, i++, NULL); // lnum |
4845 if (n < 0) | 4844 if (n < 0) |
4846 return FAIL; | 4845 return FAIL; |
4847 posp->lnum = n; | 4846 posp->lnum = n; |
4848 | 4847 |
4849 n = list_find_nr(l, i++, NULL); /* col */ | 4848 n = list_find_nr(l, i++, NULL); // col |
4850 if (n < 0) | 4849 if (n < 0) |
4851 return FAIL; | 4850 return FAIL; |
4852 posp->col = n; | 4851 posp->col = n; |
4853 | 4852 |
4854 n = list_find_nr(l, i, NULL); /* off */ | 4853 n = list_find_nr(l, i, NULL); // off |
4855 if (n < 0) | 4854 if (n < 0) |
4856 posp->coladd = 0; | 4855 posp->coladd = 0; |
4857 else | 4856 else |
4858 posp->coladd = n; | 4857 posp->coladd = n; |
4859 | 4858 |
4860 if (curswantp != NULL) | 4859 if (curswantp != NULL) |
4861 *curswantp = list_find_nr(l, i + 1, NULL); /* curswant */ | 4860 *curswantp = list_find_nr(l, i + 1, NULL); // curswant |
4862 | 4861 |
4863 return OK; | 4862 return OK; |
4864 } | 4863 } |
4865 | 4864 |
4866 /* | 4865 /* |
4874 char_u *p; | 4873 char_u *p; |
4875 int len; | 4874 int len; |
4876 | 4875 |
4877 for (p = *arg; vim_isIDc(*p); ++p) | 4876 for (p = *arg; vim_isIDc(*p); ++p) |
4878 ; | 4877 ; |
4879 if (p == *arg) /* no name found */ | 4878 if (p == *arg) // no name found |
4880 return 0; | 4879 return 0; |
4881 | 4880 |
4882 len = (int)(p - *arg); | 4881 len = (int)(p - *arg); |
4883 *arg = p; | 4882 *arg = p; |
4884 return len; | 4883 return len; |
4893 get_id_len(char_u **arg) | 4892 get_id_len(char_u **arg) |
4894 { | 4893 { |
4895 char_u *p; | 4894 char_u *p; |
4896 int len; | 4895 int len; |
4897 | 4896 |
4898 /* Find the end of the name. */ | 4897 // Find the end of the name. |
4899 for (p = *arg; eval_isnamec(*p); ++p) | 4898 for (p = *arg; eval_isnamec(*p); ++p) |
4900 { | 4899 { |
4901 if (*p == ':') | 4900 if (*p == ':') |
4902 { | 4901 { |
4903 /* "s:" is start of "s:var", but "n:" is not and can be used in | 4902 // "s:" is start of "s:var", but "n:" is not and can be used in |
4904 * slice "[n:]". Also "xx:" is not a namespace. */ | 4903 // slice "[n:]". Also "xx:" is not a namespace. |
4905 len = (int)(p - *arg); | 4904 len = (int)(p - *arg); |
4906 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, **arg) == NULL) | 4905 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, **arg) == NULL) |
4907 || len > 1) | 4906 || len > 1) |
4908 break; | 4907 break; |
4909 } | 4908 } |
4910 } | 4909 } |
4911 if (p == *arg) /* no name found */ | 4910 if (p == *arg) // no name found |
4912 return 0; | 4911 return 0; |
4913 | 4912 |
4914 len = (int)(p - *arg); | 4913 len = (int)(p - *arg); |
4915 *arg = skipwhite(p); | 4914 *arg = skipwhite(p); |
4916 | 4915 |
4936 int len; | 4935 int len; |
4937 char_u *p; | 4936 char_u *p; |
4938 char_u *expr_start; | 4937 char_u *expr_start; |
4939 char_u *expr_end; | 4938 char_u *expr_end; |
4940 | 4939 |
4941 *alias = NULL; /* default to no alias */ | 4940 *alias = NULL; // default to no alias |
4942 | 4941 |
4943 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA | 4942 if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA |
4944 && (*arg)[2] == (int)KE_SNR) | 4943 && (*arg)[2] == (int)KE_SNR) |
4945 { | 4944 { |
4946 /* hard coded <SNR>, already translated */ | 4945 // hard coded <SNR>, already translated |
4947 *arg += 3; | 4946 *arg += 3; |
4948 return get_id_len(arg) + 3; | 4947 return get_id_len(arg) + 3; |
4949 } | 4948 } |
4950 len = eval_fname_script(*arg); | 4949 len = eval_fname_script(*arg); |
4951 if (len > 0) | 4950 if (len > 0) |
4952 { | 4951 { |
4953 /* literal "<SID>", "s:" or "<SNR>" */ | 4952 // literal "<SID>", "s:" or "<SNR>" |
4954 *arg += len; | 4953 *arg += len; |
4955 } | 4954 } |
4956 | 4955 |
4957 /* | 4956 /* |
4958 * Find the end of the name; check for {} construction. | 4957 * Find the end of the name; check for {} construction. |
5015 { | 5014 { |
5016 *expr_start = NULL; | 5015 *expr_start = NULL; |
5017 *expr_end = NULL; | 5016 *expr_end = NULL; |
5018 } | 5017 } |
5019 | 5018 |
5020 /* Quick check for valid starting character. */ | 5019 // Quick check for valid starting character. |
5021 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') | 5020 if ((flags & FNE_CHECK_START) && !eval_isnamec1(*arg) && *arg != '{') |
5022 return arg; | 5021 return arg; |
5023 | 5022 |
5024 for (p = arg; *p != NUL | 5023 for (p = arg; *p != NUL |
5025 && (eval_isnamec(*p) | 5024 && (eval_isnamec(*p) |
5028 || mb_nest != 0 | 5027 || mb_nest != 0 |
5029 || br_nest != 0); MB_PTR_ADV(p)) | 5028 || br_nest != 0); MB_PTR_ADV(p)) |
5030 { | 5029 { |
5031 if (*p == '\'') | 5030 if (*p == '\'') |
5032 { | 5031 { |
5033 /* skip over 'string' to avoid counting [ and ] inside it. */ | 5032 // skip over 'string' to avoid counting [ and ] inside it. |
5034 for (p = p + 1; *p != NUL && *p != '\''; MB_PTR_ADV(p)) | 5033 for (p = p + 1; *p != NUL && *p != '\''; MB_PTR_ADV(p)) |
5035 ; | 5034 ; |
5036 if (*p == NUL) | 5035 if (*p == NUL) |
5037 break; | 5036 break; |
5038 } | 5037 } |
5039 else if (*p == '"') | 5038 else if (*p == '"') |
5040 { | 5039 { |
5041 /* skip over "str\"ing" to avoid counting [ and ] inside it. */ | 5040 // skip over "str\"ing" to avoid counting [ and ] inside it. |
5042 for (p = p + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p)) | 5041 for (p = p + 1; *p != NUL && *p != '"'; MB_PTR_ADV(p)) |
5043 if (*p == '\\' && p[1] != NUL) | 5042 if (*p == '\\' && p[1] != NUL) |
5044 ++p; | 5043 ++p; |
5045 if (*p == NUL) | 5044 if (*p == NUL) |
5046 break; | 5045 break; |
5047 } | 5046 } |
5048 else if (br_nest == 0 && mb_nest == 0 && *p == ':') | 5047 else if (br_nest == 0 && mb_nest == 0 && *p == ':') |
5049 { | 5048 { |
5050 /* "s:" is start of "s:var", but "n:" is not and can be used in | 5049 // "s:" is start of "s:var", but "n:" is not and can be used in |
5051 * slice "[n:]". Also "xx:" is not a namespace. But {ns}: is. */ | 5050 // slice "[n:]". Also "xx:" is not a namespace. But {ns}: is. |
5052 len = (int)(p - arg); | 5051 len = (int)(p - arg); |
5053 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, *arg) == NULL) | 5052 if ((len == 1 && vim_strchr(NAMESPACE_CHAR, *arg) == NULL) |
5054 || (len > 1 && p[-1] != '}')) | 5053 || (len > 1 && p[-1] != '}')) |
5055 break; | 5054 break; |
5056 } | 5055 } |
5127 STRCAT(retval, expr_end + 1); | 5126 STRCAT(retval, expr_end + 1); |
5128 } | 5127 } |
5129 } | 5128 } |
5130 vim_free(temp_result); | 5129 vim_free(temp_result); |
5131 | 5130 |
5132 *in_end = c1; /* put char back for error messages */ | 5131 *in_end = c1; // put char back for error messages |
5133 *expr_start = '{'; | 5132 *expr_start = '{'; |
5134 *expr_end = '}'; | 5133 *expr_end = '}'; |
5135 | 5134 |
5136 if (retval != NULL) | 5135 if (retval != NULL) |
5137 { | 5136 { |
5138 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); | 5137 temp_result = find_name_end(retval, &expr_start, &expr_end, 0); |
5139 if (expr_start != NULL) | 5138 if (expr_start != NULL) |
5140 { | 5139 { |
5141 /* Further expansion! */ | 5140 // Further expansion! |
5142 temp_result = make_expanded_name(retval, expr_start, | 5141 temp_result = make_expanded_name(retval, expr_start, |
5143 expr_end, temp_result); | 5142 expr_end, temp_result); |
5144 vim_free(retval); | 5143 vim_free(retval); |
5145 retval = temp_result; | 5144 retval = temp_result; |
5146 } | 5145 } |
5233 else | 5232 else |
5234 // expr->name() | 5233 // expr->name() |
5235 ret = eval_method(arg, rettv, evaluate, verbose); | 5234 ret = eval_method(arg, rettv, evaluate, verbose); |
5236 } | 5235 } |
5237 } | 5236 } |
5238 else /* **arg == '[' || **arg == '.' */ | 5237 else // **arg == '[' || **arg == '.' |
5239 { | 5238 { |
5240 dict_unref(selfdict); | 5239 dict_unref(selfdict); |
5241 if (rettv->v_type == VAR_DICT) | 5240 if (rettv->v_type == VAR_DICT) |
5242 { | 5241 { |
5243 selfdict = rettv->vval.v_dict; | 5242 selfdict = rettv->vval.v_dict; |
5252 ret = FAIL; | 5251 ret = FAIL; |
5253 } | 5252 } |
5254 } | 5253 } |
5255 } | 5254 } |
5256 | 5255 |
5257 /* Turn "dict.Func" into a partial for "Func" bound to "dict". | 5256 // Turn "dict.Func" into a partial for "Func" bound to "dict". |
5258 * Don't do this when "Func" is already a partial that was bound | 5257 // Don't do this when "Func" is already a partial that was bound |
5259 * explicitly (pt_auto is FALSE). */ | 5258 // explicitly (pt_auto is FALSE). |
5260 if (selfdict != NULL | 5259 if (selfdict != NULL |
5261 && (rettv->v_type == VAR_FUNC | 5260 && (rettv->v_type == VAR_FUNC |
5262 || (rettv->v_type == VAR_PARTIAL | 5261 || (rettv->v_type == VAR_PARTIAL |
5263 && (rettv->vval.v_partial->pt_auto | 5262 && (rettv->vval.v_partial->pt_auto |
5264 || rettv->vval.v_partial->pt_dict == NULL)))) | 5263 || rettv->vval.v_partial->pt_dict == NULL)))) |
5309 { | 5308 { |
5310 switch (varp->v_type) | 5309 switch (varp->v_type) |
5311 { | 5310 { |
5312 case VAR_FUNC: | 5311 case VAR_FUNC: |
5313 func_unref(varp->vval.v_string); | 5312 func_unref(varp->vval.v_string); |
5314 /* FALLTHROUGH */ | 5313 // FALLTHROUGH |
5315 case VAR_STRING: | 5314 case VAR_STRING: |
5316 vim_free(varp->vval.v_string); | 5315 vim_free(varp->vval.v_string); |
5317 break; | 5316 break; |
5318 case VAR_PARTIAL: | 5317 case VAR_PARTIAL: |
5319 partial_unref(varp->vval.v_partial); | 5318 partial_unref(varp->vval.v_partial); |
5357 { | 5356 { |
5358 switch (varp->v_type) | 5357 switch (varp->v_type) |
5359 { | 5358 { |
5360 case VAR_FUNC: | 5359 case VAR_FUNC: |
5361 func_unref(varp->vval.v_string); | 5360 func_unref(varp->vval.v_string); |
5362 /* FALLTHROUGH */ | 5361 // FALLTHROUGH |
5363 case VAR_STRING: | 5362 case VAR_STRING: |
5364 VIM_CLEAR(varp->vval.v_string); | 5363 VIM_CLEAR(varp->vval.v_string); |
5365 break; | 5364 break; |
5366 case VAR_PARTIAL: | 5365 case VAR_PARTIAL: |
5367 partial_unref(varp->vval.v_partial); | 5366 partial_unref(varp->vval.v_partial); |
5427 varnumber_T | 5426 varnumber_T |
5428 tv_get_number(typval_T *varp) | 5427 tv_get_number(typval_T *varp) |
5429 { | 5428 { |
5430 int error = FALSE; | 5429 int error = FALSE; |
5431 | 5430 |
5432 return tv_get_number_chk(varp, &error); /* return 0L on error */ | 5431 return tv_get_number_chk(varp, &error); // return 0L on error |
5433 } | 5432 } |
5434 | 5433 |
5435 varnumber_T | 5434 varnumber_T |
5436 tv_get_number_chk(typval_T *varp, int *denote) | 5435 tv_get_number_chk(typval_T *varp, int *denote) |
5437 { | 5436 { |
5479 break; | 5478 break; |
5480 case VAR_UNKNOWN: | 5479 case VAR_UNKNOWN: |
5481 internal_error("tv_get_number(UNKNOWN)"); | 5480 internal_error("tv_get_number(UNKNOWN)"); |
5482 break; | 5481 break; |
5483 } | 5482 } |
5484 if (denote == NULL) /* useful for values that must be unsigned */ | 5483 if (denote == NULL) // useful for values that must be unsigned |
5485 n = -1; | 5484 n = -1; |
5486 else | 5485 else |
5487 *denote = TRUE; | 5486 *denote = TRUE; |
5488 return n; | 5487 return n; |
5489 } | 5488 } |
5624 vim_snprintf((char *)buf, NUMBUFLEN, | 5623 vim_snprintf((char *)buf, NUMBUFLEN, |
5625 "process %ld %s", | 5624 "process %ld %s", |
5626 (long)job->jv_proc_info.dwProcessId, | 5625 (long)job->jv_proc_info.dwProcessId, |
5627 status); | 5626 status); |
5628 # else | 5627 # else |
5629 /* fall-back */ | 5628 // fall-back |
5630 vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status); | 5629 vim_snprintf((char *)buf, NUMBUFLEN, "process ? %s", status); |
5631 # endif | 5630 # endif |
5632 return buf; | 5631 return buf; |
5633 } | 5632 } |
5634 #endif | 5633 #endif |
5841 to->v_lock = 0; | 5840 to->v_lock = 0; |
5842 if (from->vval.v_list == NULL) | 5841 if (from->vval.v_list == NULL) |
5843 to->vval.v_list = NULL; | 5842 to->vval.v_list = NULL; |
5844 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) | 5843 else if (copyID != 0 && from->vval.v_list->lv_copyID == copyID) |
5845 { | 5844 { |
5846 /* use the copy made earlier */ | 5845 // use the copy made earlier |
5847 to->vval.v_list = from->vval.v_list->lv_copylist; | 5846 to->vval.v_list = from->vval.v_list->lv_copylist; |
5848 ++to->vval.v_list->lv_refcount; | 5847 ++to->vval.v_list->lv_refcount; |
5849 } | 5848 } |
5850 else | 5849 else |
5851 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); | 5850 to->vval.v_list = list_copy(from->vval.v_list, deep, copyID); |
5860 to->v_lock = 0; | 5859 to->v_lock = 0; |
5861 if (from->vval.v_dict == NULL) | 5860 if (from->vval.v_dict == NULL) |
5862 to->vval.v_dict = NULL; | 5861 to->vval.v_dict = NULL; |
5863 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) | 5862 else if (copyID != 0 && from->vval.v_dict->dv_copyID == copyID) |
5864 { | 5863 { |
5865 /* use the copy made earlier */ | 5864 // use the copy made earlier |
5866 to->vval.v_dict = from->vval.v_dict->dv_copydict; | 5865 to->vval.v_dict = from->vval.v_dict->dv_copydict; |
5867 ++to->vval.v_dict->dv_refcount; | 5866 ++to->vval.v_dict->dv_refcount; |
5868 } | 5867 } |
5869 else | 5868 else |
5870 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); | 5869 to->vval.v_dict = dict_copy(from->vval.v_dict, deep, copyID); |
5899 | 5898 |
5900 if (eap->skip) | 5899 if (eap->skip) |
5901 ++emsg_skip; | 5900 ++emsg_skip; |
5902 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) | 5901 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) |
5903 { | 5902 { |
5904 /* If eval1() causes an error message the text from the command may | 5903 // If eval1() causes an error message the text from the command may |
5905 * still need to be cleared. E.g., "echo 22,44". */ | 5904 // still need to be cleared. E.g., "echo 22,44". |
5906 need_clr_eos = needclr; | 5905 need_clr_eos = needclr; |
5907 | 5906 |
5908 p = arg; | 5907 p = arg; |
5909 if (eval1(&arg, &rettv, !eap->skip) == FAIL) | 5908 if (eval1(&arg, &rettv, !eap->skip) == FAIL) |
5910 { | 5909 { |
5924 if (!eap->skip) | 5923 if (!eap->skip) |
5925 { | 5924 { |
5926 if (atstart) | 5925 if (atstart) |
5927 { | 5926 { |
5928 atstart = FALSE; | 5927 atstart = FALSE; |
5929 /* Call msg_start() after eval1(), evaluating the expression | 5928 // Call msg_start() after eval1(), evaluating the expression |
5930 * may cause a message to appear. */ | 5929 // may cause a message to appear. |
5931 if (eap->cmdidx == CMD_echo) | 5930 if (eap->cmdidx == CMD_echo) |
5932 { | 5931 { |
5933 /* Mark the saved text as finishing the line, so that what | 5932 // Mark the saved text as finishing the line, so that what |
5934 * follows is displayed on a new line when scrolling back | 5933 // follows is displayed on a new line when scrolling back |
5935 * at the more prompt. */ | 5934 // at the more prompt. |
5936 msg_sb_eol(); | 5935 msg_sb_eol(); |
5937 msg_start(); | 5936 msg_start(); |
5938 } | 5937 } |
5939 } | 5938 } |
5940 else if (eap->cmdidx == CMD_echo) | 5939 else if (eap->cmdidx == CMD_echo) |
5945 { | 5944 { |
5946 if (*p == '\n' || *p == '\r' || *p == TAB) | 5945 if (*p == '\n' || *p == '\r' || *p == TAB) |
5947 { | 5946 { |
5948 if (*p != TAB && needclr) | 5947 if (*p != TAB && needclr) |
5949 { | 5948 { |
5950 /* remove any text still there from the command */ | 5949 // remove any text still there from the command |
5951 msg_clr_eos(); | 5950 msg_clr_eos(); |
5952 needclr = FALSE; | 5951 needclr = FALSE; |
5953 } | 5952 } |
5954 msg_putchar_attr(*p, echo_attr); | 5953 msg_putchar_attr(*p, echo_attr); |
5955 } | 5954 } |
5975 | 5974 |
5976 if (eap->skip) | 5975 if (eap->skip) |
5977 --emsg_skip; | 5976 --emsg_skip; |
5978 else | 5977 else |
5979 { | 5978 { |
5980 /* remove text that may still be there from the command */ | 5979 // remove text that may still be there from the command |
5981 if (needclr) | 5980 if (needclr) |
5982 msg_clr_eos(); | 5981 msg_clr_eos(); |
5983 if (eap->cmdidx == CMD_echo) | 5982 if (eap->cmdidx == CMD_echo) |
5984 msg_end(); | 5983 msg_end(); |
5985 } | 5984 } |
6058 | 6057 |
6059 if (ret != FAIL && ga.ga_data != NULL) | 6058 if (ret != FAIL && ga.ga_data != NULL) |
6060 { | 6059 { |
6061 if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echoerr) | 6060 if (eap->cmdidx == CMD_echomsg || eap->cmdidx == CMD_echoerr) |
6062 { | 6061 { |
6063 /* Mark the already saved text as finishing the line, so that what | 6062 // Mark the already saved text as finishing the line, so that what |
6064 * follows is displayed on a new line when scrolling back at the | 6063 // follows is displayed on a new line when scrolling back at the |
6065 * more prompt. */ | 6064 // more prompt. |
6066 msg_sb_eol(); | 6065 msg_sb_eol(); |
6067 } | 6066 } |
6068 | 6067 |
6069 if (eap->cmdidx == CMD_echomsg) | 6068 if (eap->cmdidx == CMD_echomsg) |
6070 { | 6069 { |
6071 msg_attr(ga.ga_data, echo_attr); | 6070 msg_attr(ga.ga_data, echo_attr); |
6072 out_flush(); | 6071 out_flush(); |
6073 } | 6072 } |
6074 else if (eap->cmdidx == CMD_echoerr) | 6073 else if (eap->cmdidx == CMD_echoerr) |
6075 { | 6074 { |
6076 /* We don't want to abort following commands, restore did_emsg. */ | 6075 // We don't want to abort following commands, restore did_emsg. |
6077 save_did_emsg = did_emsg; | 6076 save_did_emsg = did_emsg; |
6078 emsg(ga.ga_data); | 6077 emsg(ga.ga_data); |
6079 if (!force_abort) | 6078 if (!force_abort) |
6080 did_emsg = save_did_emsg; | 6079 did_emsg = save_did_emsg; |
6081 } | 6080 } |
6120 if (!ASCII_ISALPHA(*p)) | 6119 if (!ASCII_ISALPHA(*p)) |
6121 return NULL; | 6120 return NULL; |
6122 *arg = p; | 6121 *arg = p; |
6123 | 6122 |
6124 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) | 6123 if (p[0] == 't' && p[1] == '_' && p[2] != NUL && p[3] != NUL) |
6125 p += 4; /* termcap option */ | 6124 p += 4; // termcap option |
6126 else | 6125 else |
6127 while (ASCII_ISALPHA(*p)) | 6126 while (ASCII_ISALPHA(*p)) |
6128 ++p; | 6127 ++p; |
6129 return p; | 6128 return p; |
6130 } | 6129 } |
6160 /* | 6159 /* |
6161 * Compare "typ1" and "typ2". Put the result in "typ1". | 6160 * Compare "typ1" and "typ2". Put the result in "typ1". |
6162 */ | 6161 */ |
6163 int | 6162 int |
6164 typval_compare( | 6163 typval_compare( |
6165 typval_T *typ1, /* first operand */ | 6164 typval_T *typ1, // first operand |
6166 typval_T *typ2, /* second operand */ | 6165 typval_T *typ2, // second operand |
6167 exptype_T type, /* operator */ | 6166 exptype_T type, // operator |
6168 int type_is, /* TRUE for "is" and "isnot" */ | 6167 int type_is, // TRUE for "is" and "isnot" |
6169 int ic) /* ignore case */ | 6168 int ic) // ignore case |
6170 { | 6169 { |
6171 int i; | 6170 int i; |
6172 varnumber_T n1, n2; | 6171 varnumber_T n1, n2; |
6173 char_u *s1, *s2; | 6172 char_u *s1, *s2; |
6174 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; | 6173 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; |
6175 | 6174 |
6176 if (type_is && typ1->v_type != typ2->v_type) | 6175 if (type_is && typ1->v_type != typ2->v_type) |
6177 { | 6176 { |
6178 /* For "is" a different type always means FALSE, for "notis" | 6177 // For "is" a different type always means FALSE, for "notis" |
6179 * it means TRUE. */ | 6178 // it means TRUE. |
6180 n1 = (type == TYPE_NEQUAL); | 6179 n1 = (type == TYPE_NEQUAL); |
6181 } | 6180 } |
6182 else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB) | 6181 else if (typ1->v_type == VAR_BLOB || typ2->v_type == VAR_BLOB) |
6183 { | 6182 { |
6184 if (type_is) | 6183 if (type_is) |
6225 clear_tv(typ1); | 6224 clear_tv(typ1); |
6226 return FAIL; | 6225 return FAIL; |
6227 } | 6226 } |
6228 else | 6227 else |
6229 { | 6228 { |
6230 /* Compare two Lists for being equal or unequal. */ | 6229 // Compare two Lists for being equal or unequal. |
6231 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list, | 6230 n1 = list_equal(typ1->vval.v_list, typ2->vval.v_list, |
6232 ic, FALSE); | 6231 ic, FALSE); |
6233 if (type == TYPE_NEQUAL) | 6232 if (type == TYPE_NEQUAL) |
6234 n1 = !n1; | 6233 n1 = !n1; |
6235 } | 6234 } |
6254 clear_tv(typ1); | 6253 clear_tv(typ1); |
6255 return FAIL; | 6254 return FAIL; |
6256 } | 6255 } |
6257 else | 6256 else |
6258 { | 6257 { |
6259 /* Compare two Dictionaries for being equal or unequal. */ | 6258 // Compare two Dictionaries for being equal or unequal. |
6260 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict, | 6259 n1 = dict_equal(typ1->vval.v_dict, typ2->vval.v_dict, |
6261 ic, FALSE); | 6260 ic, FALSE); |
6262 if (type == TYPE_NEQUAL) | 6261 if (type == TYPE_NEQUAL) |
6263 n1 = !n1; | 6262 n1 = !n1; |
6264 } | 6263 } |
6275 } | 6274 } |
6276 if ((typ1->v_type == VAR_PARTIAL | 6275 if ((typ1->v_type == VAR_PARTIAL |
6277 && typ1->vval.v_partial == NULL) | 6276 && typ1->vval.v_partial == NULL) |
6278 || (typ2->v_type == VAR_PARTIAL | 6277 || (typ2->v_type == VAR_PARTIAL |
6279 && typ2->vval.v_partial == NULL)) | 6278 && typ2->vval.v_partial == NULL)) |
6280 /* when a partial is NULL assume not equal */ | 6279 // when a partial is NULL assume not equal |
6281 n1 = FALSE; | 6280 n1 = FALSE; |
6282 else if (type_is) | 6281 else if (type_is) |
6283 { | 6282 { |
6284 if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC) | 6283 if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC) |
6285 /* strings are considered the same if their value is | 6284 // strings are considered the same if their value is |
6286 * the same */ | 6285 // the same |
6287 n1 = tv_equal(typ1, typ2, ic, FALSE); | 6286 n1 = tv_equal(typ1, typ2, ic, FALSE); |
6288 else if (typ1->v_type == VAR_PARTIAL | 6287 else if (typ1->v_type == VAR_PARTIAL |
6289 && typ2->v_type == VAR_PARTIAL) | 6288 && typ2->v_type == VAR_PARTIAL) |
6290 n1 = (typ1->vval.v_partial == typ2->vval.v_partial); | 6289 n1 = (typ1->vval.v_partial == typ2->vval.v_partial); |
6291 else | 6290 else |
6318 case TYPE_GEQUAL: n1 = (f1 >= f2); break; | 6317 case TYPE_GEQUAL: n1 = (f1 >= f2); break; |
6319 case TYPE_SMALLER: n1 = (f1 < f2); break; | 6318 case TYPE_SMALLER: n1 = (f1 < f2); break; |
6320 case TYPE_SEQUAL: n1 = (f1 <= f2); break; | 6319 case TYPE_SEQUAL: n1 = (f1 <= f2); break; |
6321 case TYPE_UNKNOWN: | 6320 case TYPE_UNKNOWN: |
6322 case TYPE_MATCH: | 6321 case TYPE_MATCH: |
6323 case TYPE_NOMATCH: break; /* avoid gcc warning */ | 6322 case TYPE_NOMATCH: break; // avoid gcc warning |
6324 } | 6323 } |
6325 } | 6324 } |
6326 #endif | 6325 #endif |
6327 | 6326 |
6328 /* | 6327 /* |
6342 case TYPE_GEQUAL: n1 = (n1 >= n2); break; | 6341 case TYPE_GEQUAL: n1 = (n1 >= n2); break; |
6343 case TYPE_SMALLER: n1 = (n1 < n2); break; | 6342 case TYPE_SMALLER: n1 = (n1 < n2); break; |
6344 case TYPE_SEQUAL: n1 = (n1 <= n2); break; | 6343 case TYPE_SEQUAL: n1 = (n1 <= n2); break; |
6345 case TYPE_UNKNOWN: | 6344 case TYPE_UNKNOWN: |
6346 case TYPE_MATCH: | 6345 case TYPE_MATCH: |
6347 case TYPE_NOMATCH: break; /* avoid gcc warning */ | 6346 case TYPE_NOMATCH: break; // avoid gcc warning |
6348 } | 6347 } |
6349 } | 6348 } |
6350 else | 6349 else |
6351 { | 6350 { |
6352 s1 = tv_get_string_buf(typ1, buf1); | 6351 s1 = tv_get_string_buf(typ1, buf1); |
6370 n1 = pattern_match(s2, s1, ic); | 6369 n1 = pattern_match(s2, s1, ic); |
6371 if (type == TYPE_NOMATCH) | 6370 if (type == TYPE_NOMATCH) |
6372 n1 = !n1; | 6371 n1 = !n1; |
6373 break; | 6372 break; |
6374 | 6373 |
6375 case TYPE_UNKNOWN: break; /* avoid gcc warning */ | 6374 case TYPE_UNKNOWN: break; // avoid gcc warning |
6376 } | 6375 } |
6377 } | 6376 } |
6378 clear_tv(typ1); | 6377 clear_tv(typ1); |
6379 typ1->v_type = VAR_NUMBER; | 6378 typ1->v_type = VAR_NUMBER; |
6380 typ1->vval.v_number = n1; | 6379 typ1->vval.v_number = n1; |
6390 char_u *ret = NULL; | 6389 char_u *ret = NULL; |
6391 | 6390 |
6392 if (arg == NULL) | 6391 if (arg == NULL) |
6393 return vim_strsave((char_u *)"(does not exist)"); | 6392 return vim_strsave((char_u *)"(does not exist)"); |
6394 ret = tv2string(arg, &tofree, numbuf, 0); | 6393 ret = tv2string(arg, &tofree, numbuf, 0); |
6395 /* Make a copy if we have a value but it's not in allocated memory. */ | 6394 // Make a copy if we have a value but it's not in allocated memory. |
6396 if (ret != NULL && tofree == NULL) | 6395 if (ret != NULL && tofree == NULL) |
6397 ret = vim_strsave(ret); | 6396 ret = vim_strsave(ret); |
6398 return ret; | 6397 return ret; |
6399 } | 6398 } |
6400 | 6399 |
6423 garray_T ga; | 6422 garray_T ga; |
6424 char_u *ret; | 6423 char_u *ret; |
6425 char_u *save_cpo; | 6424 char_u *save_cpo; |
6426 char_u *zero_width = NULL; | 6425 char_u *zero_width = NULL; |
6427 | 6426 |
6428 /* Make 'cpoptions' empty, so that the 'l' flag doesn't work here */ | 6427 // Make 'cpoptions' empty, so that the 'l' flag doesn't work here |
6429 save_cpo = p_cpo; | 6428 save_cpo = p_cpo; |
6430 p_cpo = empty_option; | 6429 p_cpo = empty_option; |
6431 | 6430 |
6432 ga_init2(&ga, 1, 200); | 6431 ga_init2(&ga, 1, 200); |
6433 | 6432 |
6439 { | 6438 { |
6440 tail = str; | 6439 tail = str; |
6441 end = str + STRLEN(str); | 6440 end = str + STRLEN(str); |
6442 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) | 6441 while (vim_regexec_nl(®match, str, (colnr_T)(tail - str))) |
6443 { | 6442 { |
6444 /* Skip empty match except for first match. */ | 6443 // Skip empty match except for first match. |
6445 if (regmatch.startp[0] == regmatch.endp[0]) | 6444 if (regmatch.startp[0] == regmatch.endp[0]) |
6446 { | 6445 { |
6447 if (zero_width == regmatch.startp[0]) | 6446 if (zero_width == regmatch.startp[0]) |
6448 { | 6447 { |
6449 /* avoid getting stuck on a match with an empty string */ | 6448 // avoid getting stuck on a match with an empty string |
6450 i = mb_ptr2len(tail); | 6449 i = mb_ptr2len(tail); |
6451 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, | 6450 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, |
6452 (size_t)i); | 6451 (size_t)i); |
6453 ga.ga_len += i; | 6452 ga.ga_len += i; |
6454 tail += i; | 6453 tail += i; |
6470 { | 6469 { |
6471 ga_clear(&ga); | 6470 ga_clear(&ga); |
6472 break; | 6471 break; |
6473 } | 6472 } |
6474 | 6473 |
6475 /* copy the text up to where the match is */ | 6474 // copy the text up to where the match is |
6476 i = (int)(regmatch.startp[0] - tail); | 6475 i = (int)(regmatch.startp[0] - tail); |
6477 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); | 6476 mch_memmove((char_u *)ga.ga_data + ga.ga_len, tail, (size_t)i); |
6478 /* add the substituted text */ | 6477 // add the substituted text |
6479 (void)vim_regsub(®match, sub, expr, (char_u *)ga.ga_data | 6478 (void)vim_regsub(®match, sub, expr, (char_u *)ga.ga_data |
6480 + ga.ga_len + i, TRUE, TRUE, FALSE); | 6479 + ga.ga_len + i, TRUE, TRUE, FALSE); |
6481 ga.ga_len += i + sublen - 1; | 6480 ga.ga_len += i + sublen - 1; |
6482 tail = regmatch.endp[0]; | 6481 tail = regmatch.endp[0]; |
6483 if (*tail == NUL) | 6482 if (*tail == NUL) |
6495 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); | 6494 ret = vim_strsave(ga.ga_data == NULL ? str : (char_u *)ga.ga_data); |
6496 ga_clear(&ga); | 6495 ga_clear(&ga); |
6497 if (p_cpo == empty_option) | 6496 if (p_cpo == empty_option) |
6498 p_cpo = save_cpo; | 6497 p_cpo = save_cpo; |
6499 else | 6498 else |
6500 /* Darn, evaluating {sub} expression or {expr} changed the value. */ | 6499 // Darn, evaluating {sub} expression or {expr} changed the value. |
6501 free_string_option(save_cpo); | 6500 free_string_option(save_cpo); |
6502 | 6501 |
6503 return ret; | 6502 return ret; |
6504 } | 6503 } |