Add my_sprintf, which is usually just a macro for sprintf, for those
Nicholas Clark [Mon, 24 Oct 2005 21:20:21 +0000 (21:20 +0000)]
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

config_h.SH
embed.fnc
embed.h
global.sym
makedef.pl
perl.h
proto.h
util.c

index 15d8b43..e6e7f9b 100644 (file)
@@ -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!
index 320c638..f00f722 100644 (file)
--- 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 (file)
--- a/embed.h
+++ b/embed.h
 #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
 #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)
index fac84a0..e90127d 100644 (file)
@@ -699,4 +699,5 @@ Perl_stashpv_hvname_match
 Perl_gv_SVadd
 Perl_ckwarn
 Perl_ckwarn_d
+Perl_my_sprintf
 # ex: set ro:
index 0ee159d..8975d50 100644 (file)
@@ -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 (file)
--- 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 (file)
--- 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 (file)
--- 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