Mercurial > vim
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 */ |