From fed2405cb59a23153c42d25f918ceb9e8afe25fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Mon, 7 Oct 2002 13:55:50 +0000 Subject: Patch #479898: Use multibyte C library for printing strings if available. --- Objects/stringobject.c | 83 +++++++++++++++++++++++++++++++++++++++++--------- configure | 8 +++-- configure.in | 4 +-- pyconfig.h.in | 9 ++++-- 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 +# include +# 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 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 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 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 -- cgit v0.12