mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-08-08 03:02:40 +02:00
commit bash-20161111 snapshot
This commit is contained in:
@@ -1157,6 +1157,35 @@ posix_memalign (memptr, alignment, size)
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
size_t
|
||||
malloc_usable_size (mem)
|
||||
void *mem;
|
||||
{
|
||||
register union mhead *p;
|
||||
register char *ap;
|
||||
register int maxbytes;
|
||||
|
||||
|
||||
if ((ap = (char *)mem) == 0)
|
||||
return 0;
|
||||
|
||||
/* Find the true start of the memory block to discover which bin */
|
||||
p = (union mhead *) ap - 1;
|
||||
if (p->mh_alloc == ISMEMALIGN)
|
||||
{
|
||||
ap -= p->mh_nbytes;
|
||||
p = (union mhead *) ap - 1;
|
||||
}
|
||||
|
||||
/* XXX - should we return 0 if ISFREE? */
|
||||
maxbytes = binsize(p->mh_index);
|
||||
|
||||
/* So the usable size is the maximum number of bytes in the bin less the
|
||||
malloc overhead */
|
||||
maxbytes -= MOVERHEAD + MSLOP;
|
||||
return (maxbytes);
|
||||
}
|
||||
|
||||
#if !defined (NO_VALLOC)
|
||||
/* This runs into trouble with getpagesize on HPUX, and Multimax machines.
|
||||
Patching out seems cleaner than the ugly fix needed. */
|
||||
|
||||
@@ -1304,7 +1304,7 @@ rl_redisplay ()
|
||||
right edge of the screen. If LMARGIN is 0, we need to take the
|
||||
wrap offset into account. */
|
||||
t = lmargin + M_OFFSET (lmargin, wrap_offset) + _rl_screenwidth;
|
||||
if (t < out)
|
||||
if (t > 0 && t < out)
|
||||
line[t - 1] = '>';
|
||||
|
||||
if (rl_display_fixed == 0 || forced_display || lmargin != last_lmargin)
|
||||
|
||||
@@ -28,9 +28,18 @@
|
||||
#include "shmbutil.h"
|
||||
|
||||
extern int locale_mb_cur_max;
|
||||
extern int locale_utf8locale;
|
||||
|
||||
#undef mbschr
|
||||
|
||||
static inline char *
|
||||
utf8_mbschr (s, c)
|
||||
const char *s;
|
||||
int c;
|
||||
{
|
||||
return strchr (s, c); /* for now */
|
||||
}
|
||||
|
||||
/* In some locales, the non-first byte of some multibyte characters have
|
||||
the same value as some ascii character. Faced with these strings, a
|
||||
legacy strchr() might return the wrong value. */
|
||||
@@ -49,6 +58,9 @@ mbschr (s, c)
|
||||
mbstate_t state;
|
||||
size_t strlength, mblength;
|
||||
|
||||
if (locale_utf8locale && c < 0x80)
|
||||
return (utf8_mbschr (s, c)); /* XXX */
|
||||
|
||||
/* The locale encodings with said weird property are BIG5, BIG5-HKSCS,
|
||||
GBK, GB18030, SHIFT_JIS, and JOHAB. They exhibit the problem only
|
||||
when c >= 0x30. We can therefore use the faster bytewise search if
|
||||
|
||||
+143
-1
@@ -20,9 +20,15 @@
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <shmbutil.h>
|
||||
#include <shmbchar.h>
|
||||
|
||||
#ifndef errno
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if IS_BASIC_ASCII
|
||||
|
||||
/* Bit table of characters in the ISO C "basic character set". */
|
||||
@@ -37,6 +43,106 @@ const unsigned int is_basic_table [UCHAR_MAX / 32 + 1] =
|
||||
|
||||
#endif /* IS_BASIC_ASCII */
|
||||
|
||||
extern int locale_utf8locale;
|
||||
|
||||
/* We can optimize this if we know the locale is UTF-8, but needs to handle
|
||||
malformed byte sequences. */
|
||||
static inline size_t
|
||||
utf8_mbstrlen(s)
|
||||
const char *s;
|
||||
{
|
||||
size_t num = 0;
|
||||
register unsigned char c;
|
||||
|
||||
while ((c = *s++))
|
||||
/* bytes 0xc0 through 0xff are first byte of multi-byte sequence */
|
||||
if ((c & 0xc0) != 0x80) /* skip continuation bytes */
|
||||
++num;
|
||||
return (num);
|
||||
}
|
||||
|
||||
/* Adapted from GNU libutf8 */
|
||||
static inline int
|
||||
utf8_mblen (s, n)
|
||||
const char *s;
|
||||
int n;
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
if (s == 0)
|
||||
return 0;
|
||||
else if (n == 0)
|
||||
return -1;
|
||||
|
||||
c = (unsigned char) *s;
|
||||
if (c < 0x80)
|
||||
return (c != 0);
|
||||
else if (c < 0xc0)
|
||||
goto return_error;
|
||||
else
|
||||
{
|
||||
const char *start = s;
|
||||
size_t count;
|
||||
int check_unsafe;
|
||||
|
||||
if (c < 0xe0)
|
||||
{
|
||||
count = 1;
|
||||
if (c < 0xc2)
|
||||
goto return_error;
|
||||
check_unsafe = 0;
|
||||
}
|
||||
else if (c < 0xf0)
|
||||
{
|
||||
count = 2;
|
||||
check_unsafe = (c == 0xe0);
|
||||
}
|
||||
#if SIZEOF_WCHAR_T == 4
|
||||
else if (c < 0xf8)
|
||||
{
|
||||
count = 3;
|
||||
check_unsafe = (c == 0xe0);
|
||||
}
|
||||
else if (c < 0xfc)
|
||||
{
|
||||
count = 4;
|
||||
check_unsafe = (c == 0xf8);
|
||||
}
|
||||
else if (c < 0xfe)
|
||||
{
|
||||
count = 5;
|
||||
check_unsafe = (c == 0xfc);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
goto return_error;
|
||||
if (n <= count)
|
||||
return -1;
|
||||
s++;
|
||||
c = (unsigned char) *s++ ^ 0x80;
|
||||
if (c >= 0x40)
|
||||
goto return_error;
|
||||
if (--count > 0)
|
||||
{
|
||||
if (check_unsafe && ((c >> (6 - count)) == 0))
|
||||
goto return_error;
|
||||
do
|
||||
{
|
||||
c = (unsigned char) *s++ ^ 0x80;
|
||||
if (c >= 0x40)
|
||||
goto return_error;
|
||||
}
|
||||
while (--count > 0);
|
||||
}
|
||||
return s - start;
|
||||
}
|
||||
return_error:
|
||||
errno = EILSEQ;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Count the number of characters in S, counting multi-byte characters as a
|
||||
single character. */
|
||||
size_t
|
||||
mbstrlen (s)
|
||||
const char *s;
|
||||
@@ -64,7 +170,21 @@ mbstrlen (s)
|
||||
return nc;
|
||||
}
|
||||
|
||||
static inline char *
|
||||
utf8_mbsmbchar (str)
|
||||
const char *str;
|
||||
{
|
||||
register char *s;
|
||||
|
||||
for (s = (char *)str; *s; s++)
|
||||
if ((*s & 0xc0) == 0x80)
|
||||
return s;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Return pointer to first multibyte char in S, or NULL if none. */
|
||||
/* XXX - if we know that the locale is UTF-8, we can just check whether or
|
||||
not any byte has the eighth bit turned on */
|
||||
char *
|
||||
mbsmbchar (s)
|
||||
const char *s;
|
||||
@@ -74,13 +194,19 @@ mbsmbchar (s)
|
||||
mbstate_t mbs = { 0 };
|
||||
int mb_cur_max;
|
||||
|
||||
if (locale_utf8locale)
|
||||
return (utf8_mbsmbchar (s)); /* XXX */
|
||||
|
||||
mb_cur_max = MB_CUR_MAX;
|
||||
for (t = (char *)s; *t; t++)
|
||||
{
|
||||
if (is_basic (*t))
|
||||
continue;
|
||||
|
||||
clen = mbrlen (t, mb_cur_max, &mbs);
|
||||
if (locale_utf8locale) /* not used if above code active */
|
||||
clen = utf8_mblen (t, mb_cur_max);
|
||||
else
|
||||
clen = mbrlen (t, mb_cur_max, &mbs);
|
||||
|
||||
if (clen == 0)
|
||||
return 0;
|
||||
@@ -93,6 +219,22 @@ mbsmbchar (s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
utf_mbsnlen(src, srclen, maxlen)
|
||||
const char *src;
|
||||
size_t srclen;
|
||||
int maxlen;
|
||||
{
|
||||
register int sind, count;
|
||||
|
||||
for (sind = count = 0; src[sind] && sind <= maxlen; sind++)
|
||||
{
|
||||
if ((src[sind] & 0xc0) != 0x80)
|
||||
count++;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
int
|
||||
sh_mbsnlen(src, srclen, maxlen)
|
||||
const char *src;
|
||||
|
||||
+17
-22
@@ -55,6 +55,8 @@ extern const char *locale_charset __P((void));
|
||||
extern char *get_locale_var __P((char *));
|
||||
#endif
|
||||
|
||||
extern int locale_utf8locale;
|
||||
|
||||
static int u32init = 0;
|
||||
static int utf8locale = 0;
|
||||
#if defined (HAVE_ICONV)
|
||||
@@ -265,28 +267,20 @@ u32cconv (c, s)
|
||||
return n;
|
||||
#endif
|
||||
|
||||
#if HAVE_NL_LANGINFO
|
||||
codeset = nl_langinfo (CODESET);
|
||||
if (STREQ (codeset, "UTF-8"))
|
||||
{
|
||||
n = u32toutf8 (c, s);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_ICONV
|
||||
/* this is mostly from coreutils-8.5/lib/unicodeio.c */
|
||||
if (u32init == 0)
|
||||
{
|
||||
# if HAVE_LOCALE_CHARSET
|
||||
charset = locale_charset (); /* XXX - fix later */
|
||||
# else
|
||||
charset = stub_charset ();
|
||||
# endif
|
||||
if (STREQ (charset, "UTF-8"))
|
||||
utf8locale = 1;
|
||||
else
|
||||
utf8locale = locale_utf8locale;
|
||||
if (utf8locale == 0)
|
||||
{
|
||||
#if HAVE_LOCALE_CHARSET
|
||||
charset = locale_charset ();
|
||||
#elif HAVE_NL_LANGINFO
|
||||
charset = nl_langinfo (CODESET);
|
||||
#else
|
||||
charset = stub_charset ();
|
||||
#endif
|
||||
localconv = iconv_open (charset, "UTF-8");
|
||||
if (localconv == (iconv_t)-1)
|
||||
/* We assume ASCII when presented with an unknown encoding. */
|
||||
@@ -295,6 +289,8 @@ u32cconv (c, s)
|
||||
u32init = 1;
|
||||
}
|
||||
|
||||
/* NL_LANGINFO and locale_charset used when setting locale_utf8locale */
|
||||
|
||||
/* If we have a UTF-8 locale, convert to UTF-8 and return converted value. */
|
||||
n = u32toutf8 (c, s);
|
||||
if (utf8locale)
|
||||
@@ -315,12 +311,8 @@ u32cconv (c, s)
|
||||
|
||||
if (iconv (localconv, (ICONV_CONST char **)&iptr, &sn, &optr, &obytesleft) == (size_t)-1)
|
||||
{
|
||||
#if 1
|
||||
/* You get ISO C99 escape sequences if iconv fails */
|
||||
n = u32tocesc (c, s);
|
||||
#else
|
||||
/* You get UTF-8 if iconv fails */
|
||||
#endif
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -332,7 +324,10 @@ u32cconv (c, s)
|
||||
return (optr - obuf);
|
||||
#endif /* HAVE_ICONV */
|
||||
|
||||
n = u32tocesc (c, s); /* fallback is ISO C99 escape sequences */
|
||||
if (locale_utf8locale)
|
||||
n = u32toutf8 (c, s);
|
||||
else
|
||||
n = u32tocesc (c, s); /* fallback is ISO C99 escape sequences */
|
||||
return n;
|
||||
}
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user