aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarl Heuer1997-02-20 06:48:14 +0000
committerKarl Heuer1997-02-20 06:48:14 +0000
commita0ca925c4b6ac97381007e30455f83678bb0a49c (patch)
tree2582c276b72558a5ae4cd1e4316b75cd7e00fca5
parent214acc50393d7223193e133f8aa23f1cb47ff9d5 (diff)
downloademacs-a0ca925c4b6ac97381007e30455f83678bb0a49c.tar.gz
emacs-a0ca925c4b6ac97381007e30455f83678bb0a49c.zip
Include charset.h.
(doprn1): Handle multibyte characters.
-rw-r--r--src/doprnt.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/src/doprnt.c b/src/doprnt.c
index aa0b2c20055..7c703f87d5e 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -34,6 +34,11 @@ Boston, MA 02111-1307, USA. */
34#define DBL_MAX_10_EXP 308 /* IEEE double */ 34#define DBL_MAX_10_EXP 308 /* IEEE double */
35#endif 35#endif
36 36
37/* Since we use the macro CHAR_HEAD_P, we have to include this, but
38 don't have to include others because CHAR_HEAD_P does not contains
39 another macro. */
40#include "charset.h"
41
37extern long *xmalloc (), *xrealloc (); 42extern long *xmalloc (), *xrealloc ();
38 43
39static int doprnt1 (); 44static int doprnt1 ();
@@ -105,7 +110,7 @@ doprnt1 (lispstrings, buffer, bufsize, format, format_end, nargs, args)
105 char *fmtcpy; 110 char *fmtcpy;
106 int minlen; 111 int minlen;
107 int size; /* Field width factor; e.g., %90d */ 112 int size; /* Field width factor; e.g., %90d */
108 char charbuf[2]; /* Used for %c. */ 113 char charbuf[5]; /* Used for %c. */
109 114
110 if (format_end == 0) 115 if (format_end == 0)
111 format_end = format + strlen (format); 116 format_end = format + strlen (format);
@@ -123,6 +128,7 @@ doprnt1 (lispstrings, buffer, bufsize, format, format_end, nargs, args)
123 if (*fmt == '%') /* Check for a '%' character */ 128 if (*fmt == '%') /* Check for a '%' character */
124 { 129 {
125 int size_bound = 0; 130 int size_bound = 0;
131 int width; /* Columns occupied by STRING. */
126 132
127 fmt++; 133 fmt++;
128 /* Copy this one %-spec into fmtcpy. */ 134 /* Copy this one %-spec into fmtcpy. */
@@ -234,15 +240,21 @@ doprnt1 (lispstrings, buffer, bufsize, format, format_end, nargs, args)
234 string = args[cnt++]; 240 string = args[cnt++];
235 tem = strlen (string); 241 tem = strlen (string);
236 } 242 }
243 width = strwidth (string, tem);
237 goto doit1; 244 goto doit1;
238 245
239 /* Copy string into final output, truncating if no room. */ 246 /* Copy string into final output, truncating if no room. */
240 doit: 247 doit:
241 tem = strlen (string); 248 /* Coming here means STRING contains ASCII only. */
249 width = tem = strlen (string);
242 doit1: 250 doit1:
251 /* We have already calculated:
252 TEM -- length of STRING,
253 WIDTH -- columns occupied by STRING when displayed, and
254 MINLEN -- minimum columns of the output. */
243 if (minlen > 0) 255 if (minlen > 0)
244 { 256 {
245 while (minlen > tem && bufsize > 0) 257 while (minlen > width && bufsize > 0)
246 { 258 {
247 *bufptr++ = ' '; 259 *bufptr++ = ' ';
248 bufsize--; 260 bufsize--;
@@ -251,13 +263,21 @@ doprnt1 (lispstrings, buffer, bufsize, format, format_end, nargs, args)
251 minlen = 0; 263 minlen = 0;
252 } 264 }
253 if (tem > bufsize) 265 if (tem > bufsize)
254 tem = bufsize; 266 {
255 bcopy (string, bufptr, tem); 267 /* Truncate the string at character boundary. */
268 tem = bufsize;
269 while (!CHAR_HEAD_P (string + tem - 1)) tem--;
270 bcopy (string, bufptr, tem);
271 /* We must calculate WIDTH again. */
272 width = strwidth (bufptr, tem);
273 }
274 else
275 bcopy (string, bufptr, tem);
256 bufptr += tem; 276 bufptr += tem;
257 bufsize -= tem; 277 bufsize -= tem;
258 if (minlen < 0) 278 if (minlen < 0)
259 { 279 {
260 while (minlen < - tem && bufsize > 0) 280 while (minlen < - width && bufsize > 0)
261 { 281 {
262 *bufptr++ = ' '; 282 *bufptr++ = ' ';
263 bufsize--; 283 bufsize--;
@@ -270,9 +290,10 @@ doprnt1 (lispstrings, buffer, bufsize, format, format_end, nargs, args)
270 case 'c': 290 case 'c':
271 if (cnt == nargs) 291 if (cnt == nargs)
272 error ("not enough arguments for format string"); 292 error ("not enough arguments for format string");
273 *charbuf = (EMACS_INT) args[cnt++]; 293 tem = CHAR_STRING ((EMACS_INT) args[cnt], charbuf, string);
274 string = charbuf; 294 cnt++;
275 tem = 1; 295 string[tem] = 0;
296 width = strwidth (string, tem);
276 if (fmtcpy[1] != 'c') 297 if (fmtcpy[1] != 'c')
277 minlen = atoi (&fmtcpy[1]); 298 minlen = atoi (&fmtcpy[1]);
278 goto doit1; 299 goto doit1;
@@ -281,8 +302,20 @@ doprnt1 (lispstrings, buffer, bufsize, format, format_end, nargs, args)
281 fmt--; /* Drop thru and this % will be treated as normal */ 302 fmt--; /* Drop thru and this % will be treated as normal */
282 } 303 }
283 } 304 }
284 *bufptr++ = *fmt++; /* Just some characters; Copy 'em */ 305
285 bufsize--; 306 {
307 /* Just some character; Copy it if the whole multi-byte form
308 fit in the buffer. */
309 char *save_bufptr = bufptr;
310
311 do { *bufptr++ = *fmt++; }
312 while (--bufsize > 0 && !CHAR_HEAD_P (fmt));
313 if (!CHAR_HEAD_P (fmt))
314 {
315 bufptr = save_bufptr;
316 break;
317 }
318 }
286 }; 319 };
287 320
288 /* If we had to malloc something, free it. */ 321 /* If we had to malloc something, free it. */