Re: [perl #40583] sprintf "%#04X" also uppercases the 0x-prefix
SADAHIRO Tomoyuki [Fri, 27 Oct 2006 00:19:34 +0000 (09:19 +0900)]
Message-Id: <20061027001924.B158.BQW10602@nifty.com>

p4raw-id: //depot/perl@29116

pod/perlfunc.pod
sv.c
t/op/sprintf.t

index ba8cb6c..9e7414a 100644 (file)
@@ -5554,21 +5554,27 @@ to take the arguments out of order, e.g.:
 =item flags
 
 one or more of:
+
    space   prefix positive number with a space
    +       prefix positive number with a plus sign
    -       left-justify within the field
    0       use zeros, not spaces, to right-justify
-   #       prefix non-zero octal with "0", non-zero hex with "0x"
-           or "0X", non-zero binary with "0b" or "0B"
+   #       ensure the leading "0" for any octal,
+           prefix non-zero hexadecimal with "0x" or "0X",
+           prefix non-zero binary with "0b" or "0B"
 
 For example:
 
-  printf '<% d>', 12;   # prints "< 12>"
-  printf '<%+d>', 12;   # prints "<+12>"
-  printf '<%6s>', 12;   # prints "<    12>"
-  printf '<%-6s>', 12;  # prints "<12    >"
-  printf '<%06s>', 12;  # prints "<000012>"
-  printf '<%#x>', 12;   # prints "<0xc>"
+  printf '<% d>',  12;   # prints "< 12>"
+  printf '<%+d>',  12;   # prints "<+12>"
+  printf '<%6s>',  12;   # prints "<    12>"
+  printf '<%-6s>', 12;   # prints "<12    >"
+  printf '<%06s>', 12;   # prints "<000012>"
+  printf '<%#o>',  12;   # prints "<014>"
+  printf '<%#x>',  12;   # prints "<0xc>"
+  printf '<%#X>',  12;   # prints "<0XC>"
+  printf '<%#b>',  12;   # prints "<0b1100>"
+  printf '<%#B>',  12;   # prints "<0B1100>"
 
 When a space and a plus sign are given as the flags at once,
 a plus sign is used to prefix a positive number.
@@ -5576,6 +5582,13 @@ a plus sign is used to prefix a positive number.
   printf '<%+ d>', 12;   # prints "<+12>"
   printf '<% +d>', 12;   # prints "<+12>"
 
+When the # flag and a precision are given in the %o conversion,
+the precision is incremented if it's necessary for the leading "0".
+
+  printf '<%#.5o>', 012;      # prints "<00012>"
+  printf '<%#.5o>', 012345;   # prints "<012345>"
+  printf '<%#.0o>', 0;        # prints "<0>"
+
 =item vector flag
 
 This flag tells perl to interpret the supplied string as a vector of
diff --git a/sv.c b/sv.c
index e38d4b7..4f9a625 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -9148,7 +9148,8 @@ Perl_sv_vcatpvfn(pTHX_ SV *sv, const char *pat, STRLEN patlen, va_list *args, SV
                if (has_precis) {
                    if (precis > elen)
                        zeros = precis - elen;
-                   else if (precis == 0 && elen == 1 && *eptr == '0')
+                   else if (precis == 0 && elen == 1 && *eptr == '0'
+                            && !(base == 8 && alt)) /* "%#.0o" prints "0" */
                        elen = 0;
 
                /* a precision nullifies the 0 flag. */
index 6751a86..2b9c7bc 100755 (executable)
@@ -219,6 +219,26 @@ __END__
 >% 6.5b<    >12<          > 01100<
 >%06.5b<    >12<          > 01100<         >0 flag with precision: no effect<
 >%.5b<      >12<          >01100<
+>%.0b<      >0<           ><
+>%+.0b<     >0<           ><
+>% .0b<     >0<           ><
+>%-.0b<     >0<           ><
+>%#.0b<     >0<           ><
+>%#3.0b<    >0<           >   <
+>%#3.1b<    >0<           >  0<
+>%#3.2b<    >0<           > 00<
+>%#3.3b<    >0<           >000<
+>%#3.4b<    >0<           >0000<
+>%.0b<      >1<           >1<
+>%+.0b<     >1<           >1<
+>% .0b<     >1<           >1<
+>%-.0b<     >1<           >1<
+>%#.0b<     >1<           >0b1<
+>%#3.0b<    >1<           >0b1<
+>%#3.1b<    >1<           >0b1<
+>%#3.2b<    >1<           >0b01<
+>%#3.3b<    >1<           >0b001<
+>%#3.4b<    >1<           >0b0001<
 >%c<        >ord('A')<    >A<
 >%10c<      >ord('A')<    >         A<
 >%#10c<     >ord('A')<    >         A<     ># modifier: no effect<
@@ -421,6 +441,28 @@ __END__
 >% 4.o<     >36<          >  44<
 >%04.o<     >36<          >  44<          >0 flag with precision: no effect<
 >%.3o<      >18<          >022<
+>%.0o<      >0<           ><
+>%+.0o<     >0<           ><
+>% .0o<     >0<           ><
+>%-.0o<     >0<           ><
+>%#.0o<     >0<           >0<
+>%#3.0o<    >0<           >  0<
+>%#3.1o<    >0<           >  0<
+>%#3.2o<    >0<           > 00<
+>%#3.3o<    >0<           >000<
+>%#3.4o<    >0<           >0000<
+>%.0o<      >1<           >1<
+>%+.0o<     >1<           >1<
+>% .0o<     >1<           >1<
+>%-.0o<     >1<           >1<
+>%#.0o<     >1<           >01<
+>%#3.0o<    >1<           > 01<
+>%#3.1o<    >1<           > 01<
+>%#3.2o<    >1<           > 01<
+>%#3.3o<    >1<           >001<
+>%#3.4o<    >1<           >0001<
+>%#.5o<     >012345<      >012345<
+>%#.5o<     >012<         >00012<
 >%#4o<      >17<          > 021<
 >%#-4o<     >17<          >021 <
 >%-#4o<     >17<          >021 <
@@ -513,6 +555,23 @@ __END__
 >% .0x<     >0<           ><
 >%-.0x<     >0<           ><
 >%#.0x<     >0<           ><
+>%#3.0x<    >0<           >   <
+>%#3.1x<    >0<           >  0<
+>%#3.2x<    >0<           > 00<
+>%#3.3x<    >0<           >000<
+>%#3.4x<    >0<           >0000<
+>%.0x<      >1<           >1<
+>%+.0x<     >1<           >1<
+>% .0x<     >1<           >1<
+>%-.0x<     >1<           >1<
+>%#.0x<     >1<           >0x1<
+>%#3.0x<    >1<           >0x1<
+>%#3.1x<    >1<           >0x1<
+>%#3.2x<    >1<           >0x01<
+>%#3.3x<    >1<           >0x001<
+>%#3.4x<    >1<           >0x0001<
+>%#.5x<     >0x12345<     >0x12345<
+>%#.5x<     >0x12<        >0x00012<
 >%#4x<      >28<          >0x1c<
 >%#4.3x<    >28<          >0x01c<
 >%#-4.3x<   >28<          >0x01c<
@@ -583,8 +642,12 @@ __END__
 >%v#x< >''<    >%v#x INVALID<
 >%v02x<        >"\x66\x6f\x6f\012"<    >66.6f.6f.0a<
 >%#v.8b<       >"\141\000\142"<        >0b01100001.00000000.0b01100010<        >perl #39530<
+>%#v.0o<       >"\001\000\002\000"<    >01.0.02.0<
+>%#v.1o<       >"\001\000\002\000"<    >01.0.02.0<
 >%#v.4o<       >"\141\000\142"<        >0141.0000.0142<        >perl #39530<
 >%#v.3i<       >"\141\000\142"<        >097.000.098<   >perl #39530<
+>%#v.0x<       >"\001\000\002\000"<    >0x1..0x2.<
+>%#v.1x<       >"\001\000\002\000"<    >0x1.0.0x2.0<
 >%#v.2x<       >"\141\000\142"<        >0x61.00.0x62<  >perl #39530<
 >%#v.2X<       >"\141\000\142"<        >0X61.00.0X62<  >perl #39530<
 >%#v.8b<       >"\141\017\142"<        >0b01100001.0b00001111.0b01100010<      >perl #39530<