Mercurial > vim
comparison src/eval.c @ 17377:cb008de2a6ec v8.1.1687
patch 8.1.1687: the evalfunc.c file is too big
commit https://github.com/vim/vim/commit/ecaa70ea29c269dd0dabd3cd5acdfa0ce42ccd54
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jul 14 14:55:39 2019 +0200
patch 8.1.1687: the evalfunc.c file is too big
Problem: The evalfunc.c file is too big.
Solution: Move testing support to a separate file.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 14 Jul 2019 15:00:05 +0200 |
parents | 6f36caf4f702 |
children | 2558f90045e5 |
comparison
equal
deleted
inserted
replaced
17376:da3299b8b5c0 | 17377:cb008de2a6ec |
---|---|
3619 | 3619 |
3620 /* | 3620 /* |
3621 * Return TRUE if "pat" matches "text". | 3621 * Return TRUE if "pat" matches "text". |
3622 * Does not use 'cpo' and always uses 'magic'. | 3622 * Does not use 'cpo' and always uses 'magic'. |
3623 */ | 3623 */ |
3624 static int | 3624 int |
3625 pattern_match(char_u *pat, char_u *text, int ic) | 3625 pattern_match(char_u *pat, char_u *text, int ic) |
3626 { | 3626 { |
3627 int matches = FALSE; | 3627 int matches = FALSE; |
3628 char_u *save_cpo; | 3628 char_u *save_cpo; |
3629 regmatch_T regmatch; | 3629 regmatch_T regmatch; |
6988 { | 6988 { |
6989 vimvars[idx].vv_nr = val; | 6989 vimvars[idx].vv_nr = val; |
6990 } | 6990 } |
6991 | 6991 |
6992 /* | 6992 /* |
6993 * Get typval_T v: variable value. | |
6994 */ | |
6995 typval_T * | |
6996 get_vim_var_tv(int idx) | |
6997 { | |
6998 return &vimvars[idx].vv_tv; | |
6999 } | |
7000 | |
7001 /* | |
6993 * Get number v: variable value. | 7002 * Get number v: variable value. |
6994 */ | 7003 */ |
6995 varnumber_T | 7004 varnumber_T |
6996 get_vim_var_nr(int idx) | 7005 get_vim_var_nr(int idx) |
6997 { | 7006 { |
9590 set_vim_var_string(VV_OPTION_TYPE, NULL, -1); | 9599 set_vim_var_string(VV_OPTION_TYPE, NULL, -1); |
9591 set_vim_var_string(VV_OPTION_COMMAND, NULL, -1); | 9600 set_vim_var_string(VV_OPTION_COMMAND, NULL, -1); |
9592 } | 9601 } |
9593 | 9602 |
9594 /* | 9603 /* |
9595 * Prepare "gap" for an assert error and add the sourcing position. | |
9596 */ | |
9597 void | |
9598 prepare_assert_error(garray_T *gap) | |
9599 { | |
9600 char buf[NUMBUFLEN]; | |
9601 | |
9602 ga_init2(gap, 1, 100); | |
9603 if (sourcing_name != NULL) | |
9604 { | |
9605 ga_concat(gap, sourcing_name); | |
9606 if (sourcing_lnum > 0) | |
9607 ga_concat(gap, (char_u *)" "); | |
9608 } | |
9609 if (sourcing_lnum > 0) | |
9610 { | |
9611 sprintf(buf, "line %ld", (long)sourcing_lnum); | |
9612 ga_concat(gap, (char_u *)buf); | |
9613 } | |
9614 if (sourcing_name != NULL || sourcing_lnum > 0) | |
9615 ga_concat(gap, (char_u *)": "); | |
9616 } | |
9617 | |
9618 /* | |
9619 * Add an assert error to v:errors. | 9604 * Add an assert error to v:errors. |
9620 */ | 9605 */ |
9621 void | 9606 void |
9622 assert_error(garray_T *gap) | 9607 assert_error(garray_T *gap) |
9623 { | 9608 { |
9626 if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) | 9611 if (vp->vv_type != VAR_LIST || vimvars[VV_ERRORS].vv_list == NULL) |
9627 /* Make sure v:errors is a list. */ | 9612 /* Make sure v:errors is a list. */ |
9628 set_vim_var_list(VV_ERRORS, list_alloc()); | 9613 set_vim_var_list(VV_ERRORS, list_alloc()); |
9629 list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); | 9614 list_append_string(vimvars[VV_ERRORS].vv_list, gap->ga_data, gap->ga_len); |
9630 } | 9615 } |
9631 | |
9632 int | |
9633 assert_equal_common(typval_T *argvars, assert_type_T atype) | |
9634 { | |
9635 garray_T ga; | |
9636 | |
9637 if (tv_equal(&argvars[0], &argvars[1], FALSE, FALSE) | |
9638 != (atype == ASSERT_EQUAL)) | |
9639 { | |
9640 prepare_assert_error(&ga); | |
9641 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], | |
9642 atype); | |
9643 assert_error(&ga); | |
9644 ga_clear(&ga); | |
9645 return 1; | |
9646 } | |
9647 return 0; | |
9648 } | |
9649 | |
9650 int | |
9651 assert_equalfile(typval_T *argvars) | |
9652 { | |
9653 char_u buf1[NUMBUFLEN]; | |
9654 char_u buf2[NUMBUFLEN]; | |
9655 char_u *fname1 = tv_get_string_buf_chk(&argvars[0], buf1); | |
9656 char_u *fname2 = tv_get_string_buf_chk(&argvars[1], buf2); | |
9657 garray_T ga; | |
9658 FILE *fd1; | |
9659 FILE *fd2; | |
9660 | |
9661 if (fname1 == NULL || fname2 == NULL) | |
9662 return 0; | |
9663 | |
9664 IObuff[0] = NUL; | |
9665 fd1 = mch_fopen((char *)fname1, READBIN); | |
9666 if (fd1 == NULL) | |
9667 { | |
9668 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname1); | |
9669 } | |
9670 else | |
9671 { | |
9672 fd2 = mch_fopen((char *)fname2, READBIN); | |
9673 if (fd2 == NULL) | |
9674 { | |
9675 fclose(fd1); | |
9676 vim_snprintf((char *)IObuff, IOSIZE, (char *)e_notread, fname2); | |
9677 } | |
9678 else | |
9679 { | |
9680 int c1, c2; | |
9681 long count = 0; | |
9682 | |
9683 for (;;) | |
9684 { | |
9685 c1 = fgetc(fd1); | |
9686 c2 = fgetc(fd2); | |
9687 if (c1 == EOF) | |
9688 { | |
9689 if (c2 != EOF) | |
9690 STRCPY(IObuff, "first file is shorter"); | |
9691 break; | |
9692 } | |
9693 else if (c2 == EOF) | |
9694 { | |
9695 STRCPY(IObuff, "second file is shorter"); | |
9696 break; | |
9697 } | |
9698 else if (c1 != c2) | |
9699 { | |
9700 vim_snprintf((char *)IObuff, IOSIZE, | |
9701 "difference at byte %ld", count); | |
9702 break; | |
9703 } | |
9704 ++count; | |
9705 } | |
9706 fclose(fd1); | |
9707 fclose(fd2); | |
9708 } | |
9709 } | |
9710 if (IObuff[0] != NUL) | |
9711 { | |
9712 prepare_assert_error(&ga); | |
9713 ga_concat(&ga, IObuff); | |
9714 assert_error(&ga); | |
9715 ga_clear(&ga); | |
9716 return 1; | |
9717 } | |
9718 return 0; | |
9719 } | |
9720 | |
9721 int | |
9722 assert_match_common(typval_T *argvars, assert_type_T atype) | |
9723 { | |
9724 garray_T ga; | |
9725 char_u buf1[NUMBUFLEN]; | |
9726 char_u buf2[NUMBUFLEN]; | |
9727 char_u *pat = tv_get_string_buf_chk(&argvars[0], buf1); | |
9728 char_u *text = tv_get_string_buf_chk(&argvars[1], buf2); | |
9729 | |
9730 if (pat == NULL || text == NULL) | |
9731 emsg(_(e_invarg)); | |
9732 else if (pattern_match(pat, text, FALSE) != (atype == ASSERT_MATCH)) | |
9733 { | |
9734 prepare_assert_error(&ga); | |
9735 fill_assert_error(&ga, &argvars[2], NULL, &argvars[0], &argvars[1], | |
9736 atype); | |
9737 assert_error(&ga); | |
9738 ga_clear(&ga); | |
9739 return 1; | |
9740 } | |
9741 return 0; | |
9742 } | |
9743 | |
9744 int | |
9745 assert_inrange(typval_T *argvars) | |
9746 { | |
9747 garray_T ga; | |
9748 int error = FALSE; | |
9749 char_u *tofree; | |
9750 char msg[200]; | |
9751 char_u numbuf[NUMBUFLEN]; | |
9752 | |
9753 #ifdef FEAT_FLOAT | |
9754 if (argvars[0].v_type == VAR_FLOAT | |
9755 || argvars[1].v_type == VAR_FLOAT | |
9756 || argvars[2].v_type == VAR_FLOAT) | |
9757 { | |
9758 float_T flower = tv_get_float(&argvars[0]); | |
9759 float_T fupper = tv_get_float(&argvars[1]); | |
9760 float_T factual = tv_get_float(&argvars[2]); | |
9761 | |
9762 if (factual < flower || factual > fupper) | |
9763 { | |
9764 prepare_assert_error(&ga); | |
9765 if (argvars[3].v_type != VAR_UNKNOWN) | |
9766 { | |
9767 ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0)); | |
9768 vim_free(tofree); | |
9769 } | |
9770 else | |
9771 { | |
9772 vim_snprintf(msg, 200, "Expected range %g - %g, but got %g", | |
9773 flower, fupper, factual); | |
9774 ga_concat(&ga, (char_u *)msg); | |
9775 } | |
9776 assert_error(&ga); | |
9777 ga_clear(&ga); | |
9778 return 1; | |
9779 } | |
9780 } | |
9781 else | |
9782 #endif | |
9783 { | |
9784 varnumber_T lower = tv_get_number_chk(&argvars[0], &error); | |
9785 varnumber_T upper = tv_get_number_chk(&argvars[1], &error); | |
9786 varnumber_T actual = tv_get_number_chk(&argvars[2], &error); | |
9787 | |
9788 if (error) | |
9789 return 0; | |
9790 if (actual < lower || actual > upper) | |
9791 { | |
9792 prepare_assert_error(&ga); | |
9793 if (argvars[3].v_type != VAR_UNKNOWN) | |
9794 { | |
9795 ga_concat(&ga, tv2string(&argvars[3], &tofree, numbuf, 0)); | |
9796 vim_free(tofree); | |
9797 } | |
9798 else | |
9799 { | |
9800 vim_snprintf(msg, 200, "Expected range %ld - %ld, but got %ld", | |
9801 (long)lower, (long)upper, (long)actual); | |
9802 ga_concat(&ga, (char_u *)msg); | |
9803 } | |
9804 assert_error(&ga); | |
9805 ga_clear(&ga); | |
9806 return 1; | |
9807 } | |
9808 } | |
9809 return 0; | |
9810 } | |
9811 | |
9812 /* | |
9813 * Common for assert_true() and assert_false(). | |
9814 * Return non-zero for failure. | |
9815 */ | |
9816 int | |
9817 assert_bool(typval_T *argvars, int isTrue) | |
9818 { | |
9819 int error = FALSE; | |
9820 garray_T ga; | |
9821 | |
9822 if (argvars[0].v_type == VAR_SPECIAL | |
9823 && argvars[0].vval.v_number == (isTrue ? VVAL_TRUE : VVAL_FALSE)) | |
9824 return 0; | |
9825 if (argvars[0].v_type != VAR_NUMBER | |
9826 || (tv_get_number_chk(&argvars[0], &error) == 0) == isTrue | |
9827 || error) | |
9828 { | |
9829 prepare_assert_error(&ga); | |
9830 fill_assert_error(&ga, &argvars[1], | |
9831 (char_u *)(isTrue ? "True" : "False"), | |
9832 NULL, &argvars[0], ASSERT_OTHER); | |
9833 assert_error(&ga); | |
9834 ga_clear(&ga); | |
9835 return 1; | |
9836 } | |
9837 return 0; | |
9838 } | |
9839 | |
9840 int | |
9841 assert_report(typval_T *argvars) | |
9842 { | |
9843 garray_T ga; | |
9844 | |
9845 prepare_assert_error(&ga); | |
9846 ga_concat(&ga, tv_get_string(&argvars[0])); | |
9847 assert_error(&ga); | |
9848 ga_clear(&ga); | |
9849 return 1; | |
9850 } | |
9851 | |
9852 int | |
9853 assert_exception(typval_T *argvars) | |
9854 { | |
9855 garray_T ga; | |
9856 char_u *error = tv_get_string_chk(&argvars[0]); | |
9857 | |
9858 if (vimvars[VV_EXCEPTION].vv_str == NULL) | |
9859 { | |
9860 prepare_assert_error(&ga); | |
9861 ga_concat(&ga, (char_u *)"v:exception is not set"); | |
9862 assert_error(&ga); | |
9863 ga_clear(&ga); | |
9864 return 1; | |
9865 } | |
9866 else if (error != NULL | |
9867 && strstr((char *)vimvars[VV_EXCEPTION].vv_str, (char *)error) == NULL) | |
9868 { | |
9869 prepare_assert_error(&ga); | |
9870 fill_assert_error(&ga, &argvars[1], NULL, &argvars[0], | |
9871 &vimvars[VV_EXCEPTION].vv_tv, ASSERT_OTHER); | |
9872 assert_error(&ga); | |
9873 ga_clear(&ga); | |
9874 return 1; | |
9875 } | |
9876 return 0; | |
9877 } | |
9878 | |
9879 int | |
9880 assert_beeps(typval_T *argvars) | |
9881 { | |
9882 char_u *cmd = tv_get_string_chk(&argvars[0]); | |
9883 garray_T ga; | |
9884 int ret = 0; | |
9885 | |
9886 called_vim_beep = FALSE; | |
9887 suppress_errthrow = TRUE; | |
9888 emsg_silent = FALSE; | |
9889 do_cmdline_cmd(cmd); | |
9890 if (!called_vim_beep) | |
9891 { | |
9892 prepare_assert_error(&ga); | |
9893 ga_concat(&ga, (char_u *)"command did not beep: "); | |
9894 ga_concat(&ga, cmd); | |
9895 assert_error(&ga); | |
9896 ga_clear(&ga); | |
9897 ret = 1; | |
9898 } | |
9899 | |
9900 suppress_errthrow = FALSE; | |
9901 emsg_on_display = FALSE; | |
9902 return ret; | |
9903 } | |
9904 | |
9905 static void | |
9906 assert_append_cmd_or_arg(garray_T *gap, typval_T *argvars, char_u *cmd) | |
9907 { | |
9908 char_u *tofree; | |
9909 char_u numbuf[NUMBUFLEN]; | |
9910 | |
9911 if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) | |
9912 { | |
9913 ga_concat(gap, echo_string(&argvars[2], &tofree, numbuf, 0)); | |
9914 vim_free(tofree); | |
9915 } | |
9916 else | |
9917 ga_concat(gap, cmd); | |
9918 } | |
9919 | |
9920 int | |
9921 assert_fails(typval_T *argvars) | |
9922 { | |
9923 char_u *cmd = tv_get_string_chk(&argvars[0]); | |
9924 garray_T ga; | |
9925 int ret = 0; | |
9926 int save_trylevel = trylevel; | |
9927 | |
9928 // trylevel must be zero for a ":throw" command to be considered failed | |
9929 trylevel = 0; | |
9930 called_emsg = FALSE; | |
9931 suppress_errthrow = TRUE; | |
9932 emsg_silent = TRUE; | |
9933 | |
9934 do_cmdline_cmd(cmd); | |
9935 if (!called_emsg) | |
9936 { | |
9937 prepare_assert_error(&ga); | |
9938 ga_concat(&ga, (char_u *)"command did not fail: "); | |
9939 assert_append_cmd_or_arg(&ga, argvars, cmd); | |
9940 assert_error(&ga); | |
9941 ga_clear(&ga); | |
9942 ret = 1; | |
9943 } | |
9944 else if (argvars[1].v_type != VAR_UNKNOWN) | |
9945 { | |
9946 char_u buf[NUMBUFLEN]; | |
9947 char *error = (char *)tv_get_string_buf_chk(&argvars[1], buf); | |
9948 | |
9949 if (error == NULL | |
9950 || strstr((char *)vimvars[VV_ERRMSG].vv_str, error) == NULL) | |
9951 { | |
9952 prepare_assert_error(&ga); | |
9953 fill_assert_error(&ga, &argvars[2], NULL, &argvars[1], | |
9954 &vimvars[VV_ERRMSG].vv_tv, ASSERT_OTHER); | |
9955 ga_concat(&ga, (char_u *)": "); | |
9956 assert_append_cmd_or_arg(&ga, argvars, cmd); | |
9957 assert_error(&ga); | |
9958 ga_clear(&ga); | |
9959 ret = 1; | |
9960 } | |
9961 } | |
9962 | |
9963 trylevel = save_trylevel; | |
9964 called_emsg = FALSE; | |
9965 suppress_errthrow = FALSE; | |
9966 emsg_silent = FALSE; | |
9967 emsg_on_display = FALSE; | |
9968 set_vim_var_string(VV_ERRMSG, NULL, 0); | |
9969 return ret; | |
9970 } | |
9971 | |
9972 /* | |
9973 * Append "p[clen]" to "gap", escaping unprintable characters. | |
9974 * Changes NL to \n, CR to \r, etc. | |
9975 */ | |
9976 static void | |
9977 ga_concat_esc(garray_T *gap, char_u *p, int clen) | |
9978 { | |
9979 char_u buf[NUMBUFLEN]; | |
9980 | |
9981 if (clen > 1) | |
9982 { | |
9983 mch_memmove(buf, p, clen); | |
9984 buf[clen] = NUL; | |
9985 ga_concat(gap, buf); | |
9986 } | |
9987 else switch (*p) | |
9988 { | |
9989 case BS: ga_concat(gap, (char_u *)"\\b"); break; | |
9990 case ESC: ga_concat(gap, (char_u *)"\\e"); break; | |
9991 case FF: ga_concat(gap, (char_u *)"\\f"); break; | |
9992 case NL: ga_concat(gap, (char_u *)"\\n"); break; | |
9993 case TAB: ga_concat(gap, (char_u *)"\\t"); break; | |
9994 case CAR: ga_concat(gap, (char_u *)"\\r"); break; | |
9995 case '\\': ga_concat(gap, (char_u *)"\\\\"); break; | |
9996 default: | |
9997 if (*p < ' ') | |
9998 { | |
9999 vim_snprintf((char *)buf, NUMBUFLEN, "\\x%02x", *p); | |
10000 ga_concat(gap, buf); | |
10001 } | |
10002 else | |
10003 ga_append(gap, *p); | |
10004 break; | |
10005 } | |
10006 } | |
10007 | |
10008 /* | |
10009 * Append "str" to "gap", escaping unprintable characters. | |
10010 * Changes NL to \n, CR to \r, etc. | |
10011 */ | |
10012 static void | |
10013 ga_concat_shorten_esc(garray_T *gap, char_u *str) | |
10014 { | |
10015 char_u *p; | |
10016 char_u *s; | |
10017 int c; | |
10018 int clen; | |
10019 char_u buf[NUMBUFLEN]; | |
10020 int same_len; | |
10021 | |
10022 if (str == NULL) | |
10023 { | |
10024 ga_concat(gap, (char_u *)"NULL"); | |
10025 return; | |
10026 } | |
10027 | |
10028 for (p = str; *p != NUL; ++p) | |
10029 { | |
10030 same_len = 1; | |
10031 s = p; | |
10032 c = mb_ptr2char_adv(&s); | |
10033 clen = s - p; | |
10034 while (*s != NUL && c == mb_ptr2char(s)) | |
10035 { | |
10036 ++same_len; | |
10037 s += clen; | |
10038 } | |
10039 if (same_len > 20) | |
10040 { | |
10041 ga_concat(gap, (char_u *)"\\["); | |
10042 ga_concat_esc(gap, p, clen); | |
10043 ga_concat(gap, (char_u *)" occurs "); | |
10044 vim_snprintf((char *)buf, NUMBUFLEN, "%d", same_len); | |
10045 ga_concat(gap, buf); | |
10046 ga_concat(gap, (char_u *)" times]"); | |
10047 p = s - 1; | |
10048 } | |
10049 else | |
10050 ga_concat_esc(gap, p, clen); | |
10051 } | |
10052 } | |
10053 | |
10054 /* | |
10055 * Fill "gap" with information about an assert error. | |
10056 */ | |
10057 void | |
10058 fill_assert_error( | |
10059 garray_T *gap, | |
10060 typval_T *opt_msg_tv, | |
10061 char_u *exp_str, | |
10062 typval_T *exp_tv, | |
10063 typval_T *got_tv, | |
10064 assert_type_T atype) | |
10065 { | |
10066 char_u numbuf[NUMBUFLEN]; | |
10067 char_u *tofree; | |
10068 | |
10069 if (opt_msg_tv->v_type != VAR_UNKNOWN) | |
10070 { | |
10071 ga_concat(gap, echo_string(opt_msg_tv, &tofree, numbuf, 0)); | |
10072 vim_free(tofree); | |
10073 ga_concat(gap, (char_u *)": "); | |
10074 } | |
10075 | |
10076 if (atype == ASSERT_MATCH || atype == ASSERT_NOTMATCH) | |
10077 ga_concat(gap, (char_u *)"Pattern "); | |
10078 else if (atype == ASSERT_NOTEQUAL) | |
10079 ga_concat(gap, (char_u *)"Expected not equal to "); | |
10080 else | |
10081 ga_concat(gap, (char_u *)"Expected "); | |
10082 if (exp_str == NULL) | |
10083 { | |
10084 ga_concat_shorten_esc(gap, tv2string(exp_tv, &tofree, numbuf, 0)); | |
10085 vim_free(tofree); | |
10086 } | |
10087 else | |
10088 ga_concat_shorten_esc(gap, exp_str); | |
10089 if (atype != ASSERT_NOTEQUAL) | |
10090 { | |
10091 if (atype == ASSERT_MATCH) | |
10092 ga_concat(gap, (char_u *)" does not match "); | |
10093 else if (atype == ASSERT_NOTMATCH) | |
10094 ga_concat(gap, (char_u *)" does match "); | |
10095 else | |
10096 ga_concat(gap, (char_u *)" but got "); | |
10097 ga_concat_shorten_esc(gap, tv2string(got_tv, &tofree, numbuf, 0)); | |
10098 vim_free(tofree); | |
10099 } | |
10100 } | |
10101 | |
10102 /* | 9616 /* |
10103 * Compare "typ1" and "typ2". Put the result in "typ1". | 9617 * Compare "typ1" and "typ2". Put the result in "typ1". |
10104 */ | 9618 */ |
10105 int | 9619 int |
10106 typval_compare( | 9620 typval_compare( |