# HG changeset patch # User Karl Heuer # Date 856421294 0 # Node ID 42d758739319bfd98f151aa41ffa1b2ff753c8e6 # Parent e7d92eb43979e4f116b8001f3fbbcd5f1618b117 Include charset.h. (doprn1): Handle multibyte characters. diff -r e7d92eb43979 -r 42d758739319 src/doprnt.c --- a/src/doprnt.c Thu Feb 20 06:47:55 1997 +0000 +++ b/src/doprnt.c Thu Feb 20 06:48:14 1997 +0000 @@ -34,6 +34,11 @@ #define DBL_MAX_10_EXP 308 /* IEEE double */ #endif +/* Since we use the macro CHAR_HEAD_P, we have to include this, but + don't have to include others because CHAR_HEAD_P does not contains + another macro. */ +#include "charset.h" + extern long *xmalloc (), *xrealloc (); static int doprnt1 (); @@ -105,7 +110,7 @@ char *fmtcpy; int minlen; int size; /* Field width factor; e.g., %90d */ - char charbuf[2]; /* Used for %c. */ + char charbuf[5]; /* Used for %c. */ if (format_end == 0) format_end = format + strlen (format); @@ -123,6 +128,7 @@ if (*fmt == '%') /* Check for a '%' character */ { int size_bound = 0; + int width; /* Columns occupied by STRING. */ fmt++; /* Copy this one %-spec into fmtcpy. */ @@ -234,15 +240,21 @@ string = args[cnt++]; tem = strlen (string); } + width = strwidth (string, tem); goto doit1; /* Copy string into final output, truncating if no room. */ doit: - tem = strlen (string); + /* Coming here means STRING contains ASCII only. */ + width = tem = strlen (string); doit1: + /* We have already calculated: + TEM -- length of STRING, + WIDTH -- columns occupied by STRING when displayed, and + MINLEN -- minimum columns of the output. */ if (minlen > 0) { - while (minlen > tem && bufsize > 0) + while (minlen > width && bufsize > 0) { *bufptr++ = ' '; bufsize--; @@ -251,13 +263,21 @@ minlen = 0; } if (tem > bufsize) - tem = bufsize; - bcopy (string, bufptr, tem); + { + /* Truncate the string at character boundary. */ + tem = bufsize; + while (!CHAR_HEAD_P (string + tem - 1)) tem--; + bcopy (string, bufptr, tem); + /* We must calculate WIDTH again. */ + width = strwidth (bufptr, tem); + } + else + bcopy (string, bufptr, tem); bufptr += tem; bufsize -= tem; if (minlen < 0) { - while (minlen < - tem && bufsize > 0) + while (minlen < - width && bufsize > 0) { *bufptr++ = ' '; bufsize--; @@ -270,9 +290,10 @@ case 'c': if (cnt == nargs) error ("not enough arguments for format string"); - *charbuf = (EMACS_INT) args[cnt++]; - string = charbuf; - tem = 1; + tem = CHAR_STRING ((EMACS_INT) args[cnt], charbuf, string); + cnt++; + string[tem] = 0; + width = strwidth (string, tem); if (fmtcpy[1] != 'c') minlen = atoi (&fmtcpy[1]); goto doit1; @@ -281,8 +302,20 @@ fmt--; /* Drop thru and this % will be treated as normal */ } } - *bufptr++ = *fmt++; /* Just some characters; Copy 'em */ - bufsize--; + + { + /* Just some character; Copy it if the whole multi-byte form + fit in the buffer. */ + char *save_bufptr = bufptr; + + do { *bufptr++ = *fmt++; } + while (--bufsize > 0 && !CHAR_HEAD_P (fmt)); + if (!CHAR_HEAD_P (fmt)) + { + bufptr = save_bufptr; + break; + } + } }; /* If we had to malloc something, free it. */