Add a new warning, "Newline in left-justified string for printf/sprintf"
Robin Barker [Wed, 11 Jun 2003 18:10:14 +0000 (19:10 +0100)]
to be issued if the string to be left-justified by s?printf contains
a newline.

Subject: [PATCH] RE: [perl #22599] Strange behaviour when combining foreac h and printf
Message-ID: <533D273D4014D411AB1D00062938C4D904046571@hotel.npl.co.uk>

p4raw-id: //depot/perl@19752

pod/perldiag.pod
sv.c
t/lib/warnings/sv

index e2728d1..4d95016 100644 (file)
@@ -2222,6 +2222,15 @@ C<??> appear to be nested quantifiers, but aren't.  See L<perlre>.
 (S internal) The symbol in question was declared but somehow went out of
 scope before it could possibly have been used.
 
+=item Newline in left-justified string for %s
+
+(W printf) There is a newline in a string to be left justified by 
+C<printf> or C<sprintf>.
+
+The padding spaces will appear after the newline, which is probably not
+what you wanted.  Usually you should remove the newline from the string 
+and put formatting characters in the C<sprintf> format.
+
 =item No %s allowed while running setuid
 
 (F) Certain operations are deemed to be too insecure for a setuid or
diff --git a/sv.c b/sv.c
index 932438b..d1324fc 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -9329,6 +9329,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
             p = SvEND(sv);
             *p = '\0';
        }
+       if (left && ckWARN(WARN_PRINTF) && strchr(eptr, '\n') && 
+           (PL_op->op_type == OP_PRTF || PL_op->op_type == OP_SPRINTF)) 
+           Perl_warner(aTHX_ packWARN(WARN_PRINTF),
+               "Newline in left-justified string for %sprintf",
+                       (PL_op->op_type == OP_PRTF) ? "" : "s");
        
        have = esignlen + zeros + elen;
        need = (have > width ? have : width);
index d9aa827..6060fbc 100644 (file)
@@ -345,3 +345,22 @@ no warnings 'numeric' ;
 $a = "\x{100}\x{200}"; $a = -$a;
 EXPECT
 Argument "\x{100}\x{200}" isn't numeric in negation (-) at - line 3.
+########
+# sv.c
+open F, ">".($^O eq 'VMS'? 'NL:' : '/dev/null') ;
+use warnings 'printf';
+$a = "a\nb";
+$s = sprintf "%4s", $a;
+printf F "%4s", $a;
+$s = sprintf "%-4s", $a;
+printf F "%-4s", $a;
+$s = sprintf "%*s", -4, $a;
+no warnings 'printf';
+$s = sprintf "%4s", $a;
+printf F "%4s", $a;
+$s = sprintf "%-4s", $a;
+printf F "%-4s", $a;
+EXPECT
+Newline in left-justified string for sprintf at - line 7.
+Newline in left-justified string for printf at - line 8.
+Newline in left-justified string for sprintf at - line 9.