Patch 7.4.1730
Problem:    It is not easy to get a character out of a string.
Solution:   Add strgetchar() and strcharpart().
Files:      src/eval.c, src/testdir/test_expr.vim


*** ../vim-7.4.1729/src/eval.c  2016-04-14 12:46:33.616678646 +0200
--- src/eval.c  2016-04-14 15:00:41.064037067 +0200
***************
*** 779,787 ****
--- 779,789 ----
  #ifdef HAVE_STRFTIME
  static void f_strftime(typval_T *argvars, typval_T *rettv);
  #endif
+ static void f_strgetchar(typval_T *argvars, typval_T *rettv);
  static void f_stridx(typval_T *argvars, typval_T *rettv);
  static void f_string(typval_T *argvars, typval_T *rettv);
  static void f_strlen(typval_T *argvars, typval_T *rettv);
+ static void f_strcharpart(typval_T *argvars, typval_T *rettv);
  static void f_strpart(typval_T *argvars, typval_T *rettv);
  static void f_strridx(typval_T *argvars, typval_T *rettv);
  static void f_strtrans(typval_T *argvars, typval_T *rettv);
***************
*** 8635,8645 ****
--- 8637,8649 ----
      {"str2float",     1, 1, f_str2float},
  #endif
      {"str2nr",                1, 2, f_str2nr},
+     {"strcharpart",   2, 3, f_strcharpart},
      {"strchars",      1, 2, f_strchars},
      {"strdisplaywidth",       1, 2, f_strdisplaywidth},
  #ifdef HAVE_STRFTIME
      {"strftime",      1, 2, f_strftime},
  #endif
+     {"strgetchar",    2, 2, f_strgetchar},
      {"stridx",                2, 3, f_stridx},
      {"string",                1, 1, f_string},
      {"strlen",                1, 1, f_strlen},
***************
*** 19551,19556 ****
--- 19555,19600 ----
  #endif
  
  /*
+  * "strgetchar()" function
+  */
+     static void
+ f_strgetchar(typval_T *argvars, typval_T *rettv)
+ {
+     char_u    *str;
+     int               len;
+     int               error = FALSE;
+     int               charidx;
+ 
+     rettv->vval.v_number = -1;
+     str = get_tv_string_chk(&argvars[0]);
+     if (str == NULL)
+       return;
+     len = (int)STRLEN(str);
+     charidx = get_tv_number_chk(&argvars[1], &error);
+     if (error)
+       return;
+ #ifdef FEAT_MBYTE
+     {
+       int             byteidx = 0;
+ 
+       while (charidx >= 0 && byteidx < len)
+       {
+           if (charidx == 0)
+           {
+               rettv->vval.v_number = mb_ptr2char(str + byteidx);
+               break;
+           }
+           --charidx;
+           byteidx += mb_char2len(str[byteidx]);
+       }
+     }
+ #else
+     if (charidx < len)
+       rettv->vval.v_number = str[charidx];
+ #endif
+ }
+ 
+ /*
   * "stridx()" function
   */
      static void
***************
*** 19678,19683 ****
--- 19722,19792 ----
  }
  
  /*
+  * "strcharpart()" function
+  */
+     static void
+ f_strcharpart(typval_T *argvars, typval_T *rettv)
+ {
+ #ifdef FEAT_MBYTE
+     char_u    *p;
+     int               nchar;
+     int               nbyte = 0;
+     int               charlen;
+     int               len = 0;
+     int               slen;
+     int               error = FALSE;
+ 
+     p = get_tv_string(&argvars[0]);
+     slen = (int)STRLEN(p);
+ 
+     nchar = get_tv_number_chk(&argvars[1], &error);
+     if (!error)
+     {
+       if (nchar > 0)
+           while (nchar > 0 && nbyte < slen)
+           {
+               nbyte += mb_char2len(p[nbyte]);
+               --nchar;
+           }
+       else
+           nbyte = nchar;
+       if (argvars[2].v_type != VAR_UNKNOWN)
+       {
+           charlen = get_tv_number(&argvars[2]);
+           while (charlen > 0 && nbyte + len < slen)
+           {
+               len += mb_char2len(p[nbyte + len]);
+               --charlen;
+           }
+       }
+       else
+           len = slen - nbyte;    /* default: all bytes that are available. */
+     }
+ 
+     /*
+      * Only return the overlap between the specified part and the actual
+      * string.
+      */
+     if (nbyte < 0)
+     {
+       len += nbyte;
+       nbyte = 0;
+     }
+     else if (nbyte > slen)
+       nbyte = slen;
+     if (len < 0)
+       len = 0;
+     else if (nbyte + len > slen)
+       len = slen - nbyte;
+ 
+     rettv->v_type = VAR_STRING;
+     rettv->vval.v_string = vim_strnsave(p + nbyte, len);
+ #else
+     f_strpart(argvars, rettv);
+ #endif
+ }
+ 
+ /*
   * "strpart()" function
   */
      static void
*** ../vim-7.4.1729/src/testdir/test_expr.vim   2016-04-03 22:44:32.403625720 
+0200
--- src/testdir/test_expr.vim   2016-04-14 15:06:58.352114798 +0200
***************
*** 50,52 ****
--- 50,99 ----
    call assert_equal('none', d[''])
    call assert_equal('aaa', d['a'])
  endfunc
+ 
+ func Test_strgetchar()
+   call assert_equal(char2nr('a'), strgetchar('axb', 0))
+   call assert_equal(char2nr('x'), strgetchar('axb', 1))
+   call assert_equal(char2nr('b'), strgetchar('axb', 2))
+ 
+   call assert_equal(-1, strgetchar('axb', -1))
+   call assert_equal(-1, strgetchar('axb', 3))
+   call assert_equal(-1, strgetchar('', 0))
+ 
+   if !has('multi_byte')
+     return
+   endif
+ 
+   call assert_equal(char2nr('á'), strgetchar('áxb', 0))
+   call assert_equal(char2nr('x'), strgetchar('áxb', 1))
+ 
+   call assert_equal(char2nr('a'), strgetchar('àxb', 0))
+   call assert_equal(char2nr('̀'), strgetchar('àxb', 1))
+   call assert_equal(char2nr('x'), strgetchar('àxb', 2))
+ endfunc
+ 
+ func Test_strcharpart()
+   call assert_equal('a', strcharpart('axb', 0, 1))
+   call assert_equal('x', strcharpart('axb', 1, 1))
+   call assert_equal('b', strcharpart('axb', 2, 1))
+   call assert_equal('xb', strcharpart('axb', 1))
+ 
+   call assert_equal('', strcharpart('axb', 1, 0))
+   call assert_equal('', strcharpart('axb', 1, -1))
+   call assert_equal('', strcharpart('axb', -1, 1))
+   call assert_equal('', strcharpart('axb', -2, 2))
+ 
+   call assert_equal('a', strcharpart('axb', -1, 2))
+ 
+   if !has('multi_byte')
+     return
+   endif
+ 
+   call assert_equal('áxb', strcharpart('áxb', 0))
+   call assert_equal('á', strcharpart('áxb', 0, 1))
+   call assert_equal('x', strcharpart('áxb', 1, 1))
+ 
+   call assert_equal('a', strcharpart('àxb', 0, 1))
+   call assert_equal('̀', strcharpart('àxb', 1, 1))
+   call assert_equal('x', strcharpart('àxb', 2, 1))
+ endfunc
*** ../vim-7.4.1729/src/version.c       2016-04-14 14:09:21.712015920 +0200
--- src/version.c       2016-04-14 14:56:19.538712323 +0200
***************
*** 750,751 ****
--- 750,753 ----
  {   /* Add new patch number below this line */
+ /**/
+     1730,
  /**/

-- 
ARTHUR: Right! Knights! Forward!
   ARTHUR leads a charge toward the castle.  Various shots of them battling on,
   despite being hit by a variety of farm animals.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui