[Pkg-cli-apps-commits] [fsharp] 28/71: Include fix for printf regression in open edition

Christopher Halse Rogers raof-guest at moszumanska.debian.org
Fri Jan 17 05:18:13 UTC 2014


This is an automated email from the git hooks/post-receive script.

raof-guest pushed a commit to tag 3.1.0
in repository fsharp.

commit 95a3fcce19b3a5eb85efe187a91b022679fd71a7
Author: Don Syme <donsyme at fastmail.fm>
Date:   Fri Nov 29 12:01:38 2013 +0000

    Include fix for printf regression in open edition
---
 src/all-vs2013.sln                |  67 +++++++++++++++++
 src/fsharp/FSharp.Core/printf.fs  | 154 ++++++++++++++++++++++++++++++--------
 tests/fsharp/core/printf/test.fsx |   2 -
 3 files changed, 188 insertions(+), 35 deletions(-)

diff --git a/src/all-vs2013.sln b/src/all-vs2013.sln
new file mode 100644
index 0000000..52b7480
--- /dev/null
+++ b/src/all-vs2013.sln
@@ -0,0 +1,67 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.21005.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D78E3B57-DAD1-4FE1-9DC8-84F7847B0C77}"
+	ProjectSection(SolutionItems) = preProject
+		fsharp-compiler-build.proj = fsharp-compiler-build.proj
+		fsharp-proto-build.proj = fsharp-proto-build.proj
+		root.traversal.targets = root.traversal.targets
+		source-build-version = source-build-version
+	EndProjectSection
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fsc", "fsharp\Fsc\Fsc.fsproj", "{C94C257C-3C0A-4858-B5D8-D746498D1F08}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler", "fsharp\FSharp.Compiler\FSharp.Compiler.fsproj", "{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Silverlight", "fsharp\FSharp.Compiler.Silverlight\FSharp.Compiler.Silverlight.fsproj", "{A90A57BE-C2BD-4CB9-87DC-C0D18820FF6B}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Core", "fsharp\FSharp.Core\FSharp.Core.fsproj", "{DED3BBD7-53F4-428A-8C9F-27968E768605}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Build", "fsharp\FSharp.Build\FSharp.Build.fsproj", "{702A7979-BCF9-4C41-853E-3ADFC9897890}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Unittests", "fsharp\unittests\Unittests.fsproj", "{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Fsi", "fsharp\fsi\Fsi.fsproj", "{D0E98C0D-490B-4C61-9329-0862F6E87645}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Interactive.Settings", "fsharp\FSharp.Compiler.Interactive.Settings\FSharp.Compiler.Interactive.Settings.fsproj", "{649FA588-F02E-457C-9FCF-87E46407481E}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Server.Shared", "fsharp\FSharp.Compiler.Server.Shared\FSharp.Compiler.Server.Shared.fsproj", "{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Core.Unittests", "fsharp\FSharp.Core.Unittests\FSharp.Core.Unittests.fsproj", "{88E2D422-6852-46E3-A740-83E391DC7973}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.ActiveCfg = Release|x86
+		{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|x86
+		{A90A57BE-C2BD-4CB9-87DC-C0D18820FF6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{A90A57BE-C2BD-4CB9-87DC-C0D18820FF6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.ActiveCfg = Release|x86
+		{702A7979-BCF9-4C41-853E-3ADFC9897890}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{702A7979-BCF9-4C41-853E-3ADFC9897890}.Release|Any CPU.ActiveCfg = Release|x86
+		{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{EE85AAB7-CDA0-4C4E-BDA0-A64DDDD13E3F}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D0E98C0D-490B-4C61-9329-0862F6E87645}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|Any CPU.ActiveCfg = Release|x86
+		{649FA588-F02E-457C-9FCF-87E46407481E}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{649FA588-F02E-457C-9FCF-87E46407481E}.Release|Any CPU.ActiveCfg = Release|x86
+		{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Release|Any CPU.ActiveCfg = Release|x86
+		{88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/src/fsharp/FSharp.Core/printf.fs b/src/fsharp/FSharp.Core/printf.fs
index 0f861df..4396858 100755
--- a/src/fsharp/FSharp.Core/printf.fs
+++ b/src/fsharp/FSharp.Core/printf.fs
@@ -116,19 +116,6 @@ module internal PrintfImpl =
                 else acc, i
             go 0 pos
 
-        let rec findNextFormatSpecifier (s : string)  i = 
-            if i >= s.Length then 
-                s.Length
-            else
-            let c = s.[i]
-            if c = '%' then
-                if i + 1 < s.Length then
-                    if s.[i + 1] = '%' then findNextFormatSpecifier s (i + 2)
-                    else i
-                else
-                    raise (ArgumentException("Missing format specifier"))
-            else findNextFormatSpecifier s (i + 1)
-
         let parseFlags (s : string) i : FormatFlags * int = 
             let rec go flags i = 
                 match s.[i] with
@@ -154,6 +141,32 @@ module internal PrintfImpl =
         let parseTypeChar (s : string) i : char * int = 
             s.[i], (i + 1)
     
+        let findNextFormatSpecifier (s : string) i = 
+            let rec go i (buf : Text.StringBuilder) =
+                if i >= s.Length then 
+                    s.Length, buf.ToString()
+                else
+                    let c = s.[i]
+                    if c = '%' then
+                        if i + 1 < s.Length then
+                            let _, i1 = parseFlags s (i + 1)
+                            let w, i2 = parseWidth s i1
+                            let p, i3 = parsePrecision s i2
+                            let typeChar, i4 = parseTypeChar s i3
+                            // shortcut for the simpliest case
+                            // if typeChar is not % or it has star as width\precision - resort to long path
+                            if typeChar = '%' && not (w = StarValue || p = StarValue) then 
+                                buf.Append('%') |> ignore
+                                go i4 buf
+                            else 
+                                i, buf.ToString()
+                        else
+                            raise (ArgumentException("Missing format specifier"))
+                    else 
+                        buf.Append(c) |> ignore
+                        go (i + 1) buf
+            go i (Text.StringBuilder())
+
     /// Abstracts generated printer from the details of particular environment: how to write text, how to produce results etc...
     [<AbstractClass>]
     type PrintfEnv<'State, 'Residue, 'Result> =
@@ -395,7 +408,19 @@ module internal PrintfImpl =
                     env.Write s2
                     env.Finalize()
                 )
+            )   
+       
+        static member PercentStarFinal1(s1 : string, s2 : string) = 
+            (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+                (fun (_star1 : int) -> 
+                    let env = env()
+                    env.Write s1
+                    env.Write("%")
+                    env.Write s2
+                    env.Finalize()
+                )
             )
+
         static member StarFinal2<'A>(s1 : string, conv, s2 : string) = 
             (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
                 (fun (star1 : int) (star2 : int) (a : 'A) -> 
@@ -407,6 +432,18 @@ module internal PrintfImpl =
                 )
             )
 
+       /// Handles case when '%*.*%' is used at the end of string
+        static member PercentStarFinal2(s1 : string, s2 : string) = 
+            (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+                (fun (_star1 : int) (_star2 : int) -> 
+                    let env = env()
+                    env.Write s1
+                    env.Write("%")
+                    env.Write s2
+                    env.Finalize()
+                )
+            )
+
         static member StarChained1<'A, 'Tail>(s1 : string, conv, next : PrintfFactory<'State, 'Residue, 'Result,'Tail>) = 
             (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
                 (fun (star1 : int) (a : 'A) -> 
@@ -418,6 +455,20 @@ module internal PrintfImpl =
                     next env : 'Tail
                 )
             )
+  
+        /// Handles case when '%*%' is used in the middle of the string so it needs to be chained to another printing block
+        static member PercentStarChained1<'Tail>(s1 : string, next : PrintfFactory<'State, 'Residue, 'Result,'Tail>) = 
+            (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+                (fun (_star1 : int) -> 
+                    let env() =
+                        let env = env()
+                        env.Write s1
+                        env.Write("%")
+                        env
+                    next env : 'Tail
+                )
+            )
+
         static member StarChained2<'A, 'Tail>(s1 : string, conv, next : PrintfFactory<'State, 'Residue, 'Result,'Tail>) = 
             (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
                 (fun (star1 : int) (star2 : int) (a : 'A) -> 
@@ -430,6 +481,19 @@ module internal PrintfImpl =
                 )
             )
     
+        /// Handles case when '%*.*%' is used in the middle of the string so it needs to be chained to another printing block
+        static member PercentStarChained2<'Tail>(s1 : string, next : PrintfFactory<'State, 'Residue, 'Result,'Tail>) = 
+            (fun (env : unit -> PrintfEnv<'State, 'Residue, 'Result>) ->
+                (fun (_star1 : int) (_star2 : int) -> 
+                    let env() =
+                        let env = env()
+                        env.Write s1
+                        env.Write("%")
+                        env
+                    next env : 'Tail
+                )
+            )
+    
     let inline (===) a b = Object.ReferenceEquals(a, b)
     let invariantCulture = System.Globalization.CultureInfo.InvariantCulture 
 
@@ -946,9 +1010,13 @@ module internal PrintfImpl =
     
         let mutable count = 0
 
-        let verifyMethodInfoWasTaken (mi : System.Reflection.MemberInfo) =
-            if mi = null then 
+        let verifyMethodInfoWasTaken (_mi : System.Reflection.MemberInfo) =
+#if DEBUG
+            if _mi = null then 
                 ignore (System.Diagnostics.Debugger.Launch())
+#else
+            ()
+#endif
             
         let buildSpecialChained(spec : FormatSpecifier, argTys : Type[], prefix : string, tail : obj, retTy) = 
             if spec.TypeChar = 'a' then
@@ -966,14 +1034,23 @@ module internal PrintfImpl =
             else
                 System.Diagnostics.Debug.Assert(spec.IsStarPrecision || spec.IsStarWidth , "spec.IsStarPrecision || spec.IsStarWidth ")
 
-                let n = if spec.IsStarWidth = spec.IsStarPrecision then 2 else 1
-                let argTy = argTys.[argTys.Length - 2]
+                let mi = 
+                    let n = if spec.IsStarWidth = spec.IsStarPrecision then 2 else 1
+                    let prefix = if spec.TypeChar = '%' then "PercentStarChained" else "StarChained"
+                    let name = prefix + (string n)
+                    typeof<Specializations<'S, 'Re, 'Res>>.GetMethod(name, NonPublicStatics)
 
-                let mi = typeof<Specializations<'S, 'Re, 'Res>>.GetMethod("StarChained" + (n.ToString()), NonPublicStatics)
                 verifyMethodInfoWasTaken mi
-                let mi = mi.MakeGenericMethod([| argTy;  retTy |])
-                let conv = getValueConverter argTy spec 
-                let args = [| box prefix; box conv; tail |]
+                
+                let argTypes, args =
+                    if spec.TypeChar = '%' then
+                        [| retTy |], [| box prefix; tail |]
+                    else
+                        let argTy = argTys.[argTys.Length - 2]
+                        let conv = getValueConverter argTy spec 
+                        [| argTy; retTy |], [| box prefix; box conv; tail |]
+
+                let mi = mi.MakeGenericMethod argTypes
                 mi.Invoke(null, args)
             
         let buildSpecialFinal(spec : FormatSpecifier, argTys : Type[], prefix : string, suffix : string) =
@@ -991,14 +1068,23 @@ module internal PrintfImpl =
             else
                 System.Diagnostics.Debug.Assert(spec.IsStarPrecision || spec.IsStarWidth , "spec.IsStarPrecision || spec.IsStarWidth ")
 
-                let n = if spec.IsStarWidth = spec.IsStarPrecision then 2 else 1
-                let argTy = argTys.[argTys.Length - 2]
+                let mi = 
+                    let n = if spec.IsStarWidth = spec.IsStarPrecision then 2 else 1
+                    let prefix = if spec.TypeChar = '%' then "PercentStarFinal" else "StarFinal"
+                    let name = prefix + (string n)
+                    typeof<Specializations<'S, 'Re, 'Res>>.GetMethod(name, NonPublicStatics)
 
-                let mi = typeof<Specializations<'S, 'Re, 'Res>>.GetMethod("StarFinal" + (n.ToString()), NonPublicStatics)
                 verifyMethodInfoWasTaken mi
-                let mi = mi.MakeGenericMethod(argTy)
-                let conv = getValueConverter argTy spec 
-                let args = [| box prefix; box conv; box suffix  |]
+
+                let mi, args = 
+                    if spec.TypeChar = '%' then 
+                        mi, [| box prefix; box suffix  |]
+                    else
+                        let argTy = argTys.[argTys.Length - 2]
+                        let mi = mi.MakeGenericMethod(argTy)
+                        let conv = getValueConverter argTy spec 
+                        mi, [| box prefix; box conv; box suffix  |]
+
                 mi.Invoke(null, args)
 
         let buildPlainFinal(args : obj[], argTypes : Type[]) = 
@@ -1050,9 +1136,7 @@ module internal PrintfImpl =
             let typeChar, i = FormatString.parseTypeChar s i
             let spec = { TypeChar = typeChar; Precision = precision; Flags = flags; Width = width}
             
-            let next = FormatString.findNextFormatSpecifier s i
-            let suffix = s.Substring(i, next - i)
-
+            let next, suffix = FormatString.findNextFormatSpecifier s i
             let argTys = 
                 let n = 
                     if spec.TypeChar = 'a' then 2 
@@ -1060,6 +1144,11 @@ module internal PrintfImpl =
                         if spec.IsStarWidth = spec.IsStarPrecision then 3 
                         else 2
                     else 1
+
+                let n = if spec.TypeChar = '%' then n - 1 else n
+                
+                System.Diagnostics.Debug.Assert(n <> 0, "n <> 0")
+
                 extractCurriedArguments funcTy n
 
             let retTy = argTys.[argTys.Length - 1]
@@ -1127,15 +1216,14 @@ module internal PrintfImpl =
                         numberOfArgs + 1
 
         let parseFormatString (s : string) (funcTy : System.Type) : obj = 
-            let prefixPos = FormatString.findNextFormatSpecifier s 0
+            let prefixPos, prefix = FormatString.findNextFormatSpecifier s 0
             if prefixPos = s.Length then 
                 box (fun (env : unit -> PrintfEnv<'S, 'Re, 'Res>) -> 
                     let env = env()
-                    env.Write s
+                    env.Write prefix
                     env.Finalize()
                     )
             else
-                let prefix = if prefixPos = 0 then "" else s.Substring(0, prefixPos)
                 let n = parseFromFormatSpecifier prefix s funcTy prefixPos
                 
                 if n = ContinuationOnStack || n = 0 then
diff --git a/tests/fsharp/core/printf/test.fsx b/tests/fsharp/core/printf/test.fsx
index e5bc57e..15624ae 100644
--- a/tests/fsharp/core/printf/test.fsx
+++ b/tests/fsharp/core/printf/test.fsx
@@ -46,7 +46,6 @@ let verify actual expected = test expected actual expected
 
 let adjust1 obj n1 = unbox ((unbox obj) n1)
 
-(*
 let _ = test "percent00" (lazy(sprintf "%%")) "%"
 let _ = test "percent01" (lazy(sprintf " %%%% ")) " %% "
 let _ = test "percent02" (lazy(sprintf "%.2f%.2%" 2.)) "2.00%"
@@ -58,7 +57,6 @@ let _ = test "percent07" (lazy(sprintf "%-+.*%%*d%*.*%" 55 0 8 77 88)) "%8%"
 let _ = test "percent08" (lazy(sprintf "%%d")) "%d"
 let _ = test "percent09" (lazy(sprintf "% *% %d" 10 6)) "% 6"
 
-*)
 
 let _ = test "cewoui2a" (lazy(sprintf "%o" 0)) "0"
 let _ = test "cewoui2b" (lazy(sprintf "%o" 0)) "0"

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-cli-apps/packages/fsharp.git



More information about the Pkg-cli-apps-commits mailing list