From: Nicholas Clark <nick@ccl4.org>
Date: Mon, 24 Oct 2005 21:20:21 +0000 (+0000)
Subject: Add my_sprintf, which is usually just a macro for sprintf, for those
X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=ce582ceece605be1a68752611f28e5b1a8e80455;p=p5sagit%2Fp5-mst-13.2.git

Add my_sprintf, which is usually just a macro for sprintf, for those
places where we want to use the return value of sprintf. This allows
a wrapper to be used for platforms where the C library isn't ANSI-
conformant.

p4raw-id: //depot/perl@25832
---

diff --git a/config_h.SH b/config_h.SH
index 15d8b43..e6e7f9b 100644
--- a/config_h.SH
+++ b/config_h.SH
@@ -4378,5 +4378,13 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un
 #$d_ttyname_r HAS_TTYNAME_R	   /**/
 #define TTYNAME_R_PROTO $ttyname_r_proto	   /**/
 
+/* SPRINTF_RETURNS_STRLEN:
+ *	This variable defines whether sprintf returns the length of the string
+ *	(as per the ANSI spec). Some C libraries retain compatibility with
+ *	pre-ANSI C and return a pointer to the passed in buffer; for these
+ *	this variable will be undef.
+ */
+#$d_sprintf_returns_strlen SPRINTF_RETURNS_STRLEN	/**/
+
 #endif
 !GROK!THIS!
diff --git a/embed.fnc b/embed.fnc
index 320c638..f00f722 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -1545,6 +1545,10 @@ Apo	|bool	|ckwarn_d	|U32 w
 
 p	|void	|offer_nice_chunk	|NN void *chunk|U32 chunk_size
 
+#ifndef SPRINTF_RETURNS_STRLEN
+Apnod	|int	|my_sprintf	|NN char *buffer|NN const char *pat|...
+#endif
+
 END_EXTERN_C
 /*
  * ex: set ts=8 sts=4 sw=4 noet:
diff --git a/embed.h b/embed.h
index 9ccf80d..d39d4c2 100644
--- a/embed.h
+++ b/embed.h
@@ -1653,6 +1653,8 @@
 #ifdef PERL_CORE
 #define offer_nice_chunk	Perl_offer_nice_chunk
 #endif
+#ifndef SPRINTF_RETURNS_STRLEN
+#endif
 #define ck_anoncode		Perl_ck_anoncode
 #define ck_bitop		Perl_ck_bitop
 #define ck_concat		Perl_ck_concat
@@ -3639,6 +3641,8 @@
 #ifdef PERL_CORE
 #define offer_nice_chunk(a,b)	Perl_offer_nice_chunk(aTHX_ a,b)
 #endif
+#ifndef SPRINTF_RETURNS_STRLEN
+#endif
 #define ck_anoncode(a)		Perl_ck_anoncode(aTHX_ a)
 #define ck_bitop(a)		Perl_ck_bitop(aTHX_ a)
 #define ck_concat(a)		Perl_ck_concat(aTHX_ a)
diff --git a/global.sym b/global.sym
index fac84a0..e90127d 100644
--- a/global.sym
+++ b/global.sym
@@ -699,4 +699,5 @@ Perl_stashpv_hvname_match
 Perl_gv_SVadd
 Perl_ckwarn
 Perl_ckwarn_d
+Perl_my_sprintf
 # ex: set ro:
diff --git a/makedef.pl b/makedef.pl
index 0ee159d..8975d50 100644
--- a/makedef.pl
+++ b/makedef.pl
@@ -819,6 +819,11 @@ unless ($define{'PERL_DONT_CREATE_GVSV'}) {
 		     Perl_gv_SVadd
 		    )];
 }
+if ($define{'SPRINTF_RETURNS_STRLEN'}) {
+    skip_symbols [qw(
+		     Perl_my_sprintf
+		    )];
+}
 
 unless ($define{'d_mmap'}) {
     skip_symbols [qw(
diff --git a/perl.h b/perl.h
index 11cfc75..28d2ad8 100644
--- a/perl.h
+++ b/perl.h
@@ -1402,6 +1402,16 @@ int sockatmark(int);
 #  define sprintf UTS_sprintf_wrap
 #endif
 
+/* For the times when you want the return value of sprintf, and you want it
+   to be the length. Can't have a thread variable passed in, because C89 has
+   no varargs macros.
+*/
+#ifdef SPRINTF_RETURNS_STRLEN
+#  define my_sprintf sprintf
+#else
+#  define my_sprintf Perl_my_sprintf
+#endif
+
 /* Configure gets this right but the UTS compiler gets it wrong.
    -- Hal Morris <hom00@utsglobal.com> */
 #ifdef UTS
diff --git a/proto.h b/proto.h
index 2b028a1..0839945 100644
--- a/proto.h
+++ b/proto.h
@@ -4052,6 +4052,13 @@ PERL_CALLCONV void	Perl_offer_nice_chunk(pTHX_ void *chunk, U32 chunk_size)
 			__attribute__nonnull__(pTHX_1);
 
 
+#ifndef SPRINTF_RETURNS_STRLEN
+PERL_CALLCONV int	Perl_my_sprintf(char *buffer, const char *pat, ...)
+			__attribute__nonnull__(1)
+			__attribute__nonnull__(2);
+
+#endif
+
 END_EXTERN_C
 /*
  * ex: set ts=8 sts=4 sw=4 noet:
diff --git a/util.c b/util.c
index c46a40e..6df7d8d 100644
--- a/util.c
+++ b/util.c
@@ -2707,9 +2707,9 @@ Perl_pidgone(pTHX_ Pid_t pid, int status)
 {
     register SV *sv;
     char spid[TYPE_CHARS(IV)];
+    size_t len = my_sprintf(spid, "%"IVdf, (IV)pid);
 
-    sprintf(spid, "%"IVdf, (IV)pid);
-    sv = *hv_fetch(PL_pidstatus,spid,strlen(spid),TRUE);
+    sv = *hv_fetch(PL_pidstatus,spid,len,TRUE);
     SvUPGRADE(sv,SVt_IV);
     SvIV_set(sv, status);
     return;
@@ -5081,6 +5081,27 @@ Perl_mem_log_free(Malloc_t oldalloc, const char *filename, const int linenumber,
 #endif /* PERL_MEM_LOG */
 
 /*
+=for apidoc my_sprintf
+
+The C library C<sprintf>, wrapped if necessary, to ensure that it will return
+the length of the string written to the buffer. Only rare pre-ANSI systems
+need the wrapper function - usually this is a direct call to C<sprintf>.
+
+=cut
+*/
+#ifndef SPRINTF_RETURNS_STRLEN
+int
+Perl_my_sprintf(char *buffer, const char* pat, ...)
+{
+    va_list args;
+    va_start(args, pat);
+    vsprintf(buffer, pat, args);
+    va_end(args);
+    return strlen(buffer);
+}
+#endif
+
+/*
  * Local variables:
  * c-indentation-style: bsd
  * c-basic-offset: 4