comparison src/eval.c @ 8887:8bf855dea79e v7.4.1730

commit https://github.com/vim/vim/commit/58de0e2dcc1f2d251b74892a06d71a14973f3187 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Apr 14 15:13:46 2016 +0200 patch 7.4.1730 Problem: It is not easy to get a character out of a string. Solution: Add strgetchar() and strcharpart().
author Christian Brabandt <cb@256bit.org>
date Thu, 14 Apr 2016 15:15:05 +0200
parents ed0b39dd7fd6
children 8755d57debaa
comparison
equal deleted inserted replaced
8886:9954d0cd1e87 8887:8bf855dea79e
777 static void f_str2nr(typval_T *argvars, typval_T *rettv); 777 static void f_str2nr(typval_T *argvars, typval_T *rettv);
778 static void f_strchars(typval_T *argvars, typval_T *rettv); 778 static void f_strchars(typval_T *argvars, typval_T *rettv);
779 #ifdef HAVE_STRFTIME 779 #ifdef HAVE_STRFTIME
780 static void f_strftime(typval_T *argvars, typval_T *rettv); 780 static void f_strftime(typval_T *argvars, typval_T *rettv);
781 #endif 781 #endif
782 static void f_strgetchar(typval_T *argvars, typval_T *rettv);
782 static void f_stridx(typval_T *argvars, typval_T *rettv); 783 static void f_stridx(typval_T *argvars, typval_T *rettv);
783 static void f_string(typval_T *argvars, typval_T *rettv); 784 static void f_string(typval_T *argvars, typval_T *rettv);
784 static void f_strlen(typval_T *argvars, typval_T *rettv); 785 static void f_strlen(typval_T *argvars, typval_T *rettv);
786 static void f_strcharpart(typval_T *argvars, typval_T *rettv);
785 static void f_strpart(typval_T *argvars, typval_T *rettv); 787 static void f_strpart(typval_T *argvars, typval_T *rettv);
786 static void f_strridx(typval_T *argvars, typval_T *rettv); 788 static void f_strridx(typval_T *argvars, typval_T *rettv);
787 static void f_strtrans(typval_T *argvars, typval_T *rettv); 789 static void f_strtrans(typval_T *argvars, typval_T *rettv);
788 static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv); 790 static void f_strdisplaywidth(typval_T *argvars, typval_T *rettv);
789 static void f_strwidth(typval_T *argvars, typval_T *rettv); 791 static void f_strwidth(typval_T *argvars, typval_T *rettv);
8633 #ifdef FEAT_FLOAT 8635 #ifdef FEAT_FLOAT
8634 {"sqrt", 1, 1, f_sqrt}, 8636 {"sqrt", 1, 1, f_sqrt},
8635 {"str2float", 1, 1, f_str2float}, 8637 {"str2float", 1, 1, f_str2float},
8636 #endif 8638 #endif
8637 {"str2nr", 1, 2, f_str2nr}, 8639 {"str2nr", 1, 2, f_str2nr},
8640 {"strcharpart", 2, 3, f_strcharpart},
8638 {"strchars", 1, 2, f_strchars}, 8641 {"strchars", 1, 2, f_strchars},
8639 {"strdisplaywidth", 1, 2, f_strdisplaywidth}, 8642 {"strdisplaywidth", 1, 2, f_strdisplaywidth},
8640 #ifdef HAVE_STRFTIME 8643 #ifdef HAVE_STRFTIME
8641 {"strftime", 1, 2, f_strftime}, 8644 {"strftime", 1, 2, f_strftime},
8642 #endif 8645 #endif
8646 {"strgetchar", 2, 2, f_strgetchar},
8643 {"stridx", 2, 3, f_stridx}, 8647 {"stridx", 2, 3, f_stridx},
8644 {"string", 1, 1, f_string}, 8648 {"string", 1, 1, f_string},
8645 {"strlen", 1, 1, f_strlen}, 8649 {"strlen", 1, 1, f_strlen},
8646 {"strpart", 2, 3, f_strpart}, 8650 {"strpart", 2, 3, f_strpart},
8647 {"strridx", 2, 3, f_strridx}, 8651 {"strridx", 2, 3, f_strridx},
19549 } 19553 }
19550 } 19554 }
19551 #endif 19555 #endif
19552 19556
19553 /* 19557 /*
19558 * "strgetchar()" function
19559 */
19560 static void
19561 f_strgetchar(typval_T *argvars, typval_T *rettv)
19562 {
19563 char_u *str;
19564 int len;
19565 int error = FALSE;
19566 int charidx;
19567
19568 rettv->vval.v_number = -1;
19569 str = get_tv_string_chk(&argvars[0]);
19570 if (str == NULL)
19571 return;
19572 len = (int)STRLEN(str);
19573 charidx = get_tv_number_chk(&argvars[1], &error);
19574 if (error)
19575 return;
19576 #ifdef FEAT_MBYTE
19577 {
19578 int byteidx = 0;
19579
19580 while (charidx >= 0 && byteidx < len)
19581 {
19582 if (charidx == 0)
19583 {
19584 rettv->vval.v_number = mb_ptr2char(str + byteidx);
19585 break;
19586 }
19587 --charidx;
19588 byteidx += mb_char2len(str[byteidx]);
19589 }
19590 }
19591 #else
19592 if (charidx < len)
19593 rettv->vval.v_number = str[charidx];
19594 #endif
19595 }
19596
19597 /*
19554 * "stridx()" function 19598 * "stridx()" function
19555 */ 19599 */
19556 static void 19600 static void
19557 f_stridx(typval_T *argvars, typval_T *rettv) 19601 f_stridx(typval_T *argvars, typval_T *rettv)
19558 { 19602 {
19673 mb_string2cells(s, -1) 19717 mb_string2cells(s, -1)
19674 #else 19718 #else
19675 STRLEN(s) 19719 STRLEN(s)
19676 #endif 19720 #endif
19677 ); 19721 );
19722 }
19723
19724 /*
19725 * "strcharpart()" function
19726 */
19727 static void
19728 f_strcharpart(typval_T *argvars, typval_T *rettv)
19729 {
19730 #ifdef FEAT_MBYTE
19731 char_u *p;
19732 int nchar;
19733 int nbyte = 0;
19734 int charlen;
19735 int len = 0;
19736 int slen;
19737 int error = FALSE;
19738
19739 p = get_tv_string(&argvars[0]);
19740 slen = (int)STRLEN(p);
19741
19742 nchar = get_tv_number_chk(&argvars[1], &error);
19743 if (!error)
19744 {
19745 if (nchar > 0)
19746 while (nchar > 0 && nbyte < slen)
19747 {
19748 nbyte += mb_char2len(p[nbyte]);
19749 --nchar;
19750 }
19751 else
19752 nbyte = nchar;
19753 if (argvars[2].v_type != VAR_UNKNOWN)
19754 {
19755 charlen = get_tv_number(&argvars[2]);
19756 while (charlen > 0 && nbyte + len < slen)
19757 {
19758 len += mb_char2len(p[nbyte + len]);
19759 --charlen;
19760 }
19761 }
19762 else
19763 len = slen - nbyte; /* default: all bytes that are available. */
19764 }
19765
19766 /*
19767 * Only return the overlap between the specified part and the actual
19768 * string.
19769 */
19770 if (nbyte < 0)
19771 {
19772 len += nbyte;
19773 nbyte = 0;
19774 }
19775 else if (nbyte > slen)
19776 nbyte = slen;
19777 if (len < 0)
19778 len = 0;
19779 else if (nbyte + len > slen)
19780 len = slen - nbyte;
19781
19782 rettv->v_type = VAR_STRING;
19783 rettv->vval.v_string = vim_strnsave(p + nbyte, len);
19784 #else
19785 f_strpart(argvars, rettv);
19786 #endif
19678 } 19787 }
19679 19788
19680 /* 19789 /*
19681 * "strpart()" function 19790 * "strpart()" function
19682 */ 19791 */