Commit fed2405c authored by Martin v. Löwis's avatar Martin v. Löwis

Patch #479898: Use multibyte C library for printing strings if available.

parent e9ce0b0f
...@@ -26,6 +26,19 @@ static PyStringObject *nullstring; ...@@ -26,6 +26,19 @@ static PyStringObject *nullstring;
static PyObject *interned; static PyObject *interned;
#if defined(HAVE_MBTOWC) && defined(HAVE_WCHAR_H)
# define PRINT_MULTIBYTE_STRING
# include <locale.h>
# include <wchar.h>
# if defined(HAVE_ISWPRINT)
# define _isprint iswprint
# else
# define _isprint isprint
# endif
#endif
static const char *hexchars = "0123456789abcdef";
/* /*
For both PyString_FromString() and PyString_FromStringAndSize(), the For both PyString_FromString() and PyString_FromStringAndSize(), the
parameter `size' denotes number of characters to allocate, not counting any parameter `size' denotes number of characters to allocate, not counting any
...@@ -749,8 +762,14 @@ PyString_AsStringAndSize(register PyObject *obj, ...@@ -749,8 +762,14 @@ PyString_AsStringAndSize(register PyObject *obj,
static int static int
string_print(PyStringObject *op, FILE *fp, int flags) string_print(PyStringObject *op, FILE *fp, int flags)
{ {
#ifndef PRINT_MULTIBYTE_STRING
int i; int i;
char c; char c;
#else
char *scur, *send;
wchar_t c;
int cr;
#endif
int quote; int quote;
/* XXX Ought to check for interrupts when writing long strings */ /* XXX Ought to check for interrupts when writing long strings */
...@@ -776,20 +795,36 @@ string_print(PyStringObject *op, FILE *fp, int flags) ...@@ -776,20 +795,36 @@ string_print(PyStringObject *op, FILE *fp, int flags)
quote = '"'; quote = '"';
fputc(quote, fp); fputc(quote, fp);
#ifndef PRINT_MULTIBYTE_STRING
for (i = 0; i < op->ob_size; i++) { for (i = 0; i < op->ob_size; i++) {
c = op->ob_sval[i]; c = op->ob_sval[i];
#else
for (scur = op->ob_sval, send = op->ob_sval + op->ob_size;
scur < send; scur += cr) {
if ((cr = mbtowc(&c, scur, send - scur)) <= 0)
goto non_printable;
#endif
if (c == quote || c == '\\') if (c == quote || c == '\\')
fprintf(fp, "\\%c", c); fputc('\\', fp), fputc(c, fp);
else if (c == '\t') else if (c == '\t')
fprintf(fp, "\\t"); fputs("\\t", fp);
else if (c == '\n') else if (c == '\n')
fprintf(fp, "\\n"); fputs("\\n", fp);
else if (c == '\r') else if (c == '\r')
fprintf(fp, "\\r"); fputs("\\r", fp);
else if (c < ' ' || c >= 0x7f) #ifndef PRINT_MULTIBYTE_STRING
fprintf(fp, "\\x%02x", c & 0xff); else if (' ' <= c && c < 0x7f)
else
fputc(c, fp); fputc(c, fp);
else
fprintf(fp, "\\x%02x", c & 0xff);
#else
else if (_isprint(c))
fwrite(scur, cr, 1, fp);
else {
non_printable: cr = 1; /* unit to move cursor */
fprintf(fp, "\\x%02x", *scur & 0xff);
}
#endif
} }
fputc(quote, fp); fputc(quote, fp);
return 0; return 0;
...@@ -810,8 +845,14 @@ PyString_Repr(PyObject *obj, int smartquotes) ...@@ -810,8 +845,14 @@ PyString_Repr(PyObject *obj, int smartquotes)
return NULL; return NULL;
} }
else { else {
#ifndef PRINT_MULTIBYTE_STRING
register int i; register int i;
register char c; register char c;
#else
register char *scur, *send;
wchar_t c;
int cr;
#endif
register char *p; register char *p;
int quote; int quote;
...@@ -824,11 +865,18 @@ PyString_Repr(PyObject *obj, int smartquotes) ...@@ -824,11 +865,18 @@ PyString_Repr(PyObject *obj, int smartquotes)
p = PyString_AS_STRING(v); p = PyString_AS_STRING(v);
*p++ = quote; *p++ = quote;
#ifndef PRINT_MULTIBYTE_STRING
for (i = 0; i < op->ob_size; i++) { for (i = 0; i < op->ob_size; i++) {
/* There's at least enough room for a hex escape /* There's at least enough room for a hex escape
and a closing quote. */ and a closing quote. */
assert(newsize - (p - PyString_AS_STRING(v)) >= 5); assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
c = op->ob_sval[i]; c = op->ob_sval[i];
#else
for (scur = op->ob_sval, send = op->ob_sval + op->ob_size;
scur < send; scur += cr) {
if ((cr = mbtowc(&c, scur, send - scur)) <= 0)
goto non_printable;
#endif
if (c == quote || c == '\\') if (c == quote || c == '\\')
*p++ = '\\', *p++ = c; *p++ = '\\', *p++ = c;
else if (c == '\t') else if (c == '\t')
...@@ -837,15 +885,20 @@ PyString_Repr(PyObject *obj, int smartquotes) ...@@ -837,15 +885,20 @@ PyString_Repr(PyObject *obj, int smartquotes)
*p++ = '\\', *p++ = 'n'; *p++ = '\\', *p++ = 'n';
else if (c == '\r') else if (c == '\r')
*p++ = '\\', *p++ = 'r'; *p++ = '\\', *p++ = 'r';
else if (c < ' ' || c >= 0x7f) { #ifndef PRINT_MULTIBYTE_STRING
/* For performance, we don't want to call else if (' ' <= c && c < 0x7f)
PyOS_snprintf here (extra layers of
function call). */
sprintf(p, "\\x%02x", c & 0xff);
p += 4;
}
else
*p++ = c; *p++ = c;
else {
#else
else if (_isprint(c))
memcpy(p, scur, cr), p += cr;
else {
non_printable: cr = 1; c = *scur;
#endif
*p++ = '\\'; *p++ = 'x';
*p++ = hexchars[(c >> 4) & 0x0f];
*p++ = hexchars[c & 0x0f];
}
} }
assert(newsize - (p - PyString_AS_STRING(v)) >= 1); assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
*p++ = quote; *p++ = quote;
......
#! /bin/sh #! /bin/sh
# From configure.in Revision: 1.352 . # From configure.in Revision: 1.353 .
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.53. # Generated by GNU Autoconf 2.53.
# #
...@@ -11657,14 +11657,16 @@ echo "${ECHO_T}MACHDEP_OBJS" >&6 ...@@ -11657,14 +11657,16 @@ echo "${ECHO_T}MACHDEP_OBJS" >&6
for ac_func in alarm chown chroot clock confstr ctermid ctermid_r execv \ for ac_func in alarm chown chroot clock confstr ctermid ctermid_r execv \
fchdir flock fork fsync fdatasync fpathconf ftime ftruncate \ fchdir flock fork fsync fdatasync fpathconf ftime ftruncate \
gai_strerror getgroups getlogin getpeername getpgid getpid getpwent getwd \ gai_strerror getgroups getlogin getpeername getpgid getpid getpwent getwd \
hstrerror inet_pton kill killpg lchown link lstat mkfifo mknod mktime \ hstrerror inet_pton iswprint kill killpg lchown link lstat mbtowc mkfifo \
mremap nice pathconf pause plock poll pthread_init \ mknod mktime mremap nice pathconf pause plock poll pthread_init \
putenv readlink \ putenv readlink \
select setegid seteuid setgid setgroups \ select setegid seteuid setgid setgroups \
setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \ setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \
......
...@@ -1679,8 +1679,8 @@ AC_MSG_RESULT(MACHDEP_OBJS) ...@@ -1679,8 +1679,8 @@ AC_MSG_RESULT(MACHDEP_OBJS)
AC_CHECK_FUNCS(alarm chown chroot clock confstr ctermid ctermid_r execv \ AC_CHECK_FUNCS(alarm chown chroot clock confstr ctermid ctermid_r execv \
fchdir flock fork fsync fdatasync fpathconf ftime ftruncate \ fchdir flock fork fsync fdatasync fpathconf ftime ftruncate \
gai_strerror getgroups getlogin getpeername getpgid getpid getpwent getwd \ gai_strerror getgroups getlogin getpeername getpgid getpid getpwent getwd \
hstrerror inet_pton kill killpg lchown link lstat mkfifo mknod mktime \ hstrerror inet_pton iswprint kill killpg lchown link lstat mbtowc mkfifo \
mremap nice pathconf pause plock poll pthread_init \ mknod mktime mremap nice pathconf pause plock poll pthread_init \
putenv readlink \ putenv readlink \
select setegid seteuid setgid setgroups \ select setegid seteuid setgid setgroups \
setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \ setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \
......
...@@ -196,6 +196,9 @@ ...@@ -196,6 +196,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */ /* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H #undef HAVE_INTTYPES_H
/* Define to 1 if you have the `iswprint' function. */
#undef HAVE_ISWPRINT
/* Define to 1 if you have the `kill' function. */ /* Define to 1 if you have the `kill' function. */
#undef HAVE_KILL #undef HAVE_KILL
...@@ -226,9 +229,6 @@ ...@@ -226,9 +229,6 @@
/* Define to 1 if you have the <libintl.h> header file. */ /* Define to 1 if you have the <libintl.h> header file. */
#undef HAVE_LIBINTL_H #undef HAVE_LIBINTL_H
/* Define to 1 if you have the `rt' library (-lrt). */
#undef HAVE_LIBRT
/* Define to 1 if you have the <libutil.h> header file. */ /* Define to 1 if you have the <libutil.h> header file. */
#undef HAVE_LIBUTIL_H #undef HAVE_LIBUTIL_H
...@@ -250,6 +250,9 @@ ...@@ -250,6 +250,9 @@
/* Define this if you have the makedev macro. */ /* Define this if you have the makedev macro. */
#undef HAVE_MAKEDEV #undef HAVE_MAKEDEV
/* Define to 1 if you have the `mbtowc' function. */
#undef HAVE_MBTOWC
/* Define to 1 if you have the `memmove' function. */ /* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE #undef HAVE_MEMMOVE
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment