]> granicus.if.org Git - python/commitdiff
Patch #479898: Use multibyte C library for printing strings if available.
authorMartin v. Löwis <martin@v.loewis.de>
Mon, 7 Oct 2002 13:55:50 +0000 (13:55 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Mon, 7 Oct 2002 13:55:50 +0000 (13:55 +0000)
Objects/stringobject.c
configure
configure.in
pyconfig.h.in

index 92adb490ccccb1b7584df661349206abb959a202..c11a362d25133500f96cad84538f37ebf1fdfbfa 100644 (file)
@@ -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;
index eccd4d68959ade5e9fef237eec720b0362b28f03..a0f2ba21b6b9dbb6e5576b3c7b2d732f7208f1d6 100755 (executable)
--- 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.
 #
@@ -11657,14 +11657,16 @@ 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 \
index d752434ee6e69910f001b0f3deafdddb8e05d02f..80c4e54751f59dfd4ad62ef58bc2540a6d24aeb9 100644 (file)
@@ -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 \
index f5cc30ead475c89c6fb419a08b00a48d4680ee0b..c41ddda1dbe9bf24e04fccf7da95abc72ddb9077 100644 (file)
 /* 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
 
 /* 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
 
 /* 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