]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR modula2/119915: Sprintf1 repeats the entire format string if it starts with a...
authorGaius Mulley <gaiusmod2@gmail.com>
Thu, 24 Apr 2025 10:15:18 +0000 (11:15 +0100)
committerGaius Mulley <gaiusmod2@gmail.com>
Thu, 24 Apr 2025 10:15:18 +0000 (11:15 +0100)
This bugfix is for FormatStrings to ensure that in the case of %x, %u the
procedure function PerformFormatString uses Copy rather than Slice to
avoid the case on an upper bound of zero in Slice.  Oddly the %d case
had the correct code.

gcc/m2/ChangeLog:

PR modula2/119915
* gm2-libs/FormatStrings.mod (PerformFormatString): Handle
the %u and %x format specifiers in a similar way to the %d
specifier.  Avoid using Slice and use Copy instead.

gcc/testsuite/ChangeLog:

PR modula2/119915
* gm2/pimlib/run/pass/format2.mod: New test.

Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
gcc/m2/gm2-libs/FormatStrings.mod
gcc/testsuite/gm2/pimlib/run/pass/format2.mod [new file with mode: 0644]

index ec2985bdbb033c619ce83eba3897bfdb9acf13f5..aea8da94fd74bf5168757ffd4ae11400cf8c6cc6 100644 (file)
@@ -378,7 +378,7 @@ BEGIN
          THEN
             INC (afterperc) ;
             Cast (u, w) ;
-            in := ConCat (in, Slice (fmt, startpos, nextperc)) ;
+            in := Copy (fmt, in, startpos, nextperc) ;
             in := ConCat (in, CardinalToString (u, width, leader, 16, TRUE)) ;
             startpos := afterperc ;
             DSdbExit (NIL) ;
@@ -387,7 +387,7 @@ BEGIN
          THEN
             INC (afterperc) ;
             Cast (u, w) ;
-            in := ConCat (in, Slice (fmt, startpos, nextperc)) ;
+            in := Copy (fmt, in, startpos, nextperc) ;
             in := ConCat (in, CardinalToString (u, width, leader, 10, FALSE)) ;
             startpos := afterperc ;
             DSdbExit (NIL) ;
diff --git a/gcc/testsuite/gm2/pimlib/run/pass/format2.mod b/gcc/testsuite/gm2/pimlib/run/pass/format2.mod
new file mode 100644 (file)
index 0000000..2ad6a8c
--- /dev/null
@@ -0,0 +1,63 @@
+MODULE format2;
+
+FROM libc IMPORT exit, printf ;
+FROM Terminal IMPORT Write, WriteLn;
+FROM NumberIO IMPORT WriteCard;
+FROM DynamicStrings IMPORT String, Length, char, InitString;
+FROM FormatStrings IMPORT Sprintf1;
+
+PROCEDURE WriteString (s: String);
+VAR
+   l, i: CARDINAL;
+BEGIN
+   l := Length (s) ;
+   i := 0 ;
+   WHILE i < l DO
+      Write (char (s, i)) ;
+      INC (i)
+   END
+END WriteString;
+
+
+(*
+   assert -
+*)
+
+PROCEDURE assert (cond: BOOLEAN; line: CARDINAL; file: ARRAY OF CHAR) ;
+BEGIN
+   IF NOT cond
+   THEN
+      printf ("%s:%d assertion failed\n", file, line);
+      exit (1)
+   END
+END assert ;
+
+
+VAR
+   n: CARDINAL;
+   r, s: String;
+BEGIN
+   n := 2;
+   r := InitString("%u pieces of cake") ;
+   WriteString (r) ; WriteLn ;
+   assert (Length (r) = 17, __LINE__, __FILE__) ;
+   s := Sprintf1 (r, n) ;
+   WriteCard (Length (s), 4) ; WriteLn ;
+   assert (Length (s) = 16, __LINE__, __FILE__) ;
+
+   r := InitString("%d pieces of cake") ;
+   WriteString (r) ; WriteLn ;
+   assert (Length (r) = 17, __LINE__, __FILE__) ;
+   s := Sprintf1 (r, n) ;
+   WriteCard (Length (s), 4) ; WriteLn ;
+   assert (Length (s) = 16, __LINE__, __FILE__) ;
+
+   r := InitString("%x pieces of cake") ;
+   WriteString (r) ; WriteLn ;
+   assert (Length (r) = 17, __LINE__, __FILE__) ;
+   s := Sprintf1 (r, n) ;
+   WriteCard (Length (s), 4) ; WriteLn ;
+   assert (Length (s) = 16, __LINE__, __FILE__) ;
+
+   WriteString (InitString ('all tests pass')) ; WriteLn ;
+END format2.