summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2006-05-13 01:28:49 +0300
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2006-05-12 20:57:07 +0000
commitd9fad198da41e1cd37600ae397146e27a413303d (patch)
tree79dab04c73d50aa2a12e95f128a8cc3361ec5908
parent54f961c9c7fe5166a70653b44c67c26122bfc1fd (diff)
downloadperl-d9fad198da41e1cd37600ae397146e27a413303d.tar.gz
Re: [PATCH] my_snprintf
Message-ID: <4464E1F1.9010706@gmail.com> p4raw-id: //depot/perl@28183
-rw-r--r--embed.fnc3
-rw-r--r--global.sym2
-rw-r--r--perl.h3
-rw-r--r--perlio.c12
-rw-r--r--pod/perlapi.pod25
-rw-r--r--pp_ctl.c21
-rw-r--r--proto.h9
-rw-r--r--regcomp.c6
-rw-r--r--sv.c18
-rw-r--r--toke.c6
-rw-r--r--universal.c6
-rw-r--r--util.c184
12 files changed, 156 insertions, 139 deletions
diff --git a/embed.fnc b/embed.fnc
index 3fa7b932ca..98b980fa38 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -1687,6 +1687,9 @@ p |void |offer_nice_chunk |NN void *chunk|U32 chunk_size
Apnod |int |my_sprintf |NN char *buffer|NN const char *pat|...
#endif
+Apnod |int |my_snprintf |NN char *buffer|const Size_t len|NN const char *format|...
+Apnod |int |my_vsnprintf |NN char *buffer|const Size_t len|NN const char *format|va_list ap
+
px |void |my_clearenv
#ifdef PERL_IMPLICIT_CONTEXT
diff --git a/global.sym b/global.sym
index 49c90bf421..dfe7eda420 100644
--- a/global.sym
+++ b/global.sym
@@ -713,5 +713,7 @@ Perl_ckwarn
Perl_ckwarn_d
Perl_new_warnings_bitfield
Perl_my_sprintf
+Perl_my_snprintf
+Perl_my_vsnprintf
Perl_my_cxt_init
# ex: set ro:
diff --git a/perl.h b/perl.h
index f83cbf822c..91e1b58647 100644
--- a/perl.h
+++ b/perl.h
@@ -1449,6 +1449,9 @@ int sockatmark(int);
# define my_sprintf Perl_my_sprintf
#endif
+#define my_snprintf Perl_my_snprintf
+#define my_vsnprintf Perl_my_vsnprintf
+
/* Configure gets this right but the UTS compiler gets it wrong.
-- Hal Morris <hom00@utsglobal.com> */
#ifdef UTS
diff --git a/perlio.c b/perlio.c
index 288159c188..ad2570e62f 100644
--- a/perlio.c
+++ b/perlio.c
@@ -479,11 +479,7 @@ PerlIO_debug(const char *fmt, ...)
/* Use fixed buffer as sv_catpvf etc. needs SVs */
char buffer[1024];
const STRLEN len = my_sprintf(buffer, "%.40s:%" IVdf " ", s ? s : "(none)", (IV) CopLINE(PL_curcop));
-# ifdef USE_VSNPRINTF
- const STRLEN len2 = vsnprintf(buffer+len, sizeof(buffer) - len, fmt, ap);
-# else
- const STRLEN len2 = vsprintf(buffer+len, fmt, ap);
-# endif /* USE_VSNPRINTF */
+ const STRLEN len2 = my_vsnprintf(buffer+len, sizeof(buffer) - len, fmt, ap);
PerlLIO_write(PL_perlio_debug_fd, buffer, len + len2);
#else
const char *s = CopFILE(PL_curcop);
@@ -5147,11 +5143,7 @@ int
PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
{
dVAR;
-#ifdef USE_VSNPRINTF
- const int val = vsnprintf(s, n > 0 ? n : 0, fmt, ap);
-#else
- const int val = vsprintf(s, fmt, ap);
-#endif /* #ifdef USE_VSNPRINTF */
+ const int val = my_vsnprintf(s, n > 0 ? n : 0, fmt, ap);
if (n >= 0) {
if (strlen(s) >= (STRLEN) n) {
dTHX;
diff --git a/pod/perlapi.pod b/pod/perlapi.pod
index d608eef3c3..c3b6074873 100644
--- a/pod/perlapi.pod
+++ b/pod/perlapi.pod
@@ -2245,6 +2245,19 @@ Fill the sv with current working directory
=for hackers
Found in file util.c
+=item my_snprintf
+X<my_snprintf>
+
+The C library C<snprintf> functionality, if available and
+standards-compliant (uses C<vsnprintf>, actually). If the
+C<vsnprintf> is not available, will unfortunately use the unsafe
+C<vsprintf>. Consider using C<sv_vcatpvf> instead.
+
+ int my_snprintf(char *buffer, const Size_t len, const char *format, ...)
+
+=for hackers
+Found in file util.c
+
=item my_sprintf
X<my_sprintf>
@@ -2257,6 +2270,18 @@ need the wrapper function - usually this is a direct call to C<sprintf>.
=for hackers
Found in file util.c
+=item my_vsnprintf
+X<my_vsnprintf>
+
+The C library C<vsnprintf> if available and standards-compliant,
+but if the C<vsnprintf> is not available, will unfortunately use
+the unsafe C<vsprintf>. Consider using C<sv_vcatpvf> instead.
+
+ int my_vsnprintf(char *buffer, const Size_t len, const char *format, va_list ap)
+
+=for hackers
+Found in file util.c
+
=item new_version
X<new_version>
diff --git a/pp_ctl.c b/pp_ctl.c
index d335281e61..55ffb1933b 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -831,11 +831,7 @@ PP(pp_formline)
/* Formats aren't yet marked for locales, so assume "yes". */
{
STORE_NUMERIC_STANDARD_SET_LOCAL();
-#ifdef USE_SNPRINTF
- snprintf(t, SvLEN(PL_formtarget) - (t - SvPVX(PL_formtarget)), fmt, (int) fieldsize, (int) arg & 255, value);
-#else
- sprintf(t, fmt, (int) fieldsize, (int) arg & 255, value);
-#endif /* ifdef USE_SNPRINTF */
+ my_snprintf(t, SvLEN(PL_formtarget) - (t - SvPVX(PL_formtarget)), fmt, (int) fieldsize, (int) arg & 255, value);
RESTORE_NUMERIC_STANDARD();
}
t += fieldsize;
@@ -2773,13 +2769,8 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, const char *code, PAD** padp)
len = SvCUR(sv);
}
else
-#ifdef USE_SNPRINTF
- len = snprintf(tmpbuf, sizeof(tbuf), "_<(%.10s_eval %lu)", code,
- (unsigned long)++PL_evalseq);
-#else
- len = my_sprintf(tmpbuf, "_<(%.10s_eval %lu)", code,
- (unsigned long)++PL_evalseq);
-#endif /* ifdef USE_SNPRINTF */
+ len = my_snprintf(tmpbuf, sizeof(tbuf), "_<(%.10s_eval %lu)", code,
+ (unsigned long)++PL_evalseq);
SAVECOPFILE_FREE(&PL_compiling);
CopFILE_set(&PL_compiling, tmpbuf+2);
SAVECOPLINE(&PL_compiling);
@@ -3461,11 +3452,7 @@ PP(pp_entereval)
len = SvCUR(temp_sv);
}
else
-#ifdef USE_SNPRINTF
- len = snprintf(tmpbuf, sizeof(tbuf), "_<(eval %lu)", (unsigned long)++PL_evalseq);
-#else
- len = my_sprintf(tmpbuf, "_<(eval %lu)", (unsigned long)++PL_evalseq);
-#endif /* ifdef USE_SNPRINTF */
+ len = my_snprintf(tmpbuf, sizeof(tbuf), "_<(eval %lu)", (unsigned long)++PL_evalseq);
SAVECOPFILE_FREE(&PL_compiling);
CopFILE_set(&PL_compiling, tmpbuf+2);
SAVECOPLINE(&PL_compiling);
diff --git a/proto.h b/proto.h
index 43a749aea9..07ee72d4b9 100644
--- a/proto.h
+++ b/proto.h
@@ -4335,6 +4335,15 @@ PERL_CALLCONV int Perl_my_sprintf(char *buffer, const char *pat, ...)
#endif
+PERL_CALLCONV int Perl_my_snprintf(char *buffer, const Size_t len, const char *format, ...)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(3);
+
+PERL_CALLCONV int Perl_my_vsnprintf(char *buffer, const Size_t len, const char *format, va_list ap)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(3);
+
+
PERL_CALLCONV void Perl_my_clearenv(pTHX);
#ifdef PERL_IMPLICIT_CONTEXT
diff --git a/regcomp.c b/regcomp.c
index 6ba85bb0cc..e98fcf9893 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -6184,11 +6184,7 @@ Perl_save_re_context(pTHX)
U32 i;
for (i = 1; i <= rx->nparens; i++) {
char digits[TYPE_CHARS(long)];
-#ifdef USE_SNPRINTF
- const STRLEN len = snprintf(digits, sizeof(digits), "%lu", (long)i);
-#else
- const STRLEN len = my_sprintf(digits, "%lu", (long)i);
-#endif /* #ifdef USE_SNPRINTF */
+ const STRLEN len = my_snprintf(digits, sizeof(digits), "%lu", (long)i);
GV *const *const gvp
= (GV**)hv_fetch(PL_defstash, digits, len, 0);
diff --git a/sv.c b/sv.c
index 6c7071dd18..37c84f426d 100644
--- a/sv.c
+++ b/sv.c
@@ -2660,13 +2660,8 @@ Perl_sv_2pv_flags(pTHX_ register SV *sv, STRLEN *lp, I32 flags)
if (SvIOKp(sv)) {
len = SvIsUV(sv)
-#ifdef USE_SNPRINTF
- ? snprintf(tbuf, sizeof(tbuf), "%"UVuf, (UV)SvUVX(sv))
- : snprintf(tbuf, sizeof(tbuf), "%"IVdf, (IV)SvIVX(sv));
-#else
- ? my_sprintf(tbuf, "%"UVuf, (UV)SvUVX(sv))
- : my_sprintf(tbuf, "%"IVdf, (IV)SvIVX(sv));
-#endif /* #ifdef USE_SNPRINTF */
+ ? my_snprintf(tbuf, sizeof(tbuf), "%"UVuf, (UV)SvUVX(sv))
+ : my_snprintf(tbuf, sizeof(tbuf), "%"IVdf, (IV)SvIVX(sv));
} else {
Gconvert(SvNVX(sv), NV_DIG, 0, tbuf);
len = strlen(tbuf);
@@ -9270,13 +9265,8 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
* --jhi */
#if defined(HAS_LONG_DOUBLE)
elen = ((intsize == 'q')
-# ifdef USE_SNPRINTF
- ? snprintf(PL_efloatbuf, PL_efloatsize, ptr, nv)
- : snprintf(PL_efloatbuf, PL_efloatsize, ptr, (double)nv));
-# else
- ? my_sprintf(PL_efloatbuf, ptr, nv)
- : my_sprintf(PL_efloatbuf, ptr, (double)nv));
-# endif /* #ifdef USE_SNPRINTF */
+ ? my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, nv)
+ : my_snprintf(PL_efloatbuf, PL_efloatsize, ptr, (double)nv));
#else
elen = my_sprintf(PL_efloatbuf, ptr, nv);
#endif
diff --git a/toke.c b/toke.c
index 173474cd0e..9e340baeb3 100644
--- a/toke.c
+++ b/toke.c
@@ -5976,11 +5976,7 @@ Perl_yylex(pTHX)
if (!PL_in_my_stash) {
char tmpbuf[1024];
PL_bufptr = s;
-#ifdef USE_SNPRINTF
- snprintf(tmpbuf, sizeof(tmpbuf), "No such class %.1000s", PL_tokenbuf);
-#else
- sprintf(tmpbuf, "No such class %.1000s", PL_tokenbuf);
-#endif /* #ifdef USE_SNPRINTF */
+ my_snprintf(tmpbuf, sizeof(tmpbuf), "No such class %.1000s", PL_tokenbuf);
yyerror(tmpbuf);
}
#ifdef PERL_MAD
diff --git a/universal.c b/universal.c
index 21f2c541d9..266613ed49 100644
--- a/universal.c
+++ b/universal.c
@@ -622,11 +622,7 @@ XS(XS_version_qv)
if ( SvNOK(ver) ) /* may get too much accuracy */
{
char tbuf[64];
-#ifdef USE_SNPRINTF
- const STRLEN len = snprintf(tbuf, sizeof(tbuf), "%.9"NVgf, SvNVX(ver));
-#else
- const STRLEN len = my_sprintf(tbuf, "%.9"NVgf, SvNVX(ver));
-#endif /* #ifdef USE_SNPRINTF */
+ const STRLEN len = my_snprintf(tbuf, sizeof(tbuf), "%.9"NVgf, SvNVX(ver));
version = savepvn(tbuf, len);
}
else
diff --git a/util.c b/util.c
index fb461ccfee..82f7f82b00 100644
--- a/util.c
+++ b/util.c
@@ -4294,11 +4294,7 @@ Perl_upg_version(pTHX_ SV *ver)
if ( SvNOK(ver) ) /* may get too much accuracy */
{
char tbuf[64];
-#ifdef USE_SNPRINTF
- const STRLEN len = snprintf(tbuf, sizeof(tbuf), "%.9"NVgf, SvNVX(ver));
-#else
- const STRLEN len = my_sprintf(tbuf, "%.9"NVgf, SvNVX(ver));
-#endif /* #ifdef USE_SNPRINTF */
+ const STRLEN len = my_snprintf(tbuf, sizeof(tbuf), "%.9"NVgf, SvNVX(ver));
version = savepvn(tbuf, len);
}
#ifdef SvVOK
@@ -5215,38 +5211,21 @@ Perl_mem_log_alloc(const UV n, const UV typesize, const char *typename, Malloc_t
gettimeofday(&tv, 0);
{
const STRLEN len =
-# ifdef USE_SNPRINTF
- snprintf(buf,
- PERL_MEM_LOG_SPRINTF_BUF_SIZE,
- "%10d.%06d: alloc: %s:%d:%s: %"IVdf" %"UVuf
- " %s = %"IVdf": %"UVxf"\n",
- (int)tv.tv_sec, (int)tv.tv_usec,
- filename, linenumber, funcname, n, typesize,
- typename, n * typesize, PTR2UV(newalloc));
-# else
- my_sprintf(buf,
- "%10d.%06d: alloc: %s:%d:%s: %"IVdf" %"UVuf
- " %s = %"IVdf": %"UVxf"\n",
- (int)tv.tv_sec, (int)tv.tv_usec,
- filename, linenumber, funcname, n, typesize,
- typename, n * typesize, PTR2UV(newalloc));
-# endif
+ my_snprintf(buf,
+ PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+ "%10d.%06d: alloc: %s:%d:%s: %"IVdf" %"UVuf
+ " %s = %"IVdf": %"UVxf"\n",
+ (int)tv.tv_sec, (int)tv.tv_usec,
+ filename, linenumber, funcname, n, typesize,
+ typename, n * typesize, PTR2UV(newalloc));
# else
const STRLEN len =
-# ifdef USE_SNPRINTF
- snprintf(buf,
- PERL_MEM_LOG_SPRINTF_BUF_SIZE,
- "alloc: %s:%d:%s: %"IVdf" %"UVuf
- " %s = %"IVdf": %"UVxf"\n",
- filename, linenumber, funcname, n, typesize,
- typename, n * typesize, PTR2UV(newalloc));
-# else
- my_sprintf(buf,
- "alloc: %s:%d:%s: %"IVdf" %"UVuf
- " %s = %"IVdf": %"UVxf"\n",
- filename, linenumber, funcname, n, typesize,
- typename, n * typesize, PTR2UV(newalloc));
-# endif
+ my_snprintf(buf,
+ PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+ "alloc: %s:%d:%s: %"IVdf" %"UVuf
+ " %s = %"IVdf": %"UVxf"\n",
+ filename, linenumber, funcname, n, typesize,
+ typename, n * typesize, PTR2UV(newalloc));
# endif
# ifdef PERL_MEM_LOG_ENV_FD
s = PerlEnv_getenv("PERL_MEM_LOG_FD");
@@ -5280,42 +5259,23 @@ Perl_mem_log_realloc(const UV n, const UV typesize, const char *typename, Malloc
gettimeofday(&tv, 0);
{
const STRLEN len =
-# ifdef USE_SNPRINTF
- snprintf(buf,
- PERL_MEM_LOG_SPRINTF_BUF_SIZE,
- "%10d.%06d: realloc: %s:%d:%s: %"IVdf" %"UVuf
- " %s = %"IVdf": %"UVxf" -> %"UVxf"\n",
- (int)tv.tv_sec, (int)tv.tv_usec,
- filename, linenumber, funcname, n, typesize,
- typename, n * typesize, PTR2UV(oldalloc),
- PTR2UV(newalloc));
-# else
- my_sprintf(buf,
- "%10d.%06d: realloc: %s:%d:%s: %"IVdf" %"UVuf
- " %s = %"IVdf": %"UVxf" -> %"UVxf"\n",
- (int)tv.tv_sec, (int)tv.tv_usec,
- filename, linenumber, funcname, n, typesize,
- typename, n * typesize, PTR2UV(oldalloc),
- PTR2UV(newalloc));
-# endif
+ my_snprintf(buf,
+ PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+ "%10d.%06d: realloc: %s:%d:%s: %"IVdf" %"UVuf
+ " %s = %"IVdf": %"UVxf" -> %"UVxf"\n",
+ (int)tv.tv_sec, (int)tv.tv_usec,
+ filename, linenumber, funcname, n, typesize,
+ typename, n * typesize, PTR2UV(oldalloc),
+ PTR2UV(newalloc));
# else
const STRLEN len =
-# ifdef USE_SNPRINTF
- snprintf(buf,
- PERL_MEM_LOG_SPRINTF_BUF_SIZE,
- "realloc: %s:%d:%s: %"IVdf" %"UVuf
- " %s = %"IVdf": %"UVxf" -> %"UVxf"\n",
- filename, linenumber, funcname, n, typesize,
- typename, n * typesize, PTR2UV(oldalloc),
- PTR2UV(newalloc));
-# else
- my_sprintf(buf,
- "realloc: %s:%d:%s: %"IVdf" %"UVuf
- " %s = %"IVdf": %"UVxf" -> %"UVxf"\n",
- filename, linenumber, funcname, n, typesize,
- typename, n * typesize, PTR2UV(oldalloc),
- PTR2UV(newalloc));
-# endif
+ my_snprintf(buf,
+ PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+ "realloc: %s:%d:%s: %"IVdf" %"UVuf
+ " %s = %"IVdf": %"UVxf" -> %"UVxf"\n",
+ filename, linenumber, funcname, n, typesize,
+ typename, n * typesize, PTR2UV(oldalloc),
+ PTR2UV(newalloc));
# endif
# ifdef PERL_MEM_LOG_ENV_FD
s = PerlEnv_getenv("PERL_MEM_LOG_FD");
@@ -5349,20 +5309,12 @@ Perl_mem_log_free(Malloc_t oldalloc, const char *filename, const int linenumber,
gettimeofday(&tv, 0);
{
const STRLEN len =
-# ifdef USE_SNPRINTF
- snprintf(buf,
- PERL_MEM_LOG_SPRINTF_BUF_SIZE,
- "%10d.%06d: free: %s:%d:%s: %"UVxf"\n",
- (int)tv.tv_sec, (int)tv.tv_usec,
- filename, linenumber, funcname,
- PTR2UV(oldalloc));
-# else
- my_sprintf(buf,
- "%10d.%06d: free: %s:%d:%s: %"UVxf"\n",
- (int)tv.tv_sec, (int)tv.tv_usec,
- filename, linenumber, funcname,
- PTR2UV(oldalloc));
-# endif
+ my_snprintf(buf,
+ PERL_MEM_LOG_SPRINTF_BUF_SIZE,
+ "%10d.%06d: free: %s:%d:%s: %"UVxf"\n",
+ (int)tv.tv_sec, (int)tv.tv_usec,
+ filename, linenumber, funcname,
+ PTR2UV(oldalloc));
# else
const STRLEN len =
my_sprintf(buf,
@@ -5405,6 +5357,72 @@ Perl_my_sprintf(char *buffer, const char* pat, ...)
}
#endif
+/*
+=for apidoc my_snprintf
+
+The C library C<snprintf> functionality, if available and
+standards-compliant (uses C<vsnprintf>, actually). If the
+C<vsnprintf> is not available, will unfortunately use the unsafe
+C<vsprintf>. Consider using C<sv_vcatpvf> instead.
+
+=cut
+*/
+int
+Perl_my_snprintf(char *buffer, const Size_t len, const char *format, ...)
+/* Cannot do this using variadic macros because that is too unportable. */
+{
+ dTHX;
+ int retval;
+ va_list ap;
+#ifndef USE_VSNPRINTF
+ PERL_UNUSED_ARG(len);
+#endif
+ va_start(ap, format);
+#ifdef USE_VSNPRINTF
+ retval = vsnprintf(buffer, len, format, ap);
+#else
+ retval = vsprintf(buffer, format, ap);
+#endif
+ va_end(ap);
+ return retval;
+}
+
+/*
+=for apidoc my_vsnprintf
+
+The C library C<vsnprintf> if available and standards-compliant,
+but if the C<vsnprintf> is not available, will unfortunately use
+the unsafe C<vsprintf>. Consider using C<sv_vcatpvf> instead.
+
+=cut
+*/
+int
+Perl_my_vsnprintf(char *buffer, const Size_t len, const char *format, va_list ap)
+/* Cannot do this using variadic macros because that is too unportable. */
+{
+ dTHX;
+ int retval;
+#ifndef USE_VSNPRINTF
+ PERL_UNUSED_ARG(len);
+#endif
+#ifdef NEED_VA_COPY
+ va_list apc;
+ Perl_va_copy(apc);
+# ifdef USE_VSNPRINTF
+ retval = vsnprintf(buffer, len, format, apc);
+# else
+ retval = vsprintf(buffer, format, apc);
+# endif
+#else
+# ifdef USE_VSNPRINTF
+ retval = vsnprintf(buffer, len, format, ap);
+# else
+ retval = vsprintf(buffer, format, ap);
+# endif
+#endif
+ return retval;
+}
+
void
Perl_my_clearenv(pTHX)
{