# HG changeset patch # User Richard M. Stallman # Date 886486774 0 # Node ID cbaa9e50b0139638d109a609abcbd5a0edfa4683 # Parent 1b98a0ab1bee243938227b3792062d89dc1a0d2d (Fformat): If MULTIBYTE is changed to 1 after we start computing TOTAL, jump back to `retry' (a new label). diff -r 1b98a0ab1bee -r cbaa9e50b013 src/editfns.c --- a/src/editfns.c Tue Feb 03 06:17:15 1998 +0000 +++ b/src/editfns.c Tue Feb 03 06:19:34 1998 +0000 @@ -2190,7 +2190,7 @@ register Lisp_Object *args; { register int n; /* The number of the next arg to substitute */ - register int total = 5; /* An estimate of the final length */ + register int total; /* An estimate of the final length */ char *buf, *p; register unsigned char *format, *end; int length, nchars; @@ -2198,7 +2198,7 @@ which is true if any of the inputs is one. */ int multibyte = 0; unsigned char *this_format; - int longest_format = 0; + int longest_format; Lisp_Object val; extern char *index (); @@ -2206,16 +2206,26 @@ /* It should not be necessary to GCPRO ARGS, because the caller in the interpreter should take care of that. */ + /* Try to determine whether the result should be multibyte. + This is not always right; sometimes the result needs to be multibyte + because of an object that we will pass through prin1, + and in that case, we won't know it here. */ for (n = 0; n < nargs; n++) if (STRINGP (args[n]) && STRING_MULTIBYTE (args[n])) multibyte = 1; CHECK_STRING (args[0], 0); + + /* If we start out planning a unibyte result, + and later find it has to be multibyte, we jump back to retry. */ + retry: + format = XSTRING (args[0])->data; end = format + XSTRING (args[0])->size_byte; + longest_format = 0; /* Make room in result for all the non-%-codes in the control string. */ - total += CONVERTED_BYTE_SIZE (multibyte, args[0]); + total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]); /* Add to TOTAL enough space to hold the converted arguments. */ @@ -2247,8 +2257,11 @@ /* For `S', prin1 the argument and then treat like a string. */ register Lisp_Object tem; tem = Fprin1_to_string (args[n], Qnil); - if (STRING_MULTIBYTE (tem)) - multibyte = 1; + if (STRING_MULTIBYTE (tem) && ! multibyte) + { + multibyte = 1; + goto retry; + } args[n] = tem; goto string; } @@ -2291,7 +2304,10 @@ register Lisp_Object tem; tem = Fprin1_to_string (args[n], Qt); if (STRING_MULTIBYTE (tem)) - multibyte = 1; + { + multibyte = 1; + goto retry; + } args[n] = tem; goto string; } @@ -2302,6 +2318,9 @@ total += thissize + 4; } + /* Now we can no longer jump to retry. + TOTAL and LONGEST_FORMAT are known for certain. */ + this_format = (unsigned char *) alloca (longest_format + 1); /* Allocate the space for the result.