summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin v. Löwis <martin@v.loewis.de>2002-10-07 13:55:50 (GMT)
committerMartin v. Löwis <martin@v.loewis.de>2002-10-07 13:55:50 (GMT)
commitfed2405cb59a23153c42d25f918ceb9e8afe25fc (patch)
treee0ead70b4fabdab8b34bb732d35075b7cd738784
parente9ce0b0fea16453cb8d75ecac02669998cc7ff36 (diff)
downloadcpython-fed2405cb59a23153c42d25f918ceb9e8afe25fc.zip
cpython-fed2405cb59a23153c42d25f918ceb9e8afe25fc.tar.gz
cpython-fed2405cb59a23153c42d25f918ceb9e8afe25fc.tar.bz2
Patch #479898: Use multibyte C library for printing strings if available.
-rw-r--r--Objects/stringobject.c83
-rwxr-xr-xconfigure8
-rw-r--r--configure.in4
-rw-r--r--pyconfig.h.in9
4 files changed, 81 insertions, 23 deletions
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 92adb49..c11a362 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -26,6 +26,19 @@ static PyStringObject *nullstring;
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
parameter `size' denotes number of characters to allocate, not counting any
@@ -749,8 +762,14 @@ PyString_AsStringAndSize(register PyObject *obj,
static int
string_print(PyStringObject *op, FILE *fp, int flags)
{
+#ifndef PRINT_MULTIBYTE_STRING
int i;
char c;
+#else
+ char *scur, *send;
+ wchar_t c;
+ int cr;
+#endif
int quote;
/* XXX Ought to check for interrupts when writing long strings */
@@ -776,20 +795,36 @@ string_print(PyStringObject *op, FILE *fp, int flags)
quote = '"';
fputc(quote, fp);
+#ifndef PRINT_MULTIBYTE_STRING
for (i = 0; i < op->ob_size; 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 == '\\')
- fprintf(fp, "\\%c", c);
+ fputc('\\', fp), fputc(c, fp);
else if (c == '\t')
- fprintf(fp, "\\t");
+ fputs("\\t", fp);
else if (c == '\n')
- fprintf(fp, "\\n");
+ fputs("\\n", fp);
else if (c == '\r')
- fprintf(fp, "\\r");
- else if (c < ' ' || c >= 0x7f)
- fprintf(fp, "\\x%02x", c & 0xff);
- else
+ fputs("\\r", fp);
+#ifndef PRINT_MULTIBYTE_STRING
+ else if (' ' <= c && c < 0x7f)
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);
return 0;
@@ -810,8 +845,14 @@ PyString_Repr(PyObject *obj, int smartquotes)
return NULL;
}
else {
+#ifndef PRINT_MULTIBYTE_STRING
register int i;
register char c;
+#else
+ register char *scur, *send;
+ wchar_t c;
+ int cr;
+#endif
register char *p;
int quote;
@@ -824,11 +865,18 @@ PyString_Repr(PyObject *obj, int smartquotes)
p = PyString_AS_STRING(v);
*p++ = quote;
+#ifndef PRINT_MULTIBYTE_STRING
for (i = 0; i < op->ob_size; i++) {
/* There's at least enough room for a hex escape
and a closing quote. */
assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
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 == '\\')
*p++ = '\\', *p++ = c;
else if (c == '\t')
@@ -837,15 +885,20 @@ PyString_Repr(PyObject *obj, int smartquotes)
*p++ = '\\', *p++ = 'n';
else if (c == '\r')
*p++ = '\\', *p++ = 'r';
- else if (c < ' ' || c >= 0x7f) {
- /* For performance, we don't want to call
- PyOS_snprintf here (extra layers of
- function call). */
- sprintf(p, "\\x%02x", c & 0xff);
- p += 4;
- }
- else
+#ifndef PRINT_MULTIBYTE_STRING
+ else if (' ' <= c && c < 0x7f)
*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);
*p++ = quote;
diff --git a/configure b/configure
index eccd4d6..a0f2ba2 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.in Revision: 1.352 .
+# From configure.in Revision: 1.353 .
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.53.
#
@@ -11660,11 +11660,13 @@ echo "${ECHO_T}MACHDEP_OBJS" >&6
+
+
for ac_func in alarm chown chroot clock confstr ctermid ctermid_r execv \
fchdir flock fork fsync fdatasync fpathconf ftime ftruncate \
gai_strerror getgroups getlogin getpeername getpgid getpid getpwent getwd \
- hstrerror inet_pton kill killpg lchown link lstat mkfifo mknod mktime \
- mremap nice pathconf pause plock poll pthread_init \
+ hstrerror inet_pton iswprint kill killpg lchown link lstat mbtowc mkfifo \
+ mknod mktime mremap nice pathconf pause plock poll pthread_init \
putenv readlink \
select setegid seteuid setgid setgroups \
setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \
diff --git a/configure.in b/configure.in
index d752434..80c4e54 100644
--- a/configure.in
+++ b/configure.in
@@ -1679,8 +1679,8 @@ AC_MSG_RESULT(MACHDEP_OBJS)
AC_CHECK_FUNCS(alarm chown chroot clock confstr ctermid ctermid_r execv \
fchdir flock fork fsync fdatasync fpathconf ftime ftruncate \
gai_strerror getgroups getlogin getpeername getpgid getpid getpwent getwd \
- hstrerror inet_pton kill killpg lchown link lstat mkfifo mknod mktime \
- mremap nice pathconf pause plock poll pthread_init \
+ hstrerror inet_pton iswprint kill killpg lchown link lstat mbtowc mkfifo \
+ mknod mktime mremap nice pathconf pause plock poll pthread_init \
putenv readlink \
select setegid seteuid setgid setgroups \
setlocale setregid setreuid setsid setpgid setuid setvbuf snprintf \
diff --git a/pyconfig.h.in b/pyconfig.h.in
index f5cc30e..c41ddda 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -196,6 +196,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#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. */
#undef HAVE_KILL
@@ -226,9 +229,6 @@
/* Define to 1 if you have the <libintl.h> header file. */
#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. */
#undef HAVE_LIBUTIL_H
@@ -250,6 +250,9 @@
/* Define this if you have the makedev macro. */
#undef HAVE_MAKEDEV
+/* Define to 1 if you have the `mbtowc' function. */
+#undef HAVE_MBTOWC
+
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE