From 99027bdd81f63ea690394a153ef49a08f55e498d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 25 Jun 2012 19:33:51 -0700 Subject: [PATCH] Use sprintf return value instead of invoking strlen on result. In the old days this wasn't portable, since some sprintf implementations returned char *. But they died out years ago and Emacs already assumes sprintf returns int. Similarly for float_to_string. This patch speeds up (number-to-string 1000) by 3% on Fedora 15 x86-64. * ccl.c (ccl_driver): * character.c (string_escape_byte8): * data.c (Fnumber_to_string): * doprnt.c (doprnt): * print.c (print_object): * xdisp.c (message_dolog): * xfns.c (syms_of_xfns): Use sprintf or float_to_string result to avoid need to call strlen. * data.c (Fnumber_to_string): Use make_unibyte_string, since the string must be ASCII. * lisp.h, print.c (float_to_string): Now returns int length. * term.c (produce_glyphless_glyph): Use sprintf result rather than recomputing it. --- src/ChangeLog | 20 +++++++ src/ccl.c | 15 +++--- src/character.c | 8 +-- src/data.c | 15 +++--- src/doprnt.c | 24 ++++----- src/lisp.h | 2 +- src/print.c | 137 ++++++++++++++++++++++++++++-------------------- src/term.c | 3 +- src/xdisp.c | 4 +- src/xfns.c | 8 +-- 10 files changed, 131 insertions(+), 105 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index dec5ee328a7..5b3387b8134 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,25 @@ 2012-06-26 Paul Eggert + Use sprintf return value instead of invoking strlen on result. + In the old days this wasn't portable, since some sprintf + implementations returned char *. But they died out years ago and + Emacs already assumes sprintf returns int. + Similarly for float_to_string. + This patch speeds up (number-to-string 1000) by 3% on Fedora 15 x86-64. + * ccl.c (ccl_driver): + * character.c (string_escape_byte8): + * data.c (Fnumber_to_string): + * doprnt.c (doprnt): + * print.c (print_object): + * xdisp.c (message_dolog): + * xfns.c (syms_of_xfns): + Use sprintf or float_to_string result to avoid need to call strlen. + * data.c (Fnumber_to_string): + Use make_unibyte_string, since the string must be ASCII. + * lisp.h, print.c (float_to_string): Now returns int length. + * term.c (produce_glyphless_glyph): + Use sprintf result rather than recomputing it. + Clean out last vestiges of the old HAVE_CONFIG_H stuff. * Makefile.in (ALL_CFLAGS): * makefile.w32-in (LOCAL_FLAGS): Remove -DHAVE_CONFIG_H. diff --git a/src/ccl.c b/src/ccl.c index 163d01fe283..63ceaeadad5 100644 --- a/src/ccl.c +++ b/src/ccl.c @@ -1729,14 +1729,14 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size switch (ccl->status) { case CCL_STAT_INVALID_CMD: - sprintf (msg, "\nCCL: Invalid command %x (ccl_code = %x) at %d.", - code & 0x1F, code, this_ic); + msglen = sprintf (msg, + "\nCCL: Invalid command %x (ccl_code = %x) at %d.", + code & 0x1F, code, this_ic); #ifdef CCL_DEBUG { int i = ccl_backtrace_idx - 1; int j; - msglen = strlen (msg); if (dst + msglen <= (dst_bytes ? dst_end : src)) { memcpy (dst, msg, msglen); @@ -1748,8 +1748,7 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size if (i < 0) i = CCL_DEBUG_BACKTRACE_LEN - 1; if (ccl_backtrace_table[i] == 0) break; - sprintf (msg, " %d", ccl_backtrace_table[i]); - msglen = strlen (msg); + msglen = sprintf (msg, " %d", ccl_backtrace_table[i]); if (dst + msglen > (dst_bytes ? dst_end : src)) break; memcpy (dst, msg, msglen); @@ -1761,15 +1760,13 @@ ccl_driver (struct ccl_program *ccl, int *source, int *destination, int src_size break; case CCL_STAT_QUIT: - if (! ccl->quit_silently) - sprintf (msg, "\nCCL: Quitted."); + msglen = ccl->quit_silently ? 0 : sprintf (msg, "\nCCL: Quitted."); break; default: - sprintf (msg, "\nCCL: Unknown error type (%d)", ccl->status); + msglen = sprintf (msg, "\nCCL: Unknown error type (%d)", ccl->status); } - msglen = strlen (msg); if (msglen <= dst_end - dst) { for (i = 0; i < msglen; i++) diff --git a/src/character.c b/src/character.c index fbd23409d08..da182488033 100644 --- a/src/character.c +++ b/src/character.c @@ -867,8 +867,7 @@ string_escape_byte8 (Lisp_Object string) { c = STRING_CHAR_ADVANCE (src); c = CHAR_TO_BYTE8 (c); - sprintf ((char *) dst, "\\%03o", c); - dst += 4; + dst += sprintf ((char *) dst, "\\%03o", c); } else while (len--) *dst++ = *src++; @@ -878,10 +877,7 @@ string_escape_byte8 (Lisp_Object string) { c = *src++; if (c >= 0x80) - { - sprintf ((char *) dst, "\\%03o", c); - dst += 4; - } + dst += sprintf ((char *) dst, "\\%03o", c); else *dst++ = c; } diff --git a/src/data.c b/src/data.c index cd4b14a9f9d..bd757cfdad1 100644 --- a/src/data.c +++ b/src/data.c @@ -2449,20 +2449,17 @@ Uses a minus sign if negative. NUMBER may be an integer or a floating point number. */) (Lisp_Object number) { - char buffer[VALBITS]; + char buffer[max (FLOAT_TO_STRING_BUFSIZE, INT_BUFSIZE_BOUND (EMACS_INT))]; + int len; CHECK_NUMBER_OR_FLOAT (number); if (FLOATP (number)) - { - char pigbuf[FLOAT_TO_STRING_BUFSIZE]; - - float_to_string (pigbuf, XFLOAT_DATA (number)); - return build_string (pigbuf); - } + len = float_to_string (buffer, XFLOAT_DATA (number)); + else + len = sprintf (buffer, "%"pI"d", XINT (number)); - sprintf (buffer, "%"pI"d", XINT (number)); - return build_string (buffer); + return make_unibyte_string (buffer, len); } DEFUN ("string-to-number", Fstring_to_number, Sstring_to_number, 1, 2, 0, diff --git a/src/doprnt.c b/src/doprnt.c index b106ffb1938..07bbcff7081 100644 --- a/src/doprnt.c +++ b/src/doprnt.c @@ -275,32 +275,32 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format, case no_modifier: { int v = va_arg (ap, int); - sprintf (sprintf_buffer, fmtcpy, v); + tem = sprintf (sprintf_buffer, fmtcpy, v); } break; case long_modifier: { long v = va_arg (ap, long); - sprintf (sprintf_buffer, fmtcpy, v); + tem = sprintf (sprintf_buffer, fmtcpy, v); } break; case pD_modifier: signed_pD_modifier: { ptrdiff_t v = va_arg (ap, ptrdiff_t); - sprintf (sprintf_buffer, fmtcpy, v); + tem = sprintf (sprintf_buffer, fmtcpy, v); } break; case pI_modifier: { EMACS_INT v = va_arg (ap, EMACS_INT); - sprintf (sprintf_buffer, fmtcpy, v); + tem = sprintf (sprintf_buffer, fmtcpy, v); } break; case pM_modifier: { intmax_t v = va_arg (ap, intmax_t); - sprintf (sprintf_buffer, fmtcpy, v); + tem = sprintf (sprintf_buffer, fmtcpy, v); } break; } @@ -315,13 +315,13 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format, case no_modifier: { unsigned v = va_arg (ap, unsigned); - sprintf (sprintf_buffer, fmtcpy, v); + tem = sprintf (sprintf_buffer, fmtcpy, v); } break; case long_modifier: { unsigned long v = va_arg (ap, unsigned long); - sprintf (sprintf_buffer, fmtcpy, v); + tem = sprintf (sprintf_buffer, fmtcpy, v); } break; case pD_modifier: @@ -329,13 +329,13 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format, case pI_modifier: { EMACS_UINT v = va_arg (ap, EMACS_UINT); - sprintf (sprintf_buffer, fmtcpy, v); + tem = sprintf (sprintf_buffer, fmtcpy, v); } break; case pM_modifier: { uintmax_t v = va_arg (ap, uintmax_t); - sprintf (sprintf_buffer, fmtcpy, v); + tem = sprintf (sprintf_buffer, fmtcpy, v); } break; } @@ -348,7 +348,7 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format, case 'g': { double d = va_arg (ap, double); - sprintf (sprintf_buffer, fmtcpy, d); + tem = sprintf (sprintf_buffer, fmtcpy, d); /* Now copy into final output, truncating as necessary. */ string = sprintf_buffer; goto doit; @@ -369,7 +369,6 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format, /* Copy string into final output, truncating if no room. */ doit: /* Coming here means STRING contains ASCII only. */ - tem = strlen (string); if (STRING_BYTES_BOUND < tem) error ("Format width or precision too large"); width = tem; @@ -413,8 +412,7 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format, bufsize = 0; continue; } - else - memcpy (bufptr, string, tem); + memcpy (bufptr, string, tem); bufptr += tem; bufsize -= tem; if (minlen < 0) diff --git a/src/lisp.h b/src/lisp.h index f7ec612ac5e..d6cc886bae3 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -2797,7 +2797,7 @@ extern void print_error_message (Lisp_Object, Lisp_Object, const char *, extern Lisp_Object internal_with_output_to_temp_buffer (const char *, Lisp_Object (*) (Lisp_Object), Lisp_Object); #define FLOAT_TO_STRING_BUFSIZE 350 -extern void float_to_string (char *, double); +extern int float_to_string (char *, double); extern void syms_of_print (void); /* Defined in doprnt.c */ diff --git a/src/print.c b/src/print.c index a632f45bbeb..68b9c30c564 100644 --- a/src/print.c +++ b/src/print.c @@ -912,7 +912,7 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context, for (; CONSP (tail); tail = XCDR (tail), sep = ", ") { Lisp_Object obj; - + if (sep) write_string_1 (sep, 2, stream); obj = XCAR (tail); @@ -944,43 +944,49 @@ print_error_message (Lisp_Object data, Lisp_Object stream, const char *context, * Given the above, the buffer must be least FLOAT_TO_STRING_BUFSIZE bytes. */ -void +int float_to_string (char *buf, double data) { char *cp; int width; + int len; /* Check for plus infinity in a way that won't lose if there is no plus infinity. */ if (data == data / 2 && data > 1.0) { - strcpy (buf, "1.0e+INF"); - return; + static char const infinity_string[] = "1.0e+INF"; + strcpy (buf, infinity_string); + return sizeof infinity_string - 1; } /* Likewise for minus infinity. */ if (data == data / 2 && data < -1.0) { - strcpy (buf, "-1.0e+INF"); - return; + static char const minus_infinity_string[] = "-1.0e+INF"; + strcpy (buf, minus_infinity_string); + return sizeof minus_infinity_string - 1; } /* Check for NaN in a way that won't fail if there are no NaNs. */ if (! (data * 0.0 >= 0.0)) { /* Prepend "-" if the NaN's sign bit is negative. The sign bit of a double is the bit that is 1 in -0.0. */ + static char const NaN_string[] = "0.0e+NaN"; int i; union { double d; char c[sizeof (double)]; } u_data, u_minus_zero; + int negative = 0; u_data.d = data; u_minus_zero.d = - 0.0; for (i = 0; i < sizeof (double); i++) if (u_data.c[i] & u_minus_zero.c[i]) { - *buf++ = '-'; + *buf = '-'; + negative = 1; break; } - strcpy (buf, "0.0e+NaN"); - return; + strcpy (buf + negative, NaN_string); + return negative + sizeof NaN_string - 1; } if (NILP (Vfloat_output_format) @@ -989,7 +995,7 @@ float_to_string (char *buf, double data) { /* Generate the fewest number of digits that represent the floating point value without losing information. */ - dtoastr (buf, FLOAT_TO_STRING_BUFSIZE - 2, 0, 0, data); + len = dtoastr (buf, FLOAT_TO_STRING_BUFSIZE - 2, 0, 0, data); /* The decimal point must be printed, or the byte compiler can get confused (Bug#8033). */ width = 1; @@ -1032,7 +1038,7 @@ float_to_string (char *buf, double data) if (cp[1] != 0) goto lose; - sprintf (buf, SSDATA (Vfloat_output_format), data); + len = sprintf (buf, SSDATA (Vfloat_output_format), data); } /* Make sure there is a decimal point with digit after, or an @@ -1049,14 +1055,18 @@ float_to_string (char *buf, double data) { cp[1] = '0'; cp[2] = 0; + len++; } else if (*cp == 0) { *cp++ = '.'; *cp++ = '0'; *cp++ = 0; + len += 2; } } + + return len; } @@ -1332,8 +1342,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag for (i = 0; i < print_depth; i++) if (EQ (obj, being_printed[i])) { - sprintf (buf, "#%d", i); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, "#%d", i); + strout (buf, len, len, printcharfun); return; } being_printed[print_depth] = obj; @@ -1348,16 +1358,16 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag if (n < 0) { /* Add a prefix #n= if OBJ has not yet been printed; that is, its status field is nil. */ - sprintf (buf, "#%"pI"d=", -n); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, "#%"pI"d=", -n); + strout (buf, len, len, printcharfun); /* OBJ is going to be printed. Remember that fact. */ Fputhash (obj, make_number (- n), Vprint_number_table); } else { /* Just print #n# if OBJ has already been printed. */ - sprintf (buf, "#%"pI"d#", n); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, "#%"pI"d#", n); + strout (buf, len, len, printcharfun); return; } } @@ -1368,16 +1378,17 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag switch (XTYPE (obj)) { case_Lisp_Int: - sprintf (buf, "%"pI"d", XINT (obj)); - strout (buf, -1, -1, printcharfun); + { + int len = sprintf (buf, "%"pI"d", XINT (obj)); + strout (buf, len, len, printcharfun); + } break; case Lisp_Float: { char pigbuf[FLOAT_TO_STRING_BUFSIZE]; - - float_to_string (pigbuf, XFLOAT_DATA (obj)); - strout (pigbuf, -1, -1, printcharfun); + int len = float_to_string (pigbuf, XFLOAT_DATA (obj)); + strout (pigbuf, len, len, printcharfun); } break; @@ -1447,15 +1458,16 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag when found in a multibyte string, always use a hex escape so it reads back as multibyte. */ char outbuf[50]; + int len; if (CHAR_BYTE8_P (c)) - sprintf (outbuf, "\\%03o", CHAR_TO_BYTE8 (c)); + len = sprintf (outbuf, "\\%03o", CHAR_TO_BYTE8 (c)); else { - sprintf (outbuf, "\\x%04x", c); + len = sprintf (outbuf, "\\x%04x", c); need_nonhex = 1; } - strout (outbuf, -1, -1, printcharfun); + strout (outbuf, len, len, printcharfun); } else if (! multibyte && SINGLE_BYTE_CHAR_P (c) && ! ASCII_BYTE_P (c) @@ -1466,8 +1478,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag print single-byte non-ASCII string chars using octal escapes. */ char outbuf[5]; - sprintf (outbuf, "\\%03o", c); - strout (outbuf, -1, -1, printcharfun); + int len = sprintf (outbuf, "\\%03o", c); + strout (outbuf, len, len, printcharfun); } else { @@ -1632,8 +1644,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag /* Simple but incomplete way. */ if (i != 0 && EQ (obj, halftail)) { - sprintf (buf, " . #%"pMd, i / 2); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, " . #%"pMd, i / 2); + strout (buf, len, len, printcharfun); goto end_of_list; } } @@ -1697,7 +1709,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag else if (BOOL_VECTOR_P (obj)) { ptrdiff_t i; - register unsigned char c; + int len; + unsigned char c; struct gcpro gcpro1; ptrdiff_t size_in_chars = ((XBOOL_VECTOR (obj)->size + BOOL_VECTOR_BITS_PER_CHAR - 1) @@ -1707,8 +1720,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag PRINTCHAR ('#'); PRINTCHAR ('&'); - sprintf (buf, "%"pI"d", XBOOL_VECTOR (obj)->size); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, "%"pI"d", XBOOL_VECTOR (obj)->size); + strout (buf, len, len, printcharfun); PRINTCHAR ('\"'); /* Don't print more characters than the specified maximum. @@ -1759,9 +1772,11 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag } else if (WINDOWP (obj)) { + int len; strout ("#sequence_number)); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, "%"pI"d", + XFASTINT (XWINDOW (obj)->sequence_number)); + strout (buf, len, len, printcharfun); if (!NILP (XWINDOW (obj)->buffer)) { strout (" on ", -1, -1, printcharfun); @@ -1771,10 +1786,11 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag } else if (TERMINALP (obj)) { + int len; struct terminal *t = XTERMINAL (obj); strout ("#id); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, "%d", t->id); + strout (buf, len, len, printcharfun); if (t->name) { strout (" on ", -1, -1, printcharfun); @@ -1787,6 +1803,7 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag struct Lisp_Hash_Table *h = XHASH_TABLE (obj); ptrdiff_t i; ptrdiff_t real_size, size; + int len; #if 0 strout ("#test)) @@ -1797,18 +1814,18 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag PRINTCHAR (' '); strout (SDATA (SYMBOL_NAME (h->weak)), -1, -1, printcharfun); PRINTCHAR (' '); - sprintf (buf, "%"pD"d/%"pD"d", h->count, ASIZE (h->next)); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, "%"pD"d/%"pD"d", h->count, ASIZE (h->next)); + strout (buf, len, len, printcharfun); } - sprintf (buf, " %p", h); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, " %p", h); + strout (buf, len, len, printcharfun); PRINTCHAR ('>'); #endif /* Implement a readable output, e.g.: #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ /* Always print the size. */ - sprintf (buf, "#s(hash-table size %"pD"d", ASIZE (h->next)); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, "#s(hash-table size %"pD"d", ASIZE (h->next)); + strout (buf, len, len, printcharfun); if (!NILP (h->test)) { @@ -1881,12 +1898,13 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag } else if (FRAMEP (obj)) { + int len; strout ((FRAME_LIVE_P (XFRAME (obj)) ? "#name, printcharfun); - sprintf (buf, " %p", XFRAME (obj)); - strout (buf, -1, -1, printcharfun); + len = sprintf (buf, " %p", XFRAME (obj)); + strout (buf, len, len, printcharfun); PRINTCHAR ('>'); } else if (FONTP (obj)) @@ -1982,8 +2000,8 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag strout ("in no buffer", -1, -1, printcharfun); else { - sprintf (buf, "at %"pD"d", marker_position (obj)); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, "at %"pD"d", marker_position (obj)); + strout (buf, len, len, printcharfun); strout (" in ", -1, -1, printcharfun); print_string (BVAR (XMARKER (obj)->buffer, name), printcharfun); } @@ -1996,10 +2014,10 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag strout ("in no buffer", -1, -1, printcharfun); else { - sprintf (buf, "from %"pD"d to %"pD"d in ", - marker_position (OVERLAY_START (obj)), - marker_position (OVERLAY_END (obj))); - strout (buf, -1, -1, printcharfun); + int len = sprintf (buf, "from %"pD"d to %"pD"d in ", + marker_position (OVERLAY_START (obj)), + marker_position (OVERLAY_END (obj))); + strout (buf, len, len, printcharfun); print_string (BVAR (XMARKER (OVERLAY_START (obj))->buffer, name), printcharfun); } @@ -2014,10 +2032,12 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag case Lisp_Misc_Save_Value: strout ("#pointer, - XSAVE_VALUE (obj)->integer); - strout (buf, -1, -1, printcharfun); + { + int len = sprintf (buf, "ptr=%p int=%"pD"d", + XSAVE_VALUE (obj)->pointer, + XSAVE_VALUE (obj)->integer); + strout (buf, len, len, printcharfun); + } PRINTCHAR ('>'); break; @@ -2029,16 +2049,17 @@ print_object (Lisp_Object obj, register Lisp_Object printcharfun, int escapeflag default: badtype: { + int len; /* We're in trouble if this happens! Probably should just abort () */ strout ("#", -1, -1, printcharfun); } diff --git a/src/term.c b/src/term.c index d58dc2ba878..98f5639fb4a 100644 --- a/src/term.c +++ b/src/term.c @@ -1851,8 +1851,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym) len = 1; else if (len > 4) len = 4; - sprintf (buf, "[%.*s]", len, str); - len += 2; + len = sprintf (buf, "[%.*s]", len, str); str = buf; } else diff --git a/src/xdisp.c b/src/xdisp.c index 0050d644931..23ecbb5d480 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -9365,12 +9365,10 @@ message_dolog (const char *m, ptrdiff_t nbytes, int nlflag, int multibyte) { char dupstr[sizeof " [ times]" + INT_STRLEN_BOUND (printmax_t)]; - int duplen; /* If you change this format, don't forget to also change message_log_check_duplicate. */ - sprintf (dupstr, " [%"pMd" times]", dups); - duplen = strlen (dupstr); + int duplen = sprintf (dupstr, " [%"pMd" times]", dups); TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1); insert_1 (dupstr, duplen, 1, 0, 1); } diff --git a/src/xfns.c b/src/xfns.c index 575d9434c76..02aefe9d91a 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -5956,10 +5956,10 @@ When using Gtk+ tooltips, the tooltip face is not used. */); DEFVAR_LISP ("gtk-version-string", Vgtk_version_string, doc: /* Version info for GTK+. */); { - char gtk_version[40]; - g_snprintf (gtk_version, sizeof (gtk_version), "%u.%u.%u", - GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); - Vgtk_version_string = make_pure_string (gtk_version, strlen (gtk_version), strlen (gtk_version), 0); + char gtk_version[sizeof ".." + 3 * INT_STRLEN_BOUND (int)]; + int len = sprintf (gtk_version, "%d.%d.%d", + GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); + Vgtk_version_string = make_pure_string (gtk_version, len, len, 0); } #endif /* USE_GTK */ -- 2.39.2