Diff for /embedaddon/readline/mbutil.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2014/07/30 08:16:45 version 1.1.1.2, 2021/03/17 01:01:01
Line 1 Line 1
 /* mbutil.c -- readline multibyte character utility functions */  /* mbutil.c -- readline multibyte character utility functions */
   
/* Copyright (C) 2001-2009 Free Software Foundation, Inc./* Copyright (C) 2001-2020 Free Software Foundation, Inc.
   
    This file is part of the GNU Readline Library (Readline), a library     This file is part of the GNU Readline Library (Readline), a library
    for reading lines of text with interactive input and history editing.           for reading lines of text with interactive input and history editing.      
Line 75  int _rl_utf8locale = 0; Line 75  int _rl_utf8locale = 0;
   
 #if defined(HANDLE_MULTIBYTE)  #if defined(HANDLE_MULTIBYTE)
   
   /* **************************************************************** */
   /*                                                                  */
   /*              UTF-8 specific Character Utility Functions          */
   /*                                                                  */
   /* **************************************************************** */
   
   /* Return the length in bytes of the possibly-multibyte character beginning
      at S. Encoding is UTF-8. */
 static int  static int
_rl_find_next_mbchar_internal (string, seed, count, find_non_zero)_rl_utf8_mblen (const char *s, size_t n)
     char *string; 
     int seed, count, find_non_zero; 
 {  {
     unsigned char c, c1, c2, c3;
   
     if (s == 0)
       return (0); /* no shift states */
     if (n <= 0)
       return (-1);
   
     c = (unsigned char)*s;
     if (c < 0x80)
       return (c != 0);
     if (c >= 0xc2)
       {
         c1 = (unsigned char)s[1];
         if (c < 0xe0)
           {
             if (n == 1)
               return -2;
             if (n >= 2 && (c1 ^ 0x80) < 0x40)
               return 2;
           }
         else if (c < 0xf0)
           {
             if (n == 1)
               return -2;
             if ((c1 ^ 0x80) < 0x40
                   && (c >= 0xe1 || c1 >= 0xa0)
                   && (c != 0xed || c1 < 0xa0))
               {
                 if (n == 2)
                   return -2;
                 c2 = (unsigned char)s[2];
                 if ((c2 ^ 0x80) < 0x40)
                   return 3;
               }
           }
         else if (c < 0xf4)
           {
             if (n == 1)
               return -2;
             if (((c1 ^ 0x80) < 0x40)
                   && (c >= 0xf1 || c1 >= 0x90)
                   && (c < 0xf4 || (c == 0xf4 && c1 < 0x90)))
               {
                 if (n == 2)
                   return -2;
                 c2 = (unsigned char)s[2];
                 if ((c2 ^ 0x80) < 0x40)
                   {
                     if (n == 3)
                       return -2;
                     c3 = (unsigned char)s[3];
                     if ((c3 ^ 0x80) < 0x40)
                       return 4;
                   }
               }
           }
       }
     /* invalid or incomplete multibyte character */
     return -1;
   }
   
   static int
   _rl_find_next_mbchar_internal (char *string, int seed, int count, int find_non_zero)
   {
   size_t tmp, len;    size_t tmp, len;
   mbstate_t ps;    mbstate_t ps;
   int point;    int point;
Line 94  _rl_find_next_mbchar_internal (string, seed, count, fi Line 164  _rl_find_next_mbchar_internal (string, seed, count, fi
     return seed;      return seed;
   
   point = seed + _rl_adjust_point (string, seed, &ps);    point = seed + _rl_adjust_point (string, seed, &ps);
     /* if _rl_adjust_point returns -1, the character or string is invalid.
        treat as a byte. */
     if (point == seed - 1)        /* invalid */
       return seed + 1;
       
   /* if this is true, means that seed was not pointing to a byte indicating    /* if this is true, means that seed was not pointing to a byte indicating
      the beginning of a multibyte character.  Correct the point and consume       the beginning of a multibyte character.  Correct the point and consume
      one char. */       one char. */
Line 105  _rl_find_next_mbchar_internal (string, seed, count, fi Line 180  _rl_find_next_mbchar_internal (string, seed, count, fi
       len = strlen (string + point);        len = strlen (string + point);
       if (len == 0)        if (len == 0)
         break;          break;
      tmp = mbrtowc (&wc, string+point, len, &ps);      if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point]))
         {
           tmp = 1;
           wc = (wchar_t) string[point];
           memset(&ps, 0, sizeof(mbstate_t));
         }
       else
         tmp = mbrtowc (&wc, string+point, len, &ps);
       if (MB_INVALIDCH ((size_t)tmp))        if (MB_INVALIDCH ((size_t)tmp))
         {          {
           /* invalid bytes. assume a byte represents a character */            /* invalid bytes. assume a byte represents a character */
Line 145  _rl_find_next_mbchar_internal (string, seed, count, fi Line 227  _rl_find_next_mbchar_internal (string, seed, count, fi
   return point;    return point;
 }  }
   
   static inline int
   _rl_test_nonzero (char *string, int ind, int len)
   {
     size_t tmp;
     wchar_t wc;
     mbstate_t ps;
   
     memset (&ps, 0, sizeof (mbstate_t));
     tmp = mbrtowc (&wc, string + ind, len - ind, &ps);
     /* treat invalid multibyte sequences as non-zero-width */
     return (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp) || WCWIDTH (wc) > 0);
   }
   
   /* experimental -- needs to handle zero-width characters better */
 static int  static int
_rl_find_prev_mbchar_internal (string, seed, find_non_zero)_rl_find_prev_utf8char (char *string, int seed, int find_non_zero)
     char *string; 
     int seed, find_non_zero; 
 {  {
     char *s;
     unsigned char b;
     int save, prev;
     size_t len;
   
     if (find_non_zero)
       len = RL_STRLEN (string);
   
     prev = seed - 1;
     while (prev >= 0)
      {
         b = (unsigned char)string[prev];
         if (UTF8_SINGLEBYTE (b))
           return (prev);
   
         save = prev;
   
         /* Move back until we're not in the middle of a multibyte char */
         if (UTF8_MBCHAR (b))
           {
             while (prev > 0 && (b = (unsigned char)string[--prev]) && UTF8_MBCHAR (b))
               ;
           }
   
         if (UTF8_MBFIRSTCHAR (b))
           {
             if (find_non_zero)
               {
                 if (_rl_test_nonzero (string, prev, len))
                   return (prev);
                 else              /* valid but WCWIDTH (wc) == 0 */
                   prev = prev - 1;
               }
             else
               return (prev);
           }
         else
           return (save);                  /* invalid utf-8 multibyte sequence */
       }
   
     return ((prev < 0) ? 0 : prev);
   }  
   
   /*static*/ int
   _rl_find_prev_mbchar_internal (char *string, int seed, int find_non_zero)
   {
   mbstate_t ps;    mbstate_t ps;
   int prev, non_zero_prev, point, length;    int prev, non_zero_prev, point, length;
   size_t tmp;    size_t tmp;
   wchar_t wc;    wchar_t wc;
   
     if (_rl_utf8locale)
       return (_rl_find_prev_utf8char (string, seed, find_non_zero));
   
   memset(&ps, 0, sizeof(mbstate_t));    memset(&ps, 0, sizeof(mbstate_t));
   length = strlen(string);    length = strlen(string);
       
Line 166  _rl_find_prev_mbchar_internal (string, seed, find_non_ Line 309  _rl_find_prev_mbchar_internal (string, seed, find_non_
   prev = non_zero_prev = point = 0;    prev = non_zero_prev = point = 0;
   while (point < seed)    while (point < seed)
     {      {
      tmp = mbrtowc (&wc, string + point, length - point, &ps);      if (_rl_utf8locale && UTF8_SINGLEBYTE(string[point]))
         {
           tmp = 1;
           wc = (wchar_t) string[point];
           memset(&ps, 0, sizeof(mbstate_t));
         }
       else
         tmp = mbrtowc (&wc, string + point, length - point, &ps);
       if (MB_INVALIDCH ((size_t)tmp))        if (MB_INVALIDCH ((size_t)tmp))
         {          {
          /* in this case, bytes are invalid or shorted to compose          /* in this case, bytes are invalid or too short to compose
              multibyte char, so assume that the first byte represents               multibyte char, so assume that the first byte represents
              a single character anyway. */               a single character anyway. */
           tmp = 1;            tmp = 1;
Line 206  _rl_find_prev_mbchar_internal (string, seed, find_non_ Line 356  _rl_find_prev_mbchar_internal (string, seed, find_non_
    if an invalid multibyte sequence was encountered. It returns (size_t)(-2)      if an invalid multibyte sequence was encountered. It returns (size_t)(-2) 
    if it couldn't parse a complete  multibyte character.  */     if it couldn't parse a complete  multibyte character.  */
 int  int
_rl_get_char_len (src, ps)_rl_get_char_len (char *src, mbstate_t *ps)
     char *src; 
     mbstate_t *ps; 
 {  {
  size_t tmp;  size_t tmp, l;
   int mb_cur_max;
   
  tmp = mbrlen((const char *)src, (size_t)strlen (src), ps);  /* Look at no more than MB_CUR_MAX characters */
   l = (size_t)strlen (src);
   if (_rl_utf8locale && l > 0 && UTF8_SINGLEBYTE(*src))
     tmp = (*src != 0) ? 1 : 0;
   else
     {
       mb_cur_max = MB_CUR_MAX;
       tmp = mbrlen((const char *)src, (l < mb_cur_max) ? l : mb_cur_max, ps);
     }
   if (tmp == (size_t)(-2))    if (tmp == (size_t)(-2))
     {      {
      /* shorted to compose multibyte char */      /* too short to compose multibyte char */
       if (ps)        if (ps)
         memset (ps, 0, sizeof(mbstate_t));          memset (ps, 0, sizeof(mbstate_t));
       return -2;        return -2;
Line 237  _rl_get_char_len (src, ps) Line 394  _rl_get_char_len (src, ps)
 /* compare the specified two characters. If the characters matched,  /* compare the specified two characters. If the characters matched,
    return 1. Otherwise return 0. */     return 1. Otherwise return 0. */
 int  int
_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)_rl_compare_chars (char *buf1, int pos1, mbstate_t *ps1, char *buf2, int pos2, mbstate_t *ps2)
     char *buf1; 
     int pos1; 
     mbstate_t *ps1; 
     char *buf2; 
     int pos2; 
     mbstate_t *ps2; 
 {  {
   int i, w1, w2;    int i, w1, w2;
   
Line 263  _rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2) Line 414  _rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
 /* adjust pointed byte and find mbstate of the point of string.  /* adjust pointed byte and find mbstate of the point of string.
    adjusted point will be point <= adjusted_point, and returns     adjusted point will be point <= adjusted_point, and returns
    differences of the byte(adjusted_point - point).     differences of the byte(adjusted_point - point).
   if point is invalied (point < 0 || more than string length),   if point is invalid (point < 0 || more than string length),
    it returns -1 */     it returns -1 */
 int  int
_rl_adjust_point (string, point, ps)_rl_adjust_point (char *string, int point, mbstate_t *ps)
     char *string; 
     int point; 
     mbstate_t *ps; 
 {  {
  size_t tmp = 0;  size_t tmp;
  int length;  int length, pos;
  int pos = 0; 
   
     tmp = 0;
     pos = 0;
   length = strlen(string);    length = strlen(string);
   if (point < 0)    if (point < 0)
     return -1;      return -1;
Line 283  _rl_adjust_point (string, point, ps) Line 432  _rl_adjust_point (string, point, ps)
       
   while (pos < point)    while (pos < point)
     {      {
      tmp = mbrlen (string + pos, length - pos, ps);      if (_rl_utf8locale && UTF8_SINGLEBYTE(string[pos]))
         tmp = 1;
       else
         tmp = mbrlen (string + pos, length - pos, ps);
       if (MB_INVALIDCH ((size_t)tmp))        if (MB_INVALIDCH ((size_t)tmp))
         {          {
          /* in this case, bytes are invalid or shorted to compose          /* in this case, bytes are invalid or too short to compose
              multibyte char, so assume that the first byte represents               multibyte char, so assume that the first byte represents
              a single character anyway. */               a single character anyway. */
           pos++;            pos++;
Line 305  _rl_adjust_point (string, point, ps) Line 457  _rl_adjust_point (string, point, ps)
 }  }
   
 int  int
_rl_is_mbchar_matched (string, seed, end, mbchar, length)_rl_is_mbchar_matched (char *string, int seed, int end, char *mbchar, int length)
     char *string; 
     int seed, end; 
     char *mbchar; 
     int length; 
 {  {
   int i;    int i;
   
Line 323  _rl_is_mbchar_matched (string, seed, end, mbchar, leng Line 471  _rl_is_mbchar_matched (string, seed, end, mbchar, leng
 }  }
   
 wchar_t  wchar_t
_rl_char_value (buf, ind)_rl_char_value (char *buf, int ind)
     char *buf; 
     int ind; 
 {  {
   size_t tmp;    size_t tmp;
   wchar_t wc;    wchar_t wc;
Line 334  _rl_char_value (buf, ind) Line 480  _rl_char_value (buf, ind)
   
   if (MB_LEN_MAX == 1 || rl_byte_oriented)    if (MB_LEN_MAX == 1 || rl_byte_oriented)
     return ((wchar_t) buf[ind]);      return ((wchar_t) buf[ind]);
     if (_rl_utf8locale && UTF8_SINGLEBYTE(buf[ind]))
       return ((wchar_t) buf[ind]);
   l = strlen (buf);    l = strlen (buf);
   if (ind >= l - 1)    if (ind >= l - 1)
     return ((wchar_t) buf[ind]);      return ((wchar_t) buf[ind]);
     if (l < ind)                  /* Sanity check */
       l = strlen (buf+ind);
   memset (&ps, 0, sizeof (mbstate_t));    memset (&ps, 0, sizeof (mbstate_t));
   tmp = mbrtowc (&wc, buf + ind, l - ind, &ps);    tmp = mbrtowc (&wc, buf + ind, l - ind, &ps);
   if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))      if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))  
Line 350  _rl_char_value (buf, ind) Line 500  _rl_char_value (buf, ind)
    characters. */     characters. */
 #undef _rl_find_next_mbchar  #undef _rl_find_next_mbchar
 int  int
_rl_find_next_mbchar (string, seed, count, flags)_rl_find_next_mbchar (char *string, int seed, int count, int flags)
     char *string; 
     int seed, count, flags; 
 {  {
 #if defined (HANDLE_MULTIBYTE)  #if defined (HANDLE_MULTIBYTE)
   return _rl_find_next_mbchar_internal (string, seed, count, flags);    return _rl_find_next_mbchar_internal (string, seed, count, flags);
Line 366  _rl_find_next_mbchar (string, seed, count, flags) Line 514  _rl_find_next_mbchar (string, seed, count, flags)
    we look for non-zero-width multibyte characters. */     we look for non-zero-width multibyte characters. */
 #undef _rl_find_prev_mbchar  #undef _rl_find_prev_mbchar
 int  int
_rl_find_prev_mbchar (string, seed, flags)_rl_find_prev_mbchar (char *string, int seed, int flags)
     char *string; 
     int seed, flags; 
 {  {
 #if defined (HANDLE_MULTIBYTE)  #if defined (HANDLE_MULTIBYTE)
   return _rl_find_prev_mbchar_internal (string, seed, flags);    return _rl_find_prev_mbchar_internal (string, seed, flags);

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>