System.Data.SQLite
Check-in [d1fe039ff7]
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge updates from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | delegateFunction
Files: files | file ages | folders
SHA1: d1fe039ff718884e23c568f0ae4e6634611ee3f3
User & Date: mistachkin 2015-08-15 17:12:56
Context
2015-08-15
21:57
Enhance the 'isBuildAvailable' routine in the test suite infrastructure to support architecture names in addition to platform names. check-in: e56653e255 user: mistachkin tags: delegateFunction
17:12
Merge updates from trunk. check-in: d1fe039ff7 user: mistachkin tags: delegateFunction
17:08
Coding style and comment tweaks. check-in: 5c8e02eb62 user: mistachkin tags: trunk
04:04
Remove incorrect comments. check-in: b33115baa1 user: mistachkin tags: delegateFunction
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Doc/Extra/Provider/version.html.

    44     44       <div id="mainBody">
    45     45       <h1 class="heading">Version History</h1>
    46     46       <p><b>1.0.98.0 - August XX, 2015 <font color="red">(release scheduled)</font></b></p>
    47     47       <ul>
    48     48         <li>Updated to <a href="https://www.sqlite.org/releaselog/3_8_11_1.html">SQLite 3.8.11.1</a>.</li>
    49     49         <li>Add full support for Visual Studio 2015 and the .NET Framework 4.6.</li>
    50     50         <li>Implement the Substring method for LINQ using the &quot;substr&quot; core SQL function.&nbsp;<b>** Potentially Incompatible Change **</b></li>
           51  +      <li>Prevent encrypted connections from being used with the connection pool. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/89d3a159f1">[89d3a159f1]</a>.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    51     52         <li>Honor the second argument to Math.Round when using LINQ.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    52     53         <li>Honor the pre-existing flags for connections during the Open method. Fix for <a href="https://system.data.sqlite.org/index.html/info/964063da16">[964063da16]</a>.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    53     54         <li>Remove errant semi-colons from the SQL used by LINQ to INSERT and then SELECT rows with composite primary keys. Fix for <a href="https://system.data.sqlite.org/index.html/info/9d353b0bd8">[9d353b0bd8]</a>.</li>
    54     55         <li>Change the base type for the SQLiteConnectionFlags enumeration to long integer.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    55     56         <li>Add extended return codes to the SQLiteErrorCode enumeration. Pursuant to <a href="https://system.data.sqlite.org/index.html/info/71bedaca19">[71bedaca19]</a>.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    56     57         <li>Improve exception handling in all native callbacks implemented in the SQLiteConnection class.</li>
    57     58         <li>Add Progress event and ProgressOps connection string property to enable raising progress events during long-running queries.</li>

Changes to Externals/Eagle/bin/Eagle.dll.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/EagleShell.exe.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/EagleShell32.exe.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/x64/Spilornis.dll.

cannot compute difference between binary files

Changes to Externals/Eagle/bin/x86/Spilornis.dll.

cannot compute difference between binary files

Changes to Externals/Eagle/lib/Eagle1.0/init.eagle.

  2033   2033         if {[llength $args] > 2} then {
  2034   2034           error "wrong # args: should be \"parray a ?pattern?\""
  2035   2035         }
  2036   2036   
  2037   2037         upvar 1 $a array
  2038   2038   
  2039   2039         if {![array exists array]} {
  2040         -        error "\"$a\" isn't an array"
         2040  +        error [appendArgs \" $a "\" isn't an array"]
  2041   2041         }
  2042   2042   
  2043   2043         set names [lsort [eval array names array $args]]
  2044   2044         set maxLength 0
  2045   2045   
  2046   2046         foreach name $names {
  2047   2047           set length [string length $name]
................................................................................
  2154   2154           # NOTE: Old style test, use [test1] command.
  2155   2155           #
  2156   2156           set command test1
  2157   2157         }
  2158   2158   
  2159   2159         return [uplevel 1 [list $command $name $description] $args]
  2160   2160       }
         2161  +
         2162  +    proc isObjectHandle { value } {
         2163  +      set pattern [string map [list \\ \\\\ \[ \\\[ \] \\\]] $value]
         2164  +      set objects [info objects $pattern]
         2165  +
         2166  +      if {[llength $objects] == 1 && [lindex $objects 0] eq $value} then {
         2167  +        return true
         2168  +      }
         2169  +
         2170  +      return false
         2171  +    }
         2172  +
         2173  +    proc isManagedType { name } {
         2174  +      if {[llength [info commands object]] > 0} then {
         2175  +        if {![isObjectHandle $name]} then {
         2176  +          if {[catch {
         2177  +            object members -matchnameonly -nameonly -pattern Equals $name
         2178  +          } result] == 0 && $result eq "Equals"} then {
         2179  +            return true
         2180  +          }
         2181  +        }
         2182  +      }
         2183  +
         2184  +      return false
         2185  +    }
         2186  +
         2187  +    proc canGetManagedType { name {varName ""} } {
         2188  +      if {[llength [info commands object]] > 0} then {
         2189  +        if {![isObjectHandle $name]} then {
         2190  +          set cultureInfo [object invoke Interpreter.GetActive CultureInfo]
         2191  +          set type null
         2192  +
         2193  +          set code [object invoke -create -alias -flags +NonPublic \
         2194  +              Value GetType "" $name null null None $cultureInfo type]
         2195  +
         2196  +          if {[$code ToString] eq "Ok"} then {
         2197  +            if {[string length $varName] > 0} then {
         2198  +              upvar 1 $varName typeName
         2199  +            }
         2200  +
         2201  +            set typeName [$type AssemblyQualifiedName]
         2202  +
         2203  +            if {[isManagedType $typeName]} then {
         2204  +              return true
         2205  +            }
         2206  +          }
         2207  +        }
         2208  +      }
         2209  +
         2210  +      return false
         2211  +    }
         2212  +
         2213  +    proc unknownObjectInvoke { level name args } {
         2214  +      #
         2215  +      # NOTE: This is an [unknown] procedure that attempts to lookup the
         2216  +      #       name as a CLR type and then attempts to use [object invoke]
         2217  +      #       with it, merging options and arguments as necessary.
         2218  +      #
         2219  +      if {[llength [info commands object]] > 0 && \
         2220  +          ([isManagedType $name] || [canGetManagedType $name name])} then {
         2221  +        #
         2222  +        # NOTE: Get possible options for the [object invoke] sub-command.
         2223  +        #
         2224  +        set options [object invoke Utility GetInvokeOptions Invoke]
         2225  +
         2226  +        #
         2227  +        # NOTE: Create argument list for the artificial [object invoke]
         2228  +        #       alias.  This always has two arguments.
         2229  +        #
         2230  +        set arguments1 [object create ArgumentList object invoke]
         2231  +
         2232  +        #
         2233  +        # NOTE: Create argument list for the entire command being handled.
         2234  +        #       There may be options right after the command name itself.
         2235  +        #
         2236  +        set arguments2 [eval \
         2237  +            object create ArgumentList [concat [list $name] $args]]
         2238  +
         2239  +        #
         2240  +        # NOTE: Setup output arguments needed for the MergeArguments method.
         2241  +        #
         2242  +        set arguments3 null; set error null
         2243  +
         2244  +        #
         2245  +        # NOTE: Attempt to merge the option and non-option arguments into a
         2246  +        #       single list of arguments.
         2247  +        #
         2248  +        set code [object invoke -alias -flags +NonPublic \
         2249  +            Interpreter.GetActive MergeArguments $options $arguments1 \
         2250  +            $arguments2 2 1 false false arguments3 error]
         2251  +
         2252  +        #
         2253  +        # NOTE: Was the argument merging process successful?
         2254  +        #
         2255  +        if {$code eq "Ok"} then {
         2256  +          #
         2257  +          # NOTE: Jump up from our call frame (and optionally that of our
         2258  +          #       caller) and attempt to invoke the specified static object
         2259  +          #       method with the final list of merged arguments.
         2260  +          #
         2261  +          return [uplevel [expr {$level + 1}] [$arguments3 ToString]]
         2262  +        } else {
         2263  +          #
         2264  +          # NOTE: Failed to merge the arguments, raise an error.
         2265  +          #
         2266  +          error [$error ToString]
         2267  +        }
         2268  +      }
         2269  +
         2270  +      continue; # NOTE: Not handled.
         2271  +    }
  2161   2272   
  2162   2273       proc unknown { name args } {
  2163   2274         #
  2164         -      # NOTE: This is a stub unknown procedure that simply produces an
  2165         -      #       appropriate error message.
         2275  +      # NOTE: This is an [unknown] procedure that normally produces an
         2276  +      #       appropriate error message; however, it can optionally try
         2277  +      #       to invoke a static object method.
  2166   2278         #
  2167   2279         # TODO: Add support for auto-loading packages here in the future?
  2168   2280         #
  2169         -      return -code error "invalid command name \"$name\""
         2281  +      if {[hasRuntimeOption unknownObjectInvoke] && \
         2282  +          [llength [info commands object]] > 0} then {
         2283  +        #
         2284  +        # NOTE: In the context of the caller, attempt to invoke a static
         2285  +        #       object method using the specified arguments (which may
         2286  +        #       contain variable names).
         2287  +        #
         2288  +        if {[catch {
         2289  +          eval unknownObjectInvoke 1 [list $name] $args
         2290  +        } result] == 0} then {
         2291  +          #
         2292  +          # NOTE: The static object method was invoked successfully.
         2293  +          #       Return its result.
         2294  +          #
         2295  +          return -code ok $result
         2296  +        } elseif {[string length $result] > 0} then {
         2297  +          #
         2298  +          # NOTE: Attempting to invoke the static object method raised
         2299  +          #       an error.  Re-raise it now.  If no error message was
         2300  +          #       provided, fallback on the default (below).
         2301  +          #
         2302  +          return -code error $result
         2303  +        }
         2304  +      }
         2305  +
         2306  +      return -code error [appendArgs "invalid command name \"" $name \"]
  2170   2307       }
  2171   2308   
  2172   2309       namespace eval ::tcl::tm {
  2173   2310         #
  2174   2311         # NOTE: Ideally, this procedure should be created in the "::tcl::tm"
  2175   2312         #       namespace.
  2176   2313         #
................................................................................
  2193   2330   
  2194   2331       proc tclLog { string } {
  2195   2332         #
  2196   2333         # NOTE: This should work properly in both Tcl and Eagle.
  2197   2334         #
  2198   2335         catch {puts stderr $string}
  2199   2336       }
         2337  +
         2338  +    proc makeProcedureFast { name fast } {
         2339  +      #
         2340  +      # NOTE: This should work properly in Eagle only.
         2341  +      #
         2342  +      catch {
         2343  +        uplevel 1 [list object invoke -flags +NonPublic \
         2344  +            Interpreter.GetActive MakeProcedureFast $name $fast]
         2345  +      }
         2346  +    }
  2200   2347   
  2201   2348       proc makeVariableFast { name fast } {
  2202   2349         #
  2203   2350         # NOTE: This should work properly in Eagle only.
  2204   2351         #
  2205   2352         catch {
  2206   2353           uplevel 1 [list object invoke -flags +NonPublic \
................................................................................
  2239   2386             }
  2240   2387           }
  2241   2388         }
  2242   2389   
  2243   2390         foreach dir [split [exec -unicode $::env(ComSpec) /u /c dir \
  2244   2391             /ahd /b [appendArgs \" [file nativename $pattern] \"]] \n] {
  2245   2392           set dir [string trim $dir]
         2393  +
         2394  +        if {[string length $dir] > 0} then {
         2395  +          set dir [getDirResultPath $pattern $dir]
         2396  +
         2397  +          if {[lsearch -variable -exact -nocase result $dir] == -1} then {
         2398  +            lappend result $dir
         2399  +          }
         2400  +        }
         2401  +      }
         2402  +
         2403  +      return $result
         2404  +    }
         2405  +
         2406  +    proc findDirectoriesRecursive { pattern } {
         2407  +      #
         2408  +      # NOTE: Block non-Windows platforms since this is Windows specific.
         2409  +      #
         2410  +      if {![isWindows]} then {
         2411  +        error "not supported on this operating system"
         2412  +      }
         2413  +
         2414  +      #
         2415  +      # NOTE: This should work properly in Eagle only.
         2416  +      #
         2417  +      set dir ""; set result [list]
         2418  +
         2419  +      #
         2420  +      # HACK: Optimize the variable access in this procedure to be
         2421  +      #       as fast as possible.
         2422  +      #
         2423  +      makeVariableFast dir true; makeVariableFast result true
         2424  +
         2425  +      foreach dir [split [exec -unicode $::env(ComSpec) /u /c dir \
         2426  +          /ad /s /b [appendArgs \" [file nativename $pattern] \"]] \n] {
         2427  +        set dir [string trim $dir]
         2428  +
         2429  +        if {[string length $dir] > 0} then {
         2430  +          set dir [getDirResultPath $pattern $dir]
         2431  +
         2432  +          if {[lsearch -variable -exact -nocase result $dir] == -1} then {
         2433  +            lappend result $dir
         2434  +          }
         2435  +        }
         2436  +      }
         2437  +
         2438  +      foreach dir [split [exec -unicode $::env(ComSpec) /u /c dir \
         2439  +          /ahd /s /b [appendArgs \" [file nativename $pattern] \"]] \n] {
         2440  +        set dir [string trim $dir]
  2246   2441   
  2247   2442           if {[string length $dir] > 0} then {
  2248   2443             set dir [getDirResultPath $pattern $dir]
  2249   2444   
  2250   2445             if {[lsearch -variable -exact -nocase result $dir] == -1} then {
  2251   2446               lappend result $dir
  2252   2447             }
................................................................................
  2393   2588             [file normalize $pattern]]
  2394   2589   
  2395   2590         eval lappend result [glob -nocomplain -types {d hidden} \
  2396   2591             [file normalize $pattern]]
  2397   2592   
  2398   2593         return $result
  2399   2594       }
         2595  +
         2596  +    proc findDirectoriesRecursive { pattern } {
         2597  +      #
         2598  +      # NOTE: Block non-Windows platforms since this is Windows specific.
         2599  +      #
         2600  +      if {![isWindows]} then {
         2601  +        error "not supported on this operating system"
         2602  +      }
         2603  +
         2604  +      #
         2605  +      # NOTE: This should work properly in Tcl only.
         2606  +      #
         2607  +      set result [list]
         2608  +
         2609  +      catch {
         2610  +        foreach dir [split [exec $::env(ComSpec) /c dir /ad /s /b \
         2611  +            [file nativename $pattern]] \n] {
         2612  +          set dir [string trim $dir]
         2613  +
         2614  +          if {[string length $dir] > 0} then {
         2615  +            set dir [getDirResultPath $pattern $dir]
         2616  +
         2617  +            #
         2618  +            # HACK: The -nocase option to [lsearch] is only available
         2619  +            #       starting with Tcl 8.5.
         2620  +            #
         2621  +            if {$::tcl_version >= 8.5} then {
         2622  +              if {[lsearch -exact -nocase $result $dir] == -1} then {
         2623  +                lappend result $dir
         2624  +              }
         2625  +            } else {
         2626  +              if {[lsearch -exact [string tolower $result] \
         2627  +                  [string tolower $dir]] == -1} then {
         2628  +                lappend result $dir
         2629  +              }
         2630  +            }
         2631  +          }
         2632  +        }
         2633  +      }
         2634  +
         2635  +      catch {
         2636  +        foreach dir [split [exec $::env(ComSpec) /c dir /ahd /s /b \
         2637  +            [file nativename $pattern]] \n] {
         2638  +          set dir [string trim $dir]
         2639  +
         2640  +          if {[string length $dir] > 0} then {
         2641  +            set dir [getDirResultPath $pattern $dir]
         2642  +
         2643  +            #
         2644  +            # HACK: The -nocase option to [lsearch] is only available
         2645  +            #       starting with Tcl 8.5.
         2646  +            #
         2647  +            if {$::tcl_version >= 8.5} then {
         2648  +              if {[lsearch -exact -nocase $result $dir] == -1} then {
         2649  +                lappend result $dir
         2650  +              }
         2651  +            } else {
         2652  +              if {[lsearch -exact [string tolower $result] \
         2653  +                  [string tolower $dir]] == -1} then {
         2654  +                lappend result $dir
         2655  +              }
         2656  +            }
         2657  +          }
         2658  +        }
         2659  +      }
         2660  +
         2661  +      return $result
         2662  +    }
  2400   2663   
  2401   2664       proc findFiles { pattern } {
  2402   2665         #
  2403   2666         # NOTE: This should work properly in Tcl only.
  2404   2667         #
  2405   2668         eval lappend result [glob -nocomplain -types {f} \
  2406   2669             [file normalize $pattern]]
................................................................................
  2428   2691           foreach fileName [split [exec $::env(ComSpec) /c dir /a-d /s /b \
  2429   2692               [file nativename $pattern]] \n] {
  2430   2693             set fileName [string trim $fileName]
  2431   2694   
  2432   2695             if {[string length $fileName] > 0} then {
  2433   2696               set fileName [getDirResultPath $pattern $fileName]
  2434   2697   
  2435         -            if {[lsearch -exact -nocase $result $fileName] == -1} then {
  2436         -              lappend result $fileName
         2698  +            #
         2699  +            # HACK: The -nocase option to [lsearch] is only available
         2700  +            #       starting with Tcl 8.5.
         2701  +            #
         2702  +            if {$::tcl_version >= 8.5} then {
         2703  +              if {[lsearch -exact -nocase $result $fileName] == -1} then {
         2704  +                lappend result $fileName
         2705  +              }
         2706  +            } else {
         2707  +              if {[lsearch -exact [string tolower $result] \
         2708  +                  [string tolower $fileName]] == -1} then {
         2709  +                lappend result $fileName
         2710  +              }
  2437   2711               }
  2438   2712             }
  2439   2713           }
  2440   2714         }
  2441   2715   
  2442   2716         catch {
  2443   2717           foreach fileName [split [exec $::env(ComSpec) /c dir /ah-d /s /b \
  2444   2718               [file nativename $pattern]] \n] {
  2445   2719             set fileName [string trim $fileName]
  2446   2720   
  2447   2721             if {[string length $fileName] > 0} then {
  2448   2722               set fileName [getDirResultPath $pattern $fileName]
  2449   2723   
  2450         -            if {[lsearch -exact -nocase $result $fileName] == -1} then {
  2451         -              lappend result $fileName
         2724  +            #
         2725  +            # HACK: The -nocase option to [lsearch] is only available
         2726  +            #       starting with Tcl 8.5.
         2727  +            #
         2728  +            if {$::tcl_version >= 8.5} then {
         2729  +              if {[lsearch -exact -nocase $result $fileName] == -1} then {
         2730  +                lappend result $fileName
         2731  +              }
         2732  +            } else {
         2733  +              if {[lsearch -exact [string tolower $result] \
         2734  +                  [string tolower $fileName]] == -1} then {
         2735  +                lappend result $fileName
         2736  +              }
  2452   2737               }
  2453   2738             }
  2454   2739           }
  2455   2740         }
  2456   2741   
  2457   2742         return $result
  2458   2743       }
................................................................................
  2510   2795           isSameFileName getEnvironmentVariable combineFlags getCompileInfo \
  2511   2796           getPlatformInfo getPluginPath appendArgs lappendArgs \
  2512   2797           getDictionaryValue getColumnValue getRowColumnValue tqputs tqlog \
  2513   2798           readFile readSharedFile writeFile appendFile appendLogFile \
  2514   2799           appendSharedFile appendSharedLogFile readAsciiFile writeAsciiFile \
  2515   2800           readUnicodeFile writeUnicodeFile getDirResultPath addToPath \
  2516   2801           removeFromPath execShell lshuffle ldifference filter map reduce \
  2517         -        getLengthModifier debug findDirectories findFiles findFilesRecursive \
  2518         -        exportAndImportPackageCommands] false false
         2802  +        getLengthModifier debug findDirectories findDirectoriesRecursive \
         2803  +        findFiles findFilesRecursive exportAndImportPackageCommands] false \
         2804  +        false
  2519   2805   
  2520   2806       ###########################################################################
  2521   2807       ############################## END Tcl ONLY ###############################
  2522   2808       ###########################################################################
  2523   2809     }
  2524   2810   
  2525   2811     #
  2526   2812     # NOTE: Provide the Eagle library package to the interpreter.
  2527   2813     #
  2528   2814     package provide Eagle.Library \
  2529   2815       [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
  2530   2816   }
  2531   2817   

Changes to Externals/Eagle/lib/Eagle1.0/shell.eagle.

    26     26       ###########################################################################
    27     27   
    28     28       #
    29     29       # NOTE: Commands specific to initializing the Eagle interactive shell
    30     30       #       environment should be placed here.
    31     31       #
    32     32       proc help { args } {
           33  +      host result Break [appendArgs \
           34  +          "\nFor interactive help please use: #help " $args \
           35  +          "\nFor commercial support, please use: #support\n"]
           36  +
           37  +      catch {
           38  +        object invoke Interpreter.GetActive Host.WriteLine \
           39  +            "\nPlease press any key to continue...\n"
           40  +
           41  +        set key null; object invoke Interpreter.GetActive \
           42  +            Host.ReadKey true key
           43  +      }
           44  +
    33     45         eval lappend command #help $args; debug icommand $command
    34         -      error "for interactive help please use: #help $args"
           46  +    }
           47  +
           48  +    proc #support {} {
           49  +      # <help>
           50  +      # Shows the requirements for obtaining commercial support and/or
           51  +      # redirects to the appropriate web site using the default browser.
           52  +      # </help>
           53  +
           54  +      if {[catch {
           55  +        package require Licensing.Enterprise
           56  +        set fileName(1) [certificate current]
           57  +
           58  +        if {[string length $fileName(1)] == 0} then {
           59  +          error "No certificate file is available."
           60  +        }
           61  +
           62  +        set certificate [certificate import -alias $fileName(1)]
           63  +
           64  +        if {[string length $certificate] == 0} then {
           65  +          error [appendArgs \
           66  +              "No certificate is available, current file \"" \
           67  +              $fileName(1) "\" could not be imported."]
           68  +        }
           69  +
           70  +        if {[catch {
           71  +          certificate flags -hasflags S -hasall -strict $certificate
           72  +        } error(2)]} then {
           73  +          error [appendArgs \
           74  +              "Support is not enabled for certificate \"" \
           75  +              [$certificate Id] " - " [$certificate EntityName] \
           76  +              "\", the original error message was: \{" $error(2) \
           77  +              \}.]
           78  +        }
           79  +
           80  +        set uri [$certificate -create -alias Support]
           81  +
           82  +        if {[string length $uri] == 0} then {
           83  +          error [appendArgs \
           84  +              "No support information found in certificate \"" \
           85  +              [$certificate Id] " - " [$certificate EntityName] \".]
           86  +        }
           87  +
           88  +        if {[$uri Scheme] ni [list http https]} then {
           89  +          error [appendArgs \
           90  +              "Support URI scheme \"" [$uri Scheme] \
           91  +              "\" in certificate \"" [$certificate Id] " - " \
           92  +              [$certificate EntityName] "\" is not supported, " \
           93  +              "must be \"http\" or \"https\"."]
           94  +        }
           95  +
           96  +        exec -shell [$uri ToString] &
           97  +      } error(1)]} then {
           98  +        set fileName(2) [file tempname]; set fileData ""
           99  +
          100  +        foreach varName [lsort [info vars]] {
          101  +          if {$varName in [list fileData]} then {
          102  +            continue
          103  +          }
          104  +
          105  +          if {$varName eq "certificate" && \
          106  +              [string length $certificate] > 0} then {
          107  +            append fileData [appendArgs \n \
          108  +                [list array set certificate \
          109  +                [$certificate -flags +NonPublic \
          110  +                ToDictionary.KeysAndValuesToString \
          111  +                null false]]]
          112  +
          113  +            continue
          114  +          }
          115  +
          116  +          if {[array exists $varName]} then {
          117  +            append fileData [appendArgs \n \
          118  +                [list array set $varName [array get $varName]]]
          119  +          } else {
          120  +            append fileData [appendArgs \n \
          121  +                [list set $varName [set $varName]]]
          122  +          }
          123  +        }
          124  +
          125  +        append fileData \n; writeFile $fileName(2) $fileData
          126  +        set ::eagle_shell(errorFileName) $fileName(2)
          127  +
          128  +        error [appendArgs \
          129  +            "\n\nIn order to obtain commercial support, at least " \
          130  +            "one of the\nfollowing requirements must be met:\n\n" \
          131  +            "\t1. Valid, non-expired commercial license agreement\n" \
          132  +            "\t   for Eagle Enterprise Edition.\n\n" \
          133  +            "\t2. Valid, non-expired commercial support contract\n" \
          134  +            "\t   for Eagle Standard Edition.\n\n" \
          135  +            "The original error information was saved to the file:\n\n" \
          136  +            [string repeat - 60] \n $fileName(2) \n [string repeat - 60] \
          137  +            "\n\nPlease provide this file when contacting support."]
          138  +      }
    35    139       }
    36    140   
    37    141       ###########################################################################
    38    142       ############################# END Eagle ONLY ##############################
    39    143       ###########################################################################
    40    144     } else {
    41    145       ###########################################################################

Changes to Externals/Eagle/lib/Eagle1.0/test.eagle.

   233    233       }
   234    234     }
   235    235   
   236    236     proc testArrayGet { varName {integer false} } {
   237    237       #
   238    238       # NOTE: Returns the results of [array get] in a well-defined order.
   239    239       #
          240  +    if {[string length $varName] == 0} then {
          241  +      return [list]
          242  +    }
          243  +
   240    244       upvar 1 $varName array
   241    245   
   242    246       #
   243    247       # NOTE: Build the command that will sort the array names into order.
   244    248       #
   245    249       set command [list lsort]
   246    250       if {$integer} then {lappend command -integer}
................................................................................
   477    481           tputs $::test_channel [appendArgs \
   478    482               "---- skipped " $type " file: \"" $fileName \
   479    483               "\", it does not exist\n"]
   480    484         }
   481    485       }
   482    486     }
   483    487   
   484         -  proc processTestArguments { varName args } {
          488  +  proc processTestArguments { varName strict args } {
          489  +    #
          490  +    # NOTE: Initially, there are no unknown (i.e. unprocessed) arguments.
          491  +    #
          492  +    set result [list]
          493  +
   485    494       #
   486    495       # NOTE: We are going to place the configured options in the variable
   487    496       #       identified by the name provided by the caller.
   488    497       #
   489         -    upvar 1 $varName array
          498  +    if {[string length $varName] > 0} then {
          499  +      upvar 1 $varName array
          500  +    }
   490    501   
   491    502       #
   492         -    # TODO: Add more support for standard tcltest options here.
          503  +    # TODO: Add more support for standard "tcltest" options here.
   493    504       #
   494    505       set options [list \
   495         -        -breakOnLeak -configuration -constraints -exitOnComplete -file \
   496         -        -logFile -machine -match -no -notFile -platform -postTest -preTest \
   497         -        -postWait -preWait -randomOrder -skip -startFile -stopFile \
   498         -        -stopOnFailure -stopOnLeak -suffix -suite -tclsh -threshold]
          506  +        -breakOnLeak -configuration -constraints -exitOnComplete \
          507  +        -file -logFile -machine -match -no -notFile -platform \
          508  +        -postTest -preTest -postWait -preWait -randomOrder -skip \
          509  +        -startFile -stopFile -stopOnFailure -stopOnLeak -suffix \
          510  +        -suite -tclsh -threshold]
   499    511   
   500    512       set length [llength $args]
   501    513   
   502    514       for {set index 0} {$index < $length} {incr index} {
   503    515         #
   504    516         # NOTE: Grab the current list element, which should be the name of
   505    517         #       the test option.
................................................................................
   535    547           # NOTE: Is there another list element available for the value?  If
   536    548           #       not, it does not conform to the standard command line name
   537    549           #       and value pattern.
   538    550           #
   539    551           if {$index + 1 < $length} then {
   540    552             incr index; set value [lindex $args $index]
   541    553   
   542         -          tqputs $::test_channel [appendArgs \
   543         -              "---- unknown test option \"" $name "\" with value \"" \
   544         -              $value "\" ignored\n"]
          554  +          if {!$strict && [lsearch -exact $options $value] != -1} then {
          555  +            incr index -1; # HACK: Resynchronize with valid test option.
          556  +            lappend result [list $name]
          557  +
          558  +            tqputs $::test_channel [appendArgs \
          559  +                "---- no value for unknown test option \"" $name \
          560  +                "\", ignored, backing up one for test option \"" \
          561  +                $value \"...\n]
          562  +          } else {
          563  +            lappend result [list $name $value]
          564  +
          565  +            tqputs $::test_channel [appendArgs \
          566  +                "---- unknown test option \"" $name "\" with value \"" \
          567  +                $value "\", ignored\n"]
          568  +          }
   545    569           } else {
          570  +          lappend result [list $name]
          571  +
   546    572             tqputs $::test_channel [appendArgs \
   547    573                 "---- no value for unknown test option \"" $name \
   548         -              "\" ignored\n"]
          574  +              "\", ignored\n"]
   549    575           }
   550    576         } else {
   551    577           #
   552         -        # NOTE: This is not an option of *any* kind that we know about.
   553         -        #       Ignore it and issue a warning.
          578  +        # NOTE: Is there another list element available for the value?  If
          579  +        #       not, it does not conform to the standard command line name
          580  +        #       and value pattern.
   554    581           #
   555         -        tqputs $::test_channel [appendArgs \
   556         -            "---- unknown argument \"" $name "\" ignored\n"]
          582  +        if {$index + 1 < $length} then {
          583  +          incr index; set value [lindex $args $index]
          584  +
          585  +          if {!$strict && [lsearch -exact $options $value] != -1} then {
          586  +            incr index -1; # HACK: Resynchronize with valid test argument.
          587  +            lappend result [list $name]
          588  +
          589  +            tqputs $::test_channel [appendArgs \
          590  +                "---- no value for unknown argument \"" $name \
          591  +                "\", ignored, backing up one for test option \"" \
          592  +                $value \"...\n]
          593  +          } else {
          594  +            lappend result [list $name $value]
          595  +
          596  +            tqputs $::test_channel [appendArgs \
          597  +                "---- unknown argument \"" $name "\" with value \"" \
          598  +                $value "\", ignored\n"]
          599  +          }
          600  +        } else {
          601  +          #
          602  +          # NOTE: This is not an option of *any* kind that we know about.
          603  +          #       Ignore it and issue a warning.
          604  +          #
          605  +          lappend result [list $name]
          606  +
          607  +          tqputs $::test_channel [appendArgs \
          608  +              "---- unknown argument \"" $name "\", ignored\n"]
          609  +        }
   557    610         }
   558    611       }
   559    612   
   560    613       #
   561    614       # NOTE: Now, attempt to flush the test log queue, if available.
   562    615       #
   563    616       tlog ""
          617  +
          618  +    #
          619  +    # NOTE: Return the nested list of unknown arguments, formatted as
          620  +    #       name/value pairs, to the caller.
          621  +    #
          622  +    return $result
   564    623     }
   565    624   
   566    625     proc getTclShellFileName { automatic kits } {
   567    626       #
   568    627       # NOTE: Start out with an empty list of candiate Tcl shells.
   569    628       #
   570    629       set shells [list]
   571    630   
   572    631       #
   573    632       # NOTE: Check all environment variables we know about that
   574    633       #       may contain the path where the Tcl shell is located.
   575    634       #
   576         -    foreach name [list Eagle_Tcl_Shell Tcl_Shell] {
          635  +    foreach name [list Eagle_Tcl_Shell Tcl_Shell EAGLE_TCLSH TCLSH] {
   577    636         set value [getEnvironmentVariable $name]
   578    637   
   579    638         #
   580    639         # TODO: Possibly add a check if the file actually exists
   581    640         #       here.
   582    641         #
   583    642         if {[string length $value] > 0} then {
................................................................................
  1292   1351       if {![info exists ::no(epilogue.eagle)] && [info exists ::path]} then {
  1293   1352         unset ::path
  1294   1353       }
  1295   1354     }
  1296   1355   
  1297   1356     proc hookPuts {} {
  1298   1357       #
  1299         -    # NOTE: This code was stolen from tcltest and heavily modified to work
  1300         -    #       with Eagle.
         1358  +    # NOTE: This code was stolen from "tcltest" and heavily modified to
         1359  +    #       work with Eagle.
  1301   1360       #
  1302   1361       proc [namespace current]::testPuts { args } {
  1303   1362         switch [llength $args] {
  1304   1363           1 {
  1305   1364             #
  1306   1365             # NOTE: Only the string to be printed is specified (stdout).
  1307   1366             #
................................................................................
  2313   2372     proc isTestSuiteRunning {} {
  2314   2373       #
  2315   2374       # NOTE: Return non-zero if the test suite appears to be running.
  2316   2375       #
  2317   2376       return [expr {[info exists ::test_suite_running] && \
  2318   2377           $::test_suite_running}]
  2319   2378     }
         2379  +
         2380  +  proc getTestChannelOrDefault {} {
         2381  +    if {[info exists ::test_channel]} then {
         2382  +      return $::test_channel
         2383  +    }
         2384  +
         2385  +    return stdout; # TODO: Good default?
         2386  +  }
         2387  +
         2388  +  proc checkForAndSetTestPath { whatIf {quiet false} } {
         2389  +    #
         2390  +    # NOTE: Everything in this procedure requires access to the file system;
         2391  +    #       therefore, it cannot be used in a stock "safe" interpreter.
         2392  +    #
         2393  +    if {![interp issafe] && ![info exists ::test_path]} then {
         2394  +      #
         2395  +      # NOTE: Grab the name of the current script file.  If this is an empty
         2396  +      #       string, many test path checks will have to be skipped.
         2397  +      #
         2398  +      set script [info script]
         2399  +
         2400  +      #
         2401  +      # NOTE: Eagle and native Tcl have different requirements and possible
         2402  +      #       locations for the test path; therefore, handle them separately.
         2403  +      #
         2404  +      if {[isEagle]} then {
         2405  +        #
         2406  +        # NOTE: Grab the base directory and the library directory.  Without
         2407  +        #       these, several test path checks will be skipped.
         2408  +        #
         2409  +        set library [getTestLibraryDirectory]; set base [info base]
         2410  +
         2411  +        if {[string length $library] > 0} then {
         2412  +          #
         2413  +          # NOTE: Try the source release directory structure.  For this
         2414  +          #       case, the final test path would be:
         2415  +          #
         2416  +          #           $library/../../Library/Tests
         2417  +          #
         2418  +          set ::test_path [file normalize [file join [file dirname [file \
         2419  +              dirname $library]] Library Tests]]
         2420  +
         2421  +          if {!$quiet} then {
         2422  +            tqputs [getTestChannelOrDefault] [appendArgs \
         2423  +                "---- checking #1 for Eagle test path at \"" \
         2424  +                $::test_path \"...\n]
         2425  +          }
         2426  +        }
         2427  +
         2428  +        if {[string length $base] > 0 && ($whatIf || \
         2429  +            ![info exists ::test_path] || ![file exists $::test_path] || \
         2430  +            ![file isdirectory $::test_path])} then {
         2431  +          #
         2432  +          # NOTE: Try the source release directory structure again; this
         2433  +          #       time, assume only the embedded script library was used.
         2434  +          #       For this case, the final test path would be:
         2435  +          #
         2436  +          #           $base/Library/Tests
         2437  +          #
         2438  +          set ::test_path [file normalize [file join $base Library Tests]]
         2439  +
         2440  +          if {!$quiet} then {
         2441  +            tqputs [getTestChannelOrDefault] [appendArgs \
         2442  +                "---- checking #2 for Eagle test path at \"" \
         2443  +                $::test_path \"...\n]
         2444  +          }
         2445  +        }
         2446  +
         2447  +        if {[string length $script] > 0 && ($whatIf || \
         2448  +            ![info exists ::test_path] || ![file exists $::test_path] || \
         2449  +            ![file isdirectory $::test_path])} then {
         2450  +          #
         2451  +          # NOTE: Try for the test package directory.  For this case, the
         2452  +          #       final test path would be:
         2453  +          #
         2454  +          #           $script/../Test1.0
         2455  +          #
         2456  +          set ::test_path [file normalize [file join [file dirname [file \
         2457  +              dirname $script]] [appendArgs Test [info engine Version]]]]
         2458  +
         2459  +          if {!$quiet} then {
         2460  +            tqputs [getTestChannelOrDefault] [appendArgs \
         2461  +                "---- checking #3 for Eagle test path at \"" \
         2462  +                $::test_path \"...\n]
         2463  +          }
         2464  +        }
         2465  +
         2466  +        if {[string length $base] > 0 && ($whatIf || \
         2467  +            ![info exists ::test_path] || ![file exists $::test_path] || \
         2468  +            ![file isdirectory $::test_path])} then {
         2469  +          #
         2470  +          # NOTE: Try for the test package directory again; this time, use
         2471  +          #       the base path and assume the source release directory
         2472  +          #       structure.  For this case, the final test path would be:
         2473  +          #
         2474  +          #           $base/lib/Test1.0
         2475  +          #
         2476  +          set ::test_path [file normalize [file join $base lib [appendArgs \
         2477  +              Test [info engine Version]]]]
         2478  +
         2479  +          if {!$quiet} then {
         2480  +            tqputs [getTestChannelOrDefault] [appendArgs \
         2481  +                "---- checking #4 for Eagle test path at \"" \
         2482  +                $::test_path \"...\n]
         2483  +          }
         2484  +        }
         2485  +
         2486  +        if {[string length $base] > 0 && ($whatIf || \
         2487  +            ![info exists ::test_path] || ![file exists $::test_path] || \
         2488  +            ![file isdirectory $::test_path])} then {
         2489  +          #
         2490  +          # NOTE: Try for the test package directory again; this time, use
         2491  +          #       the base path.  For this case, the final test path would
         2492  +          #       be:
         2493  +          #
         2494  +          #           $base/Test1.0
         2495  +          #
         2496  +          set ::test_path [file normalize [file join $base [appendArgs \
         2497  +              Test [info engine Version]]]]
         2498  +
         2499  +          if {!$quiet} then {
         2500  +            tqputs [getTestChannelOrDefault] [appendArgs \
         2501  +                "---- checking #5 for Eagle test path at \"" \
         2502  +                $::test_path \"...\n]
         2503  +          }
         2504  +        }
         2505  +
         2506  +        if {[string length $library] > 0 && ($whatIf || \
         2507  +            ![info exists ::test_path] || ![file exists $::test_path] || \
         2508  +            ![file isdirectory $::test_path])} then {
         2509  +          #
         2510  +          # NOTE: This must be a binary release, no "Library" directory
         2511  +          #       then.  Also, binary releases have an upper-case "Tests"
         2512  +          #       directory name that originates from the "update.bat"
         2513  +          #       tool.  This must match the casing used in "update.bat".
         2514  +          #       For this case, the final test path would be:
         2515  +          #
         2516  +          #           $library/../../Tests
         2517  +          #
         2518  +          set ::test_path [file normalize [file join [file dirname [file \
         2519  +              dirname $library]] Tests]]
         2520  +
         2521  +          if {!$quiet} then {
         2522  +            tqputs [getTestChannelOrDefault] [appendArgs \
         2523  +                "---- checking #6 for Eagle test path at \"" \
         2524  +                $::test_path \"...\n]
         2525  +          }
         2526  +        }
         2527  +
         2528  +        if {[string length $base] > 0 && ($whatIf || \
         2529  +            ![info exists ::test_path] || ![file exists $::test_path] || \
         2530  +            ![file isdirectory $::test_path])} then {
         2531  +          #
         2532  +          # NOTE: Fallback to using the base directory and checking for a
         2533  +          #       "Tests" directory beneath it.  For this case, the final
         2534  +          #       test path would be:
         2535  +          #
         2536  +          #           $base/Tests
         2537  +          #
         2538  +          set ::test_path [file normalize [file join $base Tests]]
         2539  +
         2540  +          if {!$quiet} then {
         2541  +            tqputs [getTestChannelOrDefault] [appendArgs \
         2542  +                "---- checking #7 for Eagle test path at \"" \
         2543  +                $::test_path \"...\n]
         2544  +          }
         2545  +        }
         2546  +
         2547  +        if {!$quiet} then {
         2548  +          tqputs [getTestChannelOrDefault] [appendArgs \
         2549  +              "---- final Eagle test path is \"" \
         2550  +              [expr {[info exists ::test_path] ? \
         2551  +              $::test_path : "<none>"}] \"\n]
         2552  +        }
         2553  +      } else {
         2554  +        if {[string length $script] > 0} then {
         2555  +          #
         2556  +          # NOTE: Try the source release directory structure.  For this
         2557  +          #       case, the final test path would be:
         2558  +          #
         2559  +          #           $script/../../Library/Tests
         2560  +          #
         2561  +          set ::test_path [file normalize [file join [file dirname [file \
         2562  +              dirname [file dirname $script]]] Library Tests]]
         2563  +
         2564  +          if {!$quiet} then {
         2565  +            tqputs [getTestChannelOrDefault] [appendArgs \
         2566  +                "---- checking #1 for Tcl test path at \"" \
         2567  +                $::test_path \"...\n]
         2568  +          }
         2569  +        }
         2570  +
         2571  +        if {[string length $script] > 0 && ($whatIf || \
         2572  +            ![info exists ::test_path] || ![file exists $::test_path] || \
         2573  +            ![file isdirectory $::test_path])} then {
         2574  +          #
         2575  +          # NOTE: Try for the test package directory.  For this case, the
         2576  +          #       final test path would be:
         2577  +          #
         2578  +          #           $script/../Test1.0
         2579  +          #
         2580  +          set ::test_path [file normalize [file join [file dirname [file \
         2581  +              dirname $script]] Test1.0]]
         2582  +
         2583  +          if {!$quiet} then {
         2584  +            tqputs [getTestChannelOrDefault] [appendArgs \
         2585  +                "---- checking #2 for Tcl test path at \"" \
         2586  +                $::test_path \"...\n]
         2587  +          }
         2588  +        }
         2589  +
         2590  +        if {[string length $script] > 0 && ($whatIf || \
         2591  +            ![info exists ::test_path] || ![file exists $::test_path] || \
         2592  +            ![file isdirectory $::test_path])} then {
         2593  +          #
         2594  +          # NOTE: This must be a binary release, no "Library" directory
         2595  +          #       then.  Also, binary releases have an upper-case "Tests"
         2596  +          #       directory name that originates from the "update.bat"
         2597  +          #       tool.  This must match the casing used in "update.bat".
         2598  +          #       For this case, the final test path would be:
         2599  +          #
         2600  +          #           $script/../../Tests
         2601  +          #
         2602  +          set ::test_path [file normalize [file join [file dirname [file \
         2603  +              dirname [file dirname $script]]] Tests]]
         2604  +
         2605  +          if {!$quiet} then {
         2606  +            tqputs [getTestChannelOrDefault] [appendArgs \
         2607  +                "---- checking #3 for Tcl test path at \"" \
         2608  +                $::test_path \"...\n]
         2609  +          }
         2610  +        }
         2611  +
         2612  +        if {!$quiet} then {
         2613  +          tqputs [getTestChannelOrDefault] [appendArgs \
         2614  +              "---- final Tcl test path is \"" \
         2615  +              [expr {[info exists ::test_path] ? \
         2616  +              $::test_path : "<none>"}] \"\n]
         2617  +        }
         2618  +      }
         2619  +    }
         2620  +  }
  2320   2621   
  2321   2622     proc configureTcltest { match skip constraints imports force } {
         2623  +    #
         2624  +    # NOTE: Eagle and native Tcl have different configuration requirements
         2625  +    #       for the "tcltest" package.  For Eagle, the necessary testing
         2626  +    #       functionality is built-in.  In native Tcl, the package must be
         2627  +    #       loaded now and that cannot be done in a "safe" interpreter.
         2628  +    #
  2322   2629       if {[isEagle]} then {
  2323   2630         #
  2324   2631         # HACK: Flag the "test" and "runTest" script library procedures so
  2325   2632         #       that they use the script location of their caller and not
  2326   2633         #       their own.
  2327   2634         #
  2328   2635         # BUGBUG: Even this does not yet fix the script location issues in
................................................................................
  2333   2640         #
  2334   2641         # NOTE: Setup the necessary compatibility shims for the test suite.
  2335   2642         #
  2336   2643         namespace eval ::tcltest {}; # HACK: Force namespace creation now.
  2337   2644         setupTestShims true [expr {![isTestSuiteRunning]}]
  2338   2645   
  2339   2646         #
  2340         -      # NOTE: Fake having the tcltest package.
         2647  +      # NOTE: Fake having the package as the functionality is built-in.
  2341   2648         #
  2342   2649         package provide tcltest 2.2.10; # Tcl 8.4
  2343         -    } else {
         2650  +    } elseif {![interp issafe]} then {
  2344   2651         #
  2345         -      # NOTE: Attempt to detect if the tcltest package is already loaded.
         2652  +      # NOTE: Attempt to detect if the package is already loaded.
  2346   2653         #
  2347   2654         set loaded [expr {[catch {package present tcltest}] == 0}]
  2348   2655   
  2349   2656         #
  2350         -      # NOTE: Always attempt to load the tcltest package.
         2657  +      # NOTE: Always attempt to load the package.
  2351   2658         #
  2352   2659         package require tcltest
  2353   2660   
  2354   2661         #
  2355         -      # NOTE: Configure tcltest for our use (only when it was not loaded).
         2662  +      # NOTE: Configure it for our use (only when it was not loaded).
  2356   2663         #
  2357   2664         if {!$loaded} then {
  2358   2665           ::tcltest::configure -verbose bpste
  2359   2666         }
  2360   2667   
  2361   2668         #
  2362   2669         # NOTE: We need to copy the Eagle test names to match over to Tcl.
................................................................................
  2527   2834   
  2528   2835           if {[info exists test_flags(-constraints)]} then {
  2529   2836               eval lappend eagle_tests(Constraints) $test_flags(-constraints)
  2530   2837           }
  2531   2838         }
  2532   2839       }
  2533   2840   
  2534         -    proc getTestChannelOrDefault {} {
  2535         -      if {[info exists ::test_channel]} then {
  2536         -        return $::test_channel
  2537         -      }
  2538         -
  2539         -      return stdout; # TODO: Good default?
  2540         -    }
  2541         -
  2542   2841       proc setupTestShims { setup {quiet false} } {
  2543   2842         if {$setup} then {
  2544   2843           #
  2545   2844           # HACK: Compatibility shim(s) for use with various tests in the Tcl
  2546   2845           #       test suite.  Make sure these commands do not already exist
  2547   2846           #       prior to attempt to adding them.
  2548   2847           #
................................................................................
  3088   3387         object unimport -importpattern System.Windows.Forms.Layout
  3089   3388         object unimport -importpattern System.Windows.Forms.PropertyGridInternal
  3090   3389         object unimport -importpattern System.Windows.Forms.VisualStyles
  3091   3390       }
  3092   3391   
  3093   3392       proc getTestLibraryDirectory {} {
  3094   3393         #
  3095         -      # NOTE: First, query the location of the script library.
  3096         -      #
  3097         -      set result [info library]
  3098         -
         3394  +      # NOTE: First, query the location of the script library.  This will
         3395  +      #       not work right in a "safe" interpreter.
  3099   3396         #
  3100         -      # NOTE: Next, If the script library is embedded within the core
  3101         -      #       library itself (i.e. the script library location refers
  3102         -      #       to a file, not a directory), strip off the file name.
  3103         -      #
  3104         -      if {[file exists $result] && [file isfile $result]} then {
  3105         -        set result [file dirname $result]
         3397  +      if {[catch {info library} result] == 0} then {
         3398  +        #
         3399  +        # NOTE: Next, If the script library is embedded within the core
         3400  +        #       library itself (i.e. the script library location refers
         3401  +        #       to a file, not a directory), strip off the file name.
         3402  +        #
         3403  +        if {[file exists $result] && [file isfile $result]} then {
         3404  +          set result [file dirname $result]
         3405  +        }
         3406  +
         3407  +        #
         3408  +        # NOTE: Finally, return the resulting script library directory.
         3409  +        #
         3410  +        return $result
  3106   3411         }
  3107   3412   
  3108         -      #
  3109         -      # NOTE: Finally, return the resulting script library directory.
  3110         -      #
  3111         -      return $result
         3413  +      return ""
  3112   3414       }
  3113   3415   
  3114   3416       #
  3115         -    # NOTE: Setup the test path relative to the library path.
         3417  +    # NOTE: Check for the test path in the various well-known locations
         3418  +    #       and set the associated variable.
  3116   3419       #
  3117         -    if {![interp issafe] && ![info exists ::test_path]} then {
  3118         -      #
  3119         -      # NOTE: Try the source release directory structure.  For this case,
  3120         -      #       the final test path would be:
  3121         -      #
  3122         -      #           $library/../../Library/Tests
  3123         -      #
  3124         -      set ::test_path [file join [file normalize [file dirname \
  3125         -          [file dirname [getTestLibraryDirectory]]]] Library Tests]
  3126         -
  3127         -      if {![file exists $::test_path] || \
  3128         -          ![file isdirectory $::test_path]} then {
  3129         -        #
  3130         -        # NOTE: Try the source release directory structure again; this time,
  3131         -        #       assume only the embedded script library was used.  For this
  3132         -        #       case, the final test path would be:
  3133         -        #
  3134         -        #           $base/Library/Tests
  3135         -        #
  3136         -        set ::test_path [file join [info base] Library Tests]
  3137         -      }
  3138         -
  3139         -      if {![file exists $::test_path] || \
  3140         -          ![file isdirectory $::test_path]} then {
  3141         -        #
  3142         -        # NOTE: Try for the test package directory.  For this case, the final
  3143         -        #       test path would be:
  3144         -        #
  3145         -        #           $script/../Test1.0
  3146         -        #
  3147         -        set ::test_path [file join [file normalize [file dirname \
  3148         -            [file dirname [info script]]]] [appendArgs Test \
  3149         -            [info engine Version]]]
  3150         -      }
  3151         -
  3152         -      if {![file exists $::test_path] || \
  3153         -          ![file isdirectory $::test_path]} then {
  3154         -        #
  3155         -        # NOTE: Try for the test package directory again; this time, use the
  3156         -        #       base path and assume the source release directory structure.
  3157         -        #       For this case, the final test path would be:
  3158         -        #
  3159         -        #           $base/lib/Test1.0
  3160         -        #
  3161         -        set ::test_path [file join [info base] lib [appendArgs Test \
  3162         -            [info engine Version]]]
  3163         -      }
  3164         -
  3165         -      if {![file exists $::test_path] || \
  3166         -          ![file isdirectory $::test_path]} then {
  3167         -        #
  3168         -        # NOTE: Try for the test package directory again; this time, use the
  3169         -        #       base path.  For this case, the final test path would be:
  3170         -        #
  3171         -        #           $base/Test1.0
  3172         -        #
  3173         -        set ::test_path [file join [info base] [appendArgs Test \
  3174         -            [info engine Version]]]
  3175         -      }
  3176         -
  3177         -      if {![file exists $::test_path] || \
  3178         -          ![file isdirectory $::test_path]} then {
  3179         -        #
  3180         -        # NOTE: This must be a binary release, no "Library" directory then.
  3181         -        #       Also, binary releases have an upper-case "Tests" directory
  3182         -        #       name that originates from the "update.bat" tool.  This must
  3183         -        #       match the casing used in "update.bat".  For this case, the
  3184         -        #       final test path would be:
  3185         -        #
  3186         -        #           $library/../../Tests
  3187         -        #
  3188         -        set ::test_path [file join [file normalize [file dirname \
  3189         -            [file dirname [getTestLibraryDirectory]]]] Tests]
  3190         -      }
  3191         -
  3192         -      if {![file exists $::test_path] || \
  3193         -          ![file isdirectory $::test_path]} then {
  3194         -        #
  3195         -        # NOTE: Fallback to using the base directory and checking for a
  3196         -        #       "Tests" directory beneath it.  For this case, the final
  3197         -        #       test path would be:
  3198         -        #
  3199         -        #           $base/Tests
  3200         -        #
  3201         -        set ::test_path [file join [info base] Tests]
  3202         -      }
         3420  +    if {![info exists ::no(checkForAndSetTestPath)]} then {
         3421  +      checkForAndSetTestPath false [expr {![isTestSuiteRunning]}]
  3203   3422       }
  3204   3423   
  3205   3424       #
  3206         -    # NOTE: Fake having the tcltest package unless we are prevented.
         3425  +    # NOTE: Fake loading and configuring the "tcltest" package unless we
         3426  +    #       are prevented.
  3207   3427       #
  3208   3428       if {![info exists ::no(configureTcltest)]} then {
  3209   3429         configureTcltest [list] [list] [list] [list] false
  3210   3430       }
  3211   3431   
  3212   3432       ###########################################################################
  3213   3433       ############################# END Eagle ONLY ##############################
................................................................................
  3235   3455               double($::tcltest::numTests(Total)))}]
  3236   3456         }
  3237   3457   
  3238   3458         return 0; # no tests were run, etc.
  3239   3459       }
  3240   3460   
  3241   3461       #
  3242         -    # NOTE: Setup the test path relative to the path of this file.
         3462  +    # NOTE: Check for the test path in the various well-known locations
         3463  +    #       and set the associated variable.
  3243   3464       #
  3244         -    if {![interp issafe] && ![info exists ::test_path]} then {
  3245         -      #
  3246         -      # NOTE: Try the source release directory structure.
  3247         -      #
  3248         -      set ::test_path [file join [file normalize [file dirname \
  3249         -          [file dirname [file dirname [info script]]]]] Library Tests]
  3250         -
  3251         -      if {![file exists $::test_path] || \
  3252         -          ![file isdirectory $::test_path]} then {
  3253         -        #
  3254         -        # NOTE: Try for the test package directory.
  3255         -        #
  3256         -        set ::test_path [file join [file normalize [file dirname \
  3257         -            [file dirname [info script]]]] Test1.0]
  3258         -      }
  3259         -
  3260         -      if {![file exists $::test_path] || \
  3261         -          ![file isdirectory $::test_path]} then {
  3262         -        #
  3263         -        # NOTE: This must be a binary release, no "Library" directory then.
  3264         -        #       Also, binary releases have an upper-case "Tests" directory
  3265         -        #       name that originates from the "update.bat" tool.  This must
  3266         -        #       match the casing used in "update.bat".
  3267         -        #
  3268         -        set ::test_path [file join [file normalize [file dirname \
  3269         -            [file dirname [file dirname [info script]]]]] Tests]
  3270         -      }
         3465  +    if {![info exists ::no(checkForAndSetTestPath)]} then {
         3466  +      checkForAndSetTestPath false [expr {![isTestSuiteRunning]}]
  3271   3467       }
  3272   3468   
  3273   3469       #
  3274         -    # NOTE: Load and configure the tcltest package unless we are prevented.
         3470  +    # NOTE: Load and configure the "tcltest" package unless we are prevented.
  3275   3471       #
  3276         -    if {![interp issafe] && ![info exists ::no(configureTcltest)]} then {
         3472  +    if {![info exists ::no(configureTcltest)]} then {
  3277   3473         configureTcltest [list] [list] [list] [list test testConstraint] false
  3278   3474       }
  3279   3475   
  3280   3476       #
  3281   3477       # NOTE: We need several of our test related commands in the global
  3282   3478       #       namespace as well.
  3283   3479       #
................................................................................
  3292   3488           getTestSuffix testExec testClrExec execTestShell isRandomOrder \
  3293   3489           isBreakOnLeak isStopOnFailure isStopOnLeak isExitOnComplete \
  3294   3490           returnInfoScript runTestPrologue runTestEpilogue hookPuts unhookPuts \
  3295   3491           runTest testDebugBreak testArrayGet testShim tsource \
  3296   3492           recordTestStatistics reportTestStatistics formatList formatListAsDict \
  3297   3493           pathToRegexp inverseLsearchGlob removePathFromFileNames formatDecimal \
  3298   3494           clearTestPercent reportTestPercent runAllTests isTestSuiteRunning \
  3299         -        configureTcltest machineToPlatform getPassPercentage \
  3300         -        getSkipPercentage] false false
         3495  +        getTestChannelOrDefault checkForAndSetTestPath configureTcltest \
         3496  +        machineToPlatform getPassPercentage getSkipPercentage] false false
  3301   3497   
  3302   3498       ###########################################################################
  3303   3499       ############################## END Tcl ONLY ###############################
  3304   3500       ###########################################################################
  3305   3501     }
  3306   3502   
  3307   3503     #
  3308   3504     # NOTE: Provide the Eagle test package to the interpreter.
  3309   3505     #
  3310   3506     package provide Eagle.Test \
  3311   3507       [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
  3312   3508   }
  3313   3509   

Changes to Externals/Eagle/lib/Test1.0/all.eagle.

    38     38   #
    39     39   #       When using the above code snippet, the following code snippet may also
    40     40   #       be used at the very end of the corresponding "all.eagle" file instead
    41     41   #       of evaluating the "epilogue.eagle" file directly:
    42     42   #
    43     43   #           runTestEpilogue
    44     44   #
           45  +if {![info exists test_all_path]} then {
           46  +  set test_all_path \
           47  +      [file normalize [file dirname [info script]]]
           48  +}
           49  +
    45     50   if {![info exists test_path]} then {
    46         -  set test_path [file normalize [file dirname [info script]]]
           51  +  set test_path [file normalize [file join \
           52  +      [file dirname [file dirname $test_all_path]] \
           53  +      Library Tests]]
    47     54   }
    48     55   
    49         -source [file join $test_path prologue.eagle]
           56  +source [file join $test_all_path prologue.eagle]
    50     57   
    51     58   set no(prologue.eagle) true
    52     59   set no(epilogue.eagle) true
    53     60   
    54     61   set test_time [time {
    55     62     runAllTests $test_channel $test_path \
    56     63         [getTestFiles [list $test_path] $test_flags(-file) \
    57     64             $test_flags(-notFile)] \
    58         -      [list [file tail [info script]] *.tcl pkgIndex.eagle \
    59         -          constraints.eagle epilogue.eagle prologue.eagle] \
           65  +      [list [file tail [info script]] *.tcl \
           66  +          epilogue.eagle prologue.eagle] \
    60     67         $test_flags(-startFile) $test_flags(-stopFile)
    61     68   }]
    62     69   
    63     70   tputs $test_channel [appendArgs "---- all tests completed in " $test_time \n]
    64     71   unset test_time
    65     72   
    66     73   unset no(epilogue.eagle)
    67     74   unset no(prologue.eagle)
    68     75   
    69     76   if {[array size no] == 0} then {unset no}
    70     77   
    71         -source [file join $test_path epilogue.eagle]
           78  +source [file join $test_all_path epilogue.eagle]

Changes to Externals/Eagle/lib/Test1.0/constraints.eagle.

    52     52       #
    53     53       # NOTE: This job of this procedure is to return the list of "known"
    54     54       #       versions of Mono supported by the test suite infrastructure.
    55     55       #
    56     56       return [list \
    57     57           [list 2 0] [list 2 2] [list 2 4] [list 2 6] [list 2 8] [list 2 10] \
    58     58           [list 2 11] [list 2 12] [list 3 0] [list 3 1] [list 3 2] [list 3 3] \
    59         -        [list 3 4] [list 3 5] [list 3 6] [list 3 8] [list 3 10] [list 3 12]]
           59  +        [list 3 4] [list 3 5] [list 3 6] [list 3 8] [list 3 10] [list 3 12] \
           60  +        [list 4 0]]
    60     61     }
    61     62   
    62     63     #
    63     64     # NOTE: This procedure was adapted from the one listed on the Tcl Wiki page
    64     65     #       at "http://wiki.tcl.tk/43".  It is only intended to be used on very
    65     66     #       small lists because of its heavy use of recursion and complexity on
    66     67     #       the order of O(N!).
................................................................................
    99    100   
   100    101       #
   101    102       # NOTE: If this Eagle version lacks [interp readylimit] -OR- it has
   102    103       #       the default value (i.e. it always fully checks readiness),
   103    104       #       return true.
   104    105       #
   105    106       return [expr {
   106         -      [catch {interp readylimit {}} readylimit] != 0 || $readylimit == 0
          107  +      [catch {interp readylimit {}} readylimit] || $readylimit == 0
   107    108       }]
   108    109     }
   109    110   
   110    111     #
   111    112     # NOTE: This procedure should return non-zero if the "whoami" command may
   112    113     #       be executed by the test suite infrastructure outside the context
   113    114     #       of any specific tests.
................................................................................
   311    312           # NOTE: If the test suite file exists, add it to the list of file
   312    313           #       names to process.
   313    314           #
   314    315           if {[file exists $fileName]} then {
   315    316             lappend fileNames $fileName
   316    317           }
   317    318         }
          319  +
          320  +      #
          321  +      # TODO: If additional test suite files are added within the base
          322  +      #       package path, add them here as well.
          323  +      #
          324  +      foreach fileNameOnly [list \
          325  +          all.eagle constraints.eagle epilogue.eagle pkgIndex.eagle \
          326  +          pkgIndex.tcl prologue.eagle] {
          327  +        #
          328  +        # NOTE: First, check if the file resides in the Eagle-specific
          329  +        #       package sub-directory.  Failing that, fallback to using
          330  +        #       the base package path itself.
          331  +        #
          332  +        set fileName [file join \
          333  +            $::test_package_path Test1.0 $fileNameOnly]
          334  +
          335  +        if {![file exists $fileName]} then {
          336  +          set fileName [file join $::test_package_path $fileNameOnly]
          337  +        }
          338  +
          339  +        #
          340  +        # NOTE: If the test suite file exists, add it to the list of file
          341  +        #       names to process.
          342  +        #
          343  +        if {[file exists $fileName]} then {
          344  +          lappend fileNames $fileName
          345  +        }
          346  +      }
   318    347       }
   319    348   
   320    349       #
   321    350       # NOTE: Check if the test package path is available.
   322    351       #
   323    352       if {[info exists ::test_path]} then {
   324    353         #
   325    354         # TODO: If additional test suite files are added within the test
   326    355         #       package path, add them here as well.
   327    356         #
   328         -      foreach fileNameOnly [list \
   329         -          all.eagle constraints.eagle epilogue.eagle pkgIndex.eagle \
   330         -          pkgIndex.tcl prologue.eagle] {
          357  +      foreach fileNameOnly [list all.eagle epilogue.eagle prologue.eagle] {
   331    358           #
   332    359           # NOTE: Check if the file resides in the test package directory.
   333    360           #
   334    361           set fileName [file join $::test_path $fileNameOnly]
   335    362   
   336    363           #
   337    364           # NOTE: If the test suite file exists, add it to the list of file
................................................................................
  1582   1609         addConstraint timeIntensive
  1583   1610   
  1584   1611         tputs $channel yes\n
  1585   1612       } else {
  1586   1613         tputs $channel no\n
  1587   1614       }
  1588   1615     }
         1616  +
         1617  +  proc checkForFullTest { channel } {
         1618  +    tputs $channel "---- checking for full testing... "
         1619  +
         1620  +    #
         1621  +    # NOTE: Are we allowed to do full testing (i.e. to run rarely
         1622  +    #       needed tests)?
         1623  +    #
         1624  +    if {![info exists ::no(fullTest)]} then {
         1625  +      addConstraint fullTest
         1626  +
         1627  +      tputs $channel yes\n
         1628  +    } else {
         1629  +      tputs $channel no\n
         1630  +    }
         1631  +  }
  1589   1632   
  1590   1633     proc checkForMemoryIntensive { channel } {
  1591   1634       tputs $channel "---- checking for memory intensive testing... "
  1592   1635   
  1593   1636       #
  1594   1637       # NOTE: Are we allowed to do memory intensive testing?
  1595   1638       #
................................................................................
  1945   1988           addConstraint strongName
  1946   1989   
  1947   1990           tputs $channel yes\n
  1948   1991         } else {
  1949   1992           tputs $channel no\n
  1950   1993         }
  1951   1994       }
         1995  +
         1996  +    proc checkForStrongNameKey { channel } {
         1997  +      tputs $channel "---- checking for strong name key... "
         1998  +
         1999  +      if {[catch {info engine PublicKeyToken} publicKeyToken] == 0 && \
         2000  +          [string length $publicKeyToken] > 0} then {
         2001  +        #
         2002  +        # NOTE: Add a test constraint for this specific strong name key.
         2003  +        #
         2004  +        addConstraint [appendArgs strongName. $publicKeyToken]
         2005  +
         2006  +        #
         2007  +        # NOTE: Show the strong name key that we found.
         2008  +        #
         2009  +        tputs $channel [appendArgs "yes (" $publicKeyToken ")\n"]
         2010  +
         2011  +        #
         2012  +        # BUGBUG: Tcl 8.4 does not seem to like this expression because it
         2013  +        #         contains the "ni" operator added in Tcl 8.5 (and Tcl 8.4
         2014  +        #         tries to compile it even though it will only be evaluated
         2015  +        #         in Eagle).
         2016  +        #
         2017  +        set expr {$publicKeyToken ni \
         2018  +            "29c6297630be05eb 1e22ec67879739a2 358030063a832bc3"}
         2019  +
         2020  +        if {[expr $expr]} then {
         2021  +          #
         2022  +          # NOTE: The Eagle core library is strong name signed with a key that
         2023  +          #       is not official.  This is also not an error, per se; however,
         2024  +          #       it may cause some tests to fail and it should be reported to
         2025  +          #       the user and noted in the test suite log file.
         2026  +          #
         2027  +          addConstraint strongName.unofficial
         2028  +
         2029  +          #
         2030  +          # NOTE: Unless forbidden, issue and log a warning.
         2031  +          #
         2032  +          if {![info exists no(warningForStrongNameKey)] && \
         2033  +              ![haveConstraint quiet]} then {
         2034  +            tputs $channel [appendArgs \
         2035  +                "==== WARNING: unofficial Eagle strong name signature " \
         2036  +                "detected: " $publicKeyToken \n]
         2037  +          }
         2038  +        } else {
         2039  +          #
         2040  +          # NOTE: Several tests require one of the official strong name keys to
         2041  +          #       be used in order for them to pass.
         2042  +          #
         2043  +          addConstraint strongName.official
         2044  +
         2045  +          tputs $channel [appendArgs \
         2046  +              "---- official Eagle strong name signature detected: " \
         2047  +              $publicKeyToken \n]
         2048  +        }
         2049  +      } else {
         2050  +        #
         2051  +        # NOTE: The Eagle core library is not signed with a strong name key.
         2052  +        #       This is not an error, per se; however, it may cause selected
         2053  +        #       tests to fail and it should be reported to the user and noted
         2054  +        #       in the test suite log file.
         2055  +        #
         2056  +        addConstraint strongName.none
         2057  +
         2058  +        #
         2059  +        # NOTE: Show that we did not find a strong name key.
         2060  +        #
         2061  +        tputs $channel no\n
         2062  +
         2063  +        #
         2064  +        # NOTE: Unless forbidden, issue and log a warning.
         2065  +        #
         2066  +        if {![info exists no(warningForStrongNameKey)] && \
         2067  +            ![haveConstraint quiet]} then {
         2068  +          tputs $channel \
         2069  +              "==== WARNING: no Eagle strong name signature detected...\n"
         2070  +        }
         2071  +      }
         2072  +    }
  1952   2073   
  1953   2074       proc checkForCertificate { channel } {
  1954   2075         tputs $channel "---- checking for certificate... "
  1955   2076   
  1956   2077         if {[catch {
  1957   2078           object invoke Interpreter.GetActive GetCertificate
  1958   2079         } certificate] == 0 && [string length $certificate] > 0} then {
................................................................................
  1963   2084           addConstraint certificate
  1964   2085   
  1965   2086           #
  1966   2087           # NOTE: Attempt to query the subject from the certificate.
  1967   2088           #
  1968   2089           if {[catch {
  1969   2090             object invoke $certificate Subject
  1970         -        } subject] != 0 || [string length $subject] == 0} then {
         2091  +        } subject] || [string length $subject] == 0} then {
  1971   2092             #
  1972   2093             # TODO: No certificate subject, better handling here?
  1973   2094             #
  1974   2095             set subject unknown
  1975   2096           }
  1976   2097   
  1977   2098           tputs $channel [appendArgs "yes (" $subject ")\n"]
................................................................................
  2065   2186         tputs $channel "---- checking for default application domain... "
  2066   2187   
  2067   2188         if {[catch {
  2068   2189           object invoke AppDomain CurrentDomain
  2069   2190         } appDomain] == 0 && [string length $appDomain] > 0} then {
  2070   2191           if {[catch {
  2071   2192             object invoke $appDomain IsDefaultAppDomain
  2072         -        } default] != 0 || [string length $default] == 0} then {
         2193  +        } default] || [string length $default] == 0} then {
  2073   2194             set default false
  2074   2195           }
  2075   2196   
  2076         -        if {[catch {object invoke $appDomain Id} id] != 0 || \
         2197  +        if {[catch {object invoke $appDomain Id} id] || \
  2077   2198               [string length $id] == 0} then {
  2078   2199             set id unknown
  2079   2200           }
  2080   2201   
  2081   2202           if {$default} then {
  2082   2203             addConstraint defaultAppDomain
  2083   2204   
................................................................................
  2372   2493   
  2373   2494           tputs $channel [appendArgs $result ", " $::tcl_platform(processBits) \
  2374   2495               -bit " " $::tcl_platform(machine) \n]
  2375   2496         } else {
  2376   2497           tputs $channel "no, unknown\n"
  2377   2498         }
  2378   2499       }
         2500  +
         2501  +    proc checkForTestCallStack { channel } {
         2502  +      tputs $channel "---- checking for test call stack... "
         2503  +
         2504  +      #
         2505  +      # NOTE: Search for a call frame with associated arguments.
         2506  +      #       At this point, there must be at least one such call
         2507  +      #       frame (this one).  Therefore, this loop will always
         2508  +      #       terminate.
         2509  +      #
         2510  +      set index 0; set arguments [list]
         2511  +      set script {info level [info level]}
         2512  +
         2513  +      while {1} {
         2514  +        set level [appendArgs ## $index]
         2515  +
         2516  +        if {[catch {uplevel $level $script} arguments] == 0} then {
         2517  +          break
         2518  +        }
         2519  +
         2520  +        incr index
         2521  +      }
         2522  +
         2523  +      #
         2524  +      # NOTE: Grab the command name from the arguments, if any.
         2525  +      #
         2526  +      set command [expr {
         2527  +        [llength $arguments] > 0 ? [lindex $arguments 0] : ""
         2528  +      }]
         2529  +
         2530  +      #
         2531  +      # HACK: Make sure the call stack does not end up confusing
         2532  +      #       the tests that rely on absolute call frames.
         2533  +      #
         2534  +      if {$command in [list checkForTestCallStack]} then {
         2535  +        addConstraint testCallStack
         2536  +
         2537  +        tputs $channel [appendArgs "yes (\"" $command "\")\n"]
         2538  +
         2539  +        #
         2540  +        # NOTE: We are done here, return now.
         2541  +        #
         2542  +        return
         2543  +      }
         2544  +
         2545  +      tputs $channel [appendArgs "no (\"" $command "\")\n"]
         2546  +    }
  2379   2547   
  2380   2548       proc checkForGarudaDll { channel } {
  2381   2549         #
  2382   2550         # NOTE: Skip automatic Tcl shell machine detection if we are not
  2383   2551         #       allowed to execute external commands.
  2384   2552         #
  2385   2553         if {[canExecTclShell]} then {
................................................................................
  3218   3386             return
  3219   3387           }
  3220   3388         }
  3221   3389   
  3222   3390         tputs $channel no\n
  3223   3391       }
  3224   3392   
  3225         -    proc checkForNetFx45 { channel } {
  3226         -      tputs $channel "---- checking for .NET Framework 4.5... "
         3393  +    proc getFrameworkSetup46Value {} {
         3394  +      #
         3395  +      # NOTE: Check if we are running on Windows 10 or later.
         3396  +      #
         3397  +      if {[isWindows] && $::tcl_platform(osVersion) >= 10.0} then {
         3398  +        #
         3399  +        # NOTE: We are running on Windows 10, return the special value.
         3400  +        #
         3401  +        return 393295
         3402  +      }
         3403  +
         3404  +      #
         3405  +      # NOTE: We are not running on Windows 10, return the normal value.
         3406  +      #
         3407  +      return 393297
         3408  +    }
         3409  +
         3410  +    proc checkForNetFx4x { channel } {
         3411  +      tputs $channel "---- checking for .NET Framework 4.x... "
  3227   3412   
  3228   3413         #
  3229   3414         # NOTE: Platform must be Windows for this constraint to even be
  3230   3415         #       checked (i.e. we require the registry).
  3231   3416         #
  3232   3417         if {[isWindows]} then {
  3233   3418           #
................................................................................
  3260   3445             #
  3261   3446             # NOTE: If the "release" value is greater than or equal to 378758
  3262   3447             #       (or 378675 for Windows 8.1), then the .NET Framework 4.5.1
  3263   3448             #       is installed.  However, if the "release" value is also
  3264   3449             #       greater than or equal to 379893, then the .NET Framework
  3265   3450             #       4.5.2 is installed, which is an in-place upgrade to 4.5.1
  3266   3451             #       (and 4.5).  If the "release" value is also greater than or
  3267         -          #       equal to 393246, then the .NET Framework 4.6 is installed,
  3268         -          #       which is an in-place upgrade to 4.5.x.
         3452  +          #       equal to 393297 (393295 on Windows 10), then the .NET
         3453  +          #       Framework 4.6 is installed, which is an in-place upgrade
         3454  +          #       to 4.5.x.
  3269   3455             #
  3270         -          # TODO: Change the value 393246 when the .NET Framework 4.6 goes
  3271         -          #       final.
  3272         -          #
  3273         -          if {$release >= 393246} then {
         3456  +          if {$release >= [getFrameworkSetup46Value]} then {
         3457  +            addConstraint dotNet451OrHigher
         3458  +            addConstraint dotNet452OrHigher
  3274   3459               addConstraint dotNet46
  3275   3460               addConstraint dotNet46OrHigher
  3276   3461   
  3277   3462               set version 4.6
  3278   3463             } elseif {$release >= 379893} then {
         3464  +            addConstraint dotNet451OrHigher
  3279   3465               addConstraint dotNet452
  3280   3466               addConstraint dotNet452OrHigher
  3281   3467   
  3282   3468               set version 4.5.2
  3283   3469             } elseif {$release >= 378675} then {
  3284   3470               addConstraint dotNet451
  3285   3471               addConstraint dotNet451OrHigher
................................................................................
  3520   3706           checkForGaruda checkForShell checkForDebug checkForTk checkForVersion \
  3521   3707           checkForCommand checkForNamespaces checkForTestExec \
  3522   3708           checkForTestMachine checkForTestPlatform checkForTestConfiguration \
  3523   3709           checkForTestSuffix checkForFile checkForPathFile checkForNativeCode \
  3524   3710           checkForTip127 checkForTip194 checkForTip207 checkForTip241 \
  3525   3711           checkForTip285 checkForTip405 checkForTip426 checkForTip429 \
  3526   3712           checkForTiming checkForPerformance checkForBigLists \
  3527         -        checkForTimeIntensive checkForMemoryIntensive checkForStackIntensive \
  3528         -        checkForInteractive checkForInteractiveCommand checkForUserInteraction \
  3529         -        checkForNetwork checkForCompileOption checkForKnownCompileOptions] \
  3530         -        false false
         3713  +        checkForTimeIntensive checkForFullTest checkForMemoryIntensive \
         3714  +        checkForStackIntensive checkForInteractive checkForInteractiveCommand \
         3715  +        checkForUserInteraction checkForNetwork checkForCompileOption \
         3716  +        checkForKnownCompileOptions] false false
  3531   3717   
  3532   3718       ###########################################################################
  3533   3719       ############################## END Tcl ONLY ###############################
  3534   3720       ###########################################################################
  3535   3721     }
  3536   3722   
  3537   3723     #
  3538   3724     # NOTE: Provide the Eagle test constraints package to the interpreter.
  3539   3725     #
  3540   3726     package provide Eagle.Test.Constraints \
  3541   3727       [expr {[isEagle] ? [info engine PatchLevel] : "1.0"}]
  3542   3728   }
  3543   3729   

Changes to Externals/Eagle/lib/Test1.0/epilogue.eagle.

    21     21   
    22     22     #
    23     23     # NOTE: Verify that the current call frame is correct and that the
    24     24     #       interpreter call stack has not been imbalanced by previous
    25     25     #       tests or other errors.  This check only applies to Eagle.
    26     26     #
    27     27     if {[isEagle] && [llength [info commands object]] > 0} then {
    28         -    catch {
    29         -      #
    30         -      # NOTE: Check the name of the current call frame against the one
    31         -      #       that should be used for evaluating this script file.
    32         -      #
    33         -      if {[object invoke -flags +NonPublic \
    34         -              Interpreter.GetActive.CurrentFrame Name] ne \
    35         -          [list source [file normalize [info script]]]} then {
    36         -        unset -nocomplain test_suite_running
    37         -        error "cannot run, current frame is not for this script"
    38         -      }
           28  +    #
           29  +    # NOTE: Check the name of the current call frame against the one
           30  +    #       that should be used for evaluating this script file.
           31  +    #
           32  +    if {[object invoke -flags +NonPublic \
           33  +            Interpreter.GetActive.CurrentFrame Name] ne \
           34  +        [list source [file normalize [info script]]]} then {
           35  +      unset -nocomplain test_suite_running
           36  +      error "cannot run epilogue, current frame not for this script"
    39     37       }
    40     38     }
    41     39   
    42     40     #
    43     41     # NOTE: Make sure all the variables used by this epilogue are unset.
    44     42     #
    45     43     unset -nocomplain memory stack name count passedOrSkipped percent \

Changes to Externals/Eagle/lib/Test1.0/prologue.eagle.

    19     19       error "cannot run, current level is not global"
    20     20     }
    21     21   
    22     22     #
    23     23     # NOTE: Make sure all the variables used by this prologue are unset.
    24     24     #
    25     25     unset -nocomplain pkg_dir pattern dummy directory name value exec encoding \
    26         -      host memory stack drive publicKeyToken expr server database timeout \
    27         -      user password percent checkout timeStamp loaded
           26  +      host memory stack drive server database timeout user password percent \
           27  +      checkout timeStamp loaded
    28     28   
    29     29     #
    30     30     # NOTE: Indicate that the test suite is currently running.
    31     31     #
    32     32     if {![info exists test_suite_running] || !$test_suite_running} then {
    33     33       set test_suite_running true
    34     34     }
    35     35   
           36  +  #
           37  +  # NOTE: Set the location of the test suite package, if necessary.
           38  +  #
           39  +  if {![info exists test_all_path]} then {
           40  +    set test_all_path [file normalize [file dirname [info script]]]
           41  +  }
           42  +
    36     43     #
    37     44     # NOTE: Set the location of the test suite, if necessary.
    38     45     #
    39     46     if {![info exists test_path]} then {
    40         -    set test_path [file normalize [file dirname [info script]]]
           47  +    set test_path [file normalize [file join \
           48  +        [file dirname [file dirname $test_all_path]] Library Tests]]
    41     49     }
    42     50   
    43     51     #
    44     52     # NOTE: Set the location of the test suite data, if necessary.
    45     53     #
    46     54     if {![info exists test_data_path]} then {
    47     55       set test_data_path [file join $test_path data]
................................................................................
   177    185     # NOTE: Make sure our primary package path is part of the auto-path.
   178    186     #
   179    187     if {[lsearch -exact $auto_path $test_package_path] == -1} then {
   180    188       lappend auto_path $test_package_path
   181    189     }
   182    190   
   183    191     #
   184         -  # NOTE: Make sure our test package path is part of the auto-path.
          192  +  # NOTE: Make sure the test suite package is part of the auto-path.
          193  +  #
          194  +  if {[lsearch -exact $auto_path $test_all_path] == -1} then {
          195  +    lappend auto_path $test_all_path
          196  +  }
          197  +
          198  +  #
          199  +  # NOTE: Make sure the test suite is part of the auto-path.  This is
          200  +  #       now done for legacy compatibility only.
   185    201     #
   186    202     if {[lsearch -exact $auto_path $test_path] == -1} then {
   187    203       lappend auto_path $test_path
   188    204     }
   189    205   
   190    206     #############################################################################
   191    207   
................................................................................
   216    232     #
   217    233     # NOTE: Verify that the current call frame is correct and that the
   218    234     #       interpreter call stack has not been imbalanced by previous
   219    235     #       tests or other errors.  This check only applies to Eagle.
   220    236     #       This block requires the "Eagle.Library" package.
   221    237     #
   222    238     if {[isEagle] && [llength [info commands object]] > 0} then {
   223         -    catch {
   224         -      #
   225         -      # NOTE: Check the name of the current call frame against the one
   226         -      #       that should be used for evaluating this script file.
   227         -      #
   228         -      if {[object invoke -flags +NonPublic \
   229         -              Interpreter.GetActive.CurrentFrame Name] ne \
   230         -          [list source [file normalize [info script]]]} then {
   231         -        unset -nocomplain test_suite_running
   232         -        error "cannot run, current frame is not for this script"
   233         -      }
          239  +    #
          240  +    # NOTE: Check the name of the current call frame against the one
          241  +    #       that should be used for evaluating this script file.
          242  +    #
          243  +    if {[object invoke -flags +NonPublic \
          244  +            Interpreter.GetActive.CurrentFrame Name] ne \
          245  +        [list source [file normalize [info script]]]} then {
          246  +      unset -nocomplain test_suite_running
          247  +      error "cannot run prologue, current frame not for this script"
   234    248       }
   235    249     }
   236    250   
   237    251     #############################################################################
   238    252   
   239    253     #
   240    254     # NOTE: Set the local root directory of the source checkout (i.e. of Eagle
................................................................................
   305    319     set test_flags(-stopOnLeak) ""; # default to continue on leak.
   306    320     set test_flags(-exitOnComplete) ""; # default to not exit after complete.
   307    321     set test_flags(-preTest) ""; # default to not evaluating anything.
   308    322     set test_flags(-postTest) ""; # default to not evaluating anything.
   309    323     set test_flags(-preWait) ""; # default to not waiting.
   310    324     set test_flags(-postWait) ""; # default to not waiting.
   311    325     set test_flags(-tclsh) ""; # Tcl shell, default to empty.
          326  +  set test_flags(-bad) [list]; # these are the unrecognized arguments.
          327  +  set test_flags(-no) [list]; # default to not having any restrictions.
   312    328   
   313    329     #
   314    330     # NOTE: Check for and process any command line arguments.
   315    331     #
   316    332     if {[info exists argv]} then {
   317         -    eval processTestArguments test_flags $argv
          333  +    set test_flags(-bad) [eval processTestArguments test_flags false $argv]
   318    334   
   319    335       if {[info exists test_flags(-no)] && \
   320    336           [string length $test_flags(-no)] > 0} then {
   321    337         #
   322    338         # NOTE: Set the test run restrictions based on the provided command line
   323    339         #       argument value (which is assumed to be a "dictionary-style" list
   324    340         #       containing name/value pairs to add to the global "no" array).
................................................................................
   728    744   
   729    745     tputs $test_channel [appendArgs "---- executable: \"" \
   730    746         $bin_file \"\n]
   731    747   
   732    748     tputs $test_channel [appendArgs "---- command line: " \
   733    749         [expr {[info exists argv] && [string length $argv] > 0 ? \
   734    750             $argv : "<none>"}] \n]
          751  +
          752  +  tputs $test_channel [appendArgs "---- unrecognized arguments: " \
          753  +      [expr {[info exists test_flags(-bad)] && \
          754  +          [string length $test_flags(-bad)] > 0 ? \
          755  +              $test_flags(-bad) : "<none>"}] \n]
   735    756   
   736    757     tputs $test_channel [appendArgs "---- logging to: " \
   737    758         [expr {[info exists test_log] && [string length $test_log] > 0 ? \
   738    759             [appendArgs \" $test_log \"] : "<none>"}] \n]
   739    760   
   740    761     tputs $test_channel [appendArgs "---- pass threshold: " \
   741    762         [expr {[info exists test_threshold] && \
................................................................................
   880    901         #       "debug-1.4", "glob-99.*", "object-10.*", "perf-2.2",
   881    902         #       and various other places within the test suite code
   882    903         #       itself.
   883    904         #
   884    905         checkForQuiet $test_channel false
   885    906       }
   886    907   
   887         -    #
   888         -    # NOTE: Has strong name key detection been disabled?
   889         -    #
   890         -    if {![info exists no(strongNameKey)]} then {
   891         -      catch {info engine PublicKeyToken} publicKeyToken
   892         -
   893         -      if {[string length $publicKeyToken] == 0} then {
   894         -        #
   895         -        # NOTE: The Eagle core library is not signed with a strong name key.
   896         -        #       This is not an error, per se; however, it may cause selected
   897         -        #       tests to fail and it should be reported to the user and noted
   898         -        #       in the test suite log file.
   899         -        #
   900         -        addConstraint strongName.none
   901         -
   902         -        if {![info exists no(warningForStrongNameKey)] && \
   903         -            ![haveConstraint quiet]} then {
   904         -          tputs $test_channel \
   905         -              "==== WARNING: no Eagle strong name signature detected...\n"
   906         -        }
   907         -      } else {
   908         -        #
   909         -        # NOTE: Add a test constraint for this specific strong name key.
   910         -        #
   911         -        addConstraint [appendArgs strongName. $publicKeyToken]
   912         -
   913         -        #
   914         -        # BUGBUG: Tcl 8.4 does not seem to like this expression because it
   915         -        #         contains the "ni" operator added in Tcl 8.5 (and Tcl 8.4
   916         -        #         tries to compile it even though it will only be evaluated
   917         -        #         in Eagle).
   918         -        #
   919         -        set expr {$publicKeyToken ni \
   920         -            "29c6297630be05eb 1e22ec67879739a2 358030063a832bc3"}
   921         -
   922         -        if {[expr $expr]} then {
   923         -          #
   924         -          # NOTE: The Eagle core library is strong name signed with a key that
   925         -          #       is not official.  This is also not an error, per se; however,
   926         -          #       it may cause some tests to fail and it should be reported to
   927         -          #       the user and noted in the test suite log file.
   928         -          #
   929         -          addConstraint strongName.unofficial
   930         -
   931         -          if {![info exists no(warningForStrongNameKey)] && \
   932         -              ![haveConstraint quiet]} then {
   933         -            tputs $test_channel [appendArgs \
   934         -                "==== WARNING: unofficial Eagle strong name signature " \
   935         -                "detected: " $publicKeyToken \n]
   936         -          }
   937         -        } else {
   938         -          #
   939         -          # NOTE: Several tests require one of the official strong name keys to
   940         -          #       be used in order for them to pass.
   941         -          #
   942         -          addConstraint strongName.official
   943         -
   944         -          tputs $test_channel [appendArgs \
   945         -              "---- official Eagle strong name signature detected: " \
   946         -              $publicKeyToken \n]
   947         -        }
   948         -
   949         -        unset expr
   950         -      }
   951         -
   952         -      unset publicKeyToken
   953         -    }
   954         -
   955    908       #
   956    909       # NOTE: Has administrator detection support been disabled?  We do
   957    910       #       this check [nearly] first as it may [eventually] be used
   958    911       #       to help determine if other constraints should be skipped.
   959    912       #
   960    913       if {![info exists no(administrator)]} then {
   961    914         checkForAdministrator $test_channel
................................................................................
  1039    992       if {![info exists no(machine)]} then {
  1040    993         checkForMachine $test_channel 32 intel; # (i.e. x86)
  1041    994         checkForMachine $test_channel 32 arm;   # (i.e. arm)
  1042    995         checkForMachine $test_channel 64 ia64;  # (i.e. itanium)
  1043    996         checkForMachine $test_channel 64 amd64; # (i.e. x64)
  1044    997       }
  1045    998   
          999  +    #
         1000  +    # NOTE: Has test suite call stack probing been disabled?
         1001  +    #
         1002  +    if {![info exists no(testCallStack)]} then {
         1003  +      checkForTestCallStack $test_channel
         1004  +    }
         1005  +
  1046   1006       #
  1047   1007       # NOTE: Has culture detection support been disabled?
  1048   1008       #
  1049   1009       if {![info exists no(culture)]} then {
  1050   1010         checkForCulture $test_channel
  1051   1011       }
  1052   1012   
................................................................................
  1066   1026   
  1067   1027       #
  1068   1028       # NOTE: Has strong name detection support been disabled?
  1069   1029       #
  1070   1030       if {![info exists no(strongName)]} then {
  1071   1031         checkForStrongName $test_channel
  1072   1032       }
         1033  +
         1034  +    #
         1035  +    # NOTE: Has strong name key detection been disabled?
         1036  +    #
         1037  +    if {![info exists no(strongNameKey)]} then {
         1038  +      checkForStrongNameKey $test_channel
         1039  +    }
  1073   1040   
  1074   1041       #
  1075   1042       # NOTE: Has certificate detection support been disabled?
  1076   1043       #
  1077   1044       if {![info exists no(certificate)]} then {
  1078   1045         checkForCertificate $test_channel
  1079   1046       }
................................................................................
  1613   1580           #
  1614   1581           # NOTE: For test "lpermute-1.3".
  1615   1582           #
  1616   1583           checkForObjectMember $test_channel Eagle._Tests.Default \
  1617   1584               *TestPermute*
  1618   1585         }
  1619   1586   
         1587  +      if {![info exists no(testDynamicCallback)]} then {
         1588  +        #
         1589  +        # NOTE: For tests "object-8.1??".
         1590  +        #
         1591  +        checkForObjectMember $test_channel Eagle._Tests.Default \
         1592  +            *TestCallDynamicCallback0*
         1593  +
         1594  +        checkForObjectMember $test_channel Eagle._Tests.Default \
         1595  +            *TestCallDynamicCallback1*
         1596  +
         1597  +        checkForObjectMember $test_channel Eagle._Tests.Default \
         1598  +            *TestCallDynamicCallback2*
         1599  +
         1600  +        checkForObjectMember $test_channel Eagle._Tests.Default \
         1601  +            *TestCallDynamicCallback3*
         1602  +
         1603  +        checkForObjectMember $test_channel Eagle._Tests.Default \
         1604  +            *TestGetDynamicCallbacks*
         1605  +
         1606  +        checkForObjectMember $test_channel Eagle._Tests.Default \
         1607  +            *TestCallStaticDynamicCallback0*
         1608  +
         1609  +        checkForObjectMember $test_channel Eagle._Tests.Default \
         1610  +            *TestCallStaticDynamicCallback1*
         1611  +
         1612  +        checkForObjectMember $test_channel Eagle._Tests.Default \
         1613  +            *TestCallStaticDynamicCallback2*
         1614  +
         1615  +        checkForObjectMember $test_channel Eagle._Tests.Default \
         1616  +            *TestCallStaticDynamicCallback3*
         1617  +
         1618  +        checkForObjectMember $test_channel Eagle._Tests.Default \
         1619  +            *TestGetStaticDynamicCallbacks*
         1620  +      }
         1621  +
  1620   1622         #
  1621   1623         # NOTE: Has DateTime testing support been disabled?
  1622   1624         #
  1623   1625         if {![info exists no(testDateTime)]} then {
  1624   1626           #
  1625   1627           # NOTE: For test "vwait-1.11".
  1626   1628           #
................................................................................
  2115   2117         #
  2116   2118         # NOTE: For test "hash-1.1".
  2117   2119         #
  2118   2120         checkForNetFx20ServicePack $test_channel
  2119   2121       }
  2120   2122   
  2121   2123       #
  2122         -    # NOTE: Has .NET Framework 4.5 testing support been disabled?
         2124  +    # NOTE: Has .NET Framework 4.x testing support been disabled?
  2123   2125       #
  2124         -    if {![info exists no(netFx45)]} then {
         2126  +    if {![info exists no(netFx4x)]} then {
  2125   2127         #
  2126   2128         # NOTE: For test "object-12.1.*".
  2127   2129         #
  2128         -      checkForNetFx45 $test_channel
         2130  +      checkForNetFx4x $test_channel
  2129   2131       }
  2130   2132   
  2131   2133       #
  2132   2134       # NOTE: Has target framework testing support been disabled?
  2133   2135       #
  2134   2136       if {![info exists no(targetFramework)]} then {
  2135   2137         checkForTargetFramework $test_channel
................................................................................
  2351   2353       #
  2352   2354       # NOTE: For tests "benchmark-1.3[89]" and "benchmark-1.40".
  2353   2355       #
  2354   2356       if {![info exists no(benchmark.txt)]} then {
  2355   2357         checkForFile $test_channel [file join $test_data_path benchmark.txt]
  2356   2358       }
  2357   2359   
         2360  +    #
         2361  +    # NOTE: For test "benchmark-1.42".
         2362  +    #
         2363  +    if {![info exists no(pngDump.txt)]} then {
         2364  +      checkForFile $test_channel [file join $test_data_path pngDump.txt]
         2365  +    }
         2366  +
  2358   2367       #
  2359   2368       # NOTE: For test "garuda-1.1".
  2360   2369       #
  2361   2370       if {![info exists no(pkgAll.tcl)]} then {
  2362   2371         checkForFile $test_channel [file join $base_path Native Package \
  2363   2372             Tests all.tcl] pkgAll.tcl
  2364   2373       }
................................................................................
  2365   2374   
  2366   2375       #
  2367   2376       # NOTE: For tests "subst-1.*".
  2368   2377       #
  2369   2378       if {![info exists no(bad_subst.txt)]} then {
  2370   2379         checkForFile $test_channel [file join $test_data_path bad_subst.txt]
  2371   2380       }
         2381  +
         2382  +    #
         2383  +    # NOTE: For test "processIsolation-1.1".
         2384  +    #
         2385  +    if {![info exists no(isolated.eagle)]} then {
         2386  +      checkForFile $test_channel [file join $test_data_path isolated.eagle]
         2387  +    }
  2372   2388   
  2373   2389       #
  2374   2390       # NOTE: This is not currently used by any tests.
  2375   2391       #
  2376   2392       if {![info exists no(evaluate.eagle)]} then {
  2377   2393         checkForFile $test_channel [file join $test_data_path evaluate.eagle]
  2378   2394       }
................................................................................
  2619   2635     if {![info exists no(checkForBigLists)]} then {
  2620   2636       checkForBigLists $test_channel
  2621   2637     }
  2622   2638   
  2623   2639     if {![info exists no(checkForTimeIntensive)]} then {
  2624   2640       checkForTimeIntensive $test_channel
  2625   2641     }
         2642  +
         2643  +  if {![info exists no(checkForFullTest)]} then {
         2644  +    checkForFullTest $test_channel
         2645  +  }
  2626   2646   
  2627   2647     if {![info exists no(checkForMemoryIntensive)]} then {
  2628   2648       checkForMemoryIntensive $test_channel
  2629   2649     }
  2630   2650   
  2631   2651     if {![info exists no(checkForStackIntensive)]} then {
  2632   2652       checkForStackIntensive $test_channel

Added Setup/build_mono.bat.

            1  +@ECHO OFF
            2  +
            3  +::
            4  +:: build_mono.bat --
            5  +::
            6  +:: Mono Wrapper Tool for MSBuild
            7  +::
            8  +:: Written by Joe Mistachkin.
            9  +:: Released to the public domain, use at your own risk!
           10  +::
           11  +
           12  +SETLOCAL
           13  +
           14  +REM SET __ECHO=ECHO
           15  +REM SET __ECHO3=ECHO
           16  +IF NOT DEFINED _AECHO (SET _AECHO=REM)
           17  +IF NOT DEFINED _CECHO (SET _CECHO=REM)
           18  +IF NOT DEFINED _VECHO (SET _VECHO=REM)
           19  +
           20  +%_AECHO% Running %0 %*
           21  +
           22  +SET DUMMY2=%1
           23  +
           24  +IF DEFINED DUMMY2 (
           25  +  GOTO usage
           26  +)
           27  +
           28  +SET TOOLS=%~dp0
           29  +SET TOOLS=%TOOLS:~0,-1%
           30  +
           31  +%_VECHO% Tools = '%TOOLS%'
           32  +
           33  +SET BUILD_CONFIGURATIONS=DebugManagedOnly ReleaseManagedOnly
           34  +SET PLATFORMS="Any CPU"
           35  +SET YEARS=2008 2013
           36  +SET NOUSER=1
           37  +SET MSBUILD_ARGS=/property:UseInteropDll=false
           38  +SET MSBUILD_ARGS=%MSBUILD_ARGS% /property:UseSqliteStandard=true
           39  +SET MSBUILD_ARGS=%MSBUILD_ARGS% /property:InteropCodec=false
           40  +SET MSBUILD_ARGS=%MSBUILD_ARGS% /property:InteropExtensionFunctions=false
           41  +SET MSBUILD_ARGS=%MSBUILD_ARGS% /property:InteropVirtualTable=false
           42  +SET MSBUILD_ARGS=%MSBUILD_ARGS% /property:InteropTestExtension=false
           43  +
           44  +CALL :fn_ResetErrorLevel
           45  +
           46  +%__ECHO3% CALL "%TOOLS%\build_all.bat"
           47  +
           48  +IF ERRORLEVEL 1 (
           49  +  ECHO Failed to build Mono binaries.
           50  +  GOTO errors
           51  +)
           52  +
           53  +:fn_ResetErrorLevel
           54  +  VERIFY > NUL
           55  +  GOTO :EOF
           56  +
           57  +:fn_SetErrorLevel
           58  +  VERIFY MAYBE 2> NUL
           59  +  GOTO :EOF
           60  +
           61  +:usage
           62  +  ECHO.
           63  +  ECHO Usage: %~nx0
           64  +  ECHO.
           65  +  GOTO errors
           66  +
           67  +:errors
           68  +  CALL :fn_SetErrorLevel
           69  +  ENDLOCAL
           70  +  ECHO.
           71  +  ECHO Build failure, errors were encountered.
           72  +  GOTO end_of_file
           73  +
           74  +:no_errors
           75  +  CALL :fn_ResetErrorLevel
           76  +  ENDLOCAL
           77  +  ECHO.
           78  +  ECHO Build success, no errors were encountered.
           79  +  GOTO end_of_file
           80  +
           81  +:end_of_file
           82  +%__ECHO% EXIT /B %ERRORLEVEL%

Changes to Setup/clean.bat.

    38     38   IF NOT EXIST "%TEMP%" (
    39     39     ECHO The TEMP directory, "%TEMP%", does not exist.
    40     40     GOTO usage
    41     41   )
    42     42   
    43     43   IF DEFINED CLEANDIRS GOTO skip_cleanDirs
    44     44   
    45         -SET CLEANDIRS=bin obj Doc\Output Setup\Output
           45  +SET CLEANDIRS=.vs bin obj Doc\Output Setup\Output
    46     46   SET CLEANDIRS=%CLEANDIRS% SQLite.Designer\bin SQLite.Designer\obj
    47     47   SET CLEANDIRS=%CLEANDIRS% SQLite.Interop\bin SQLite.Interop\obj
    48     48   SET CLEANDIRS=%CLEANDIRS% System.Data.SQLite\bin System.Data.SQLite\obj
    49     49   SET CLEANDIRS=%CLEANDIRS% System.Data.SQLite.Linq\bin System.Data.SQLite.Linq\obj
    50     50   SET CLEANDIRS=%CLEANDIRS% test\bin test\obj testce\bin testce\obj testlinq\bin
    51     51   SET CLEANDIRS=%CLEANDIRS% testlinq\obj tools\install\bin tools\install\obj
    52     52   

Changes to System.Data.SQLite/LINQ/SQLiteFactory_Linq.cs.

    39     39   
    40     40       static SQLiteFactory()
    41     41       {
    42     42   #if (SQLITE_STANDARD || USE_INTEROP_DLL || PLATFORM_COMPACTFRAMEWORK) && PRELOAD_NATIVE_LIBRARY
    43     43           UnsafeNativeMethods.Initialize();
    44     44   #endif
    45     45   
    46         -#if INTEROP_LOG
           46  +#if USE_INTEROP_DLL && INTEROP_LOG
    47     47           if (UnsafeNativeMethods.sqlite3_config_log_interop() == SQLiteErrorCode.Ok)
    48     48           {
    49     49               UnsafeNativeMethods.sqlite3_log(
    50     50                   SQLiteErrorCode.Ok, SQLiteConvert.ToUTF8("logging initialized."));
    51     51           }
    52     52   #endif
    53     53   
................................................................................
    86     86               string typeName = UnsafeNativeMethods.GetSettingValue(
    87     87                   "TypeName_SQLiteProviderServices", null);
    88     88   
    89     89               Version version = this.GetType().Assembly.GetName().Version;
    90     90   
    91     91               if (typeName != null)
    92     92               {
    93         -                typeName = String.Format(
           93  +                typeName = UnsafeNativeMethods.StringFormat(
    94     94                       CultureInfo.InvariantCulture, typeName, version);
    95     95               }
    96     96               else
    97     97               {
    98         -                typeName = String.Format(
           98  +                typeName = UnsafeNativeMethods.StringFormat(
    99     99                       CultureInfo.InvariantCulture, DefaultTypeName, version);
   100    100               }
   101    101   
   102    102               Type type = Type.GetType(typeName, false);
   103    103   
   104    104               if (type != null)
   105    105               {

Changes to System.Data.SQLite/SQLite3.cs.

   244    244                 if (SQLiteBase.ResetConnection(_sql, _sql, canThrow))
   245    245                 {
   246    246                     if (unbindFunctions)
   247    247                     {
   248    248                         if (SQLiteFunction.UnbindAllFunctions(this, _flags, false))
   249    249                         {
   250    250   #if !NET_COMPACT_20 && TRACE_CONNECTION
   251         -                          Trace.WriteLine(String.Format(
          251  +                          Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   252    252                                 CultureInfo.CurrentCulture,
   253    253                                 "UnbindFunctions (Pool) Success: {0}",
   254    254                                 HandleToString()));
   255    255   #endif
   256    256                         }
   257    257                         else
   258    258                         {
   259    259   #if !NET_COMPACT_20 && TRACE_CONNECTION
   260         -                          Trace.WriteLine(String.Format(
          260  +                          Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   261    261                                 CultureInfo.CurrentCulture,
   262    262                                 "UnbindFunctions (Pool) Failure: {0}",
   263    263                                 HandleToString()));
   264    264   #endif
   265    265                         }
   266    266                     }
   267    267   
................................................................................
   273    273   
   274    274                     SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
   275    275                         SQLiteConnectionEventType.ClosedToPool, null, null,
   276    276                         null, null, _sql, _fileName, new object[] {
   277    277                         typeof(SQLite3), canThrow, _fileName, _poolVersion }));
   278    278   
   279    279   #if !NET_COMPACT_20 && TRACE_CONNECTION
   280         -                  Trace.WriteLine(String.Format(
          280  +                  Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   281    281                         CultureInfo.CurrentCulture,
   282    282                         "Close (Pool) Success: {0}",
   283    283                         HandleToString()));
   284    284   #endif
   285    285                 }
   286    286   #if !NET_COMPACT_20 && TRACE_CONNECTION
   287    287                 else
   288    288                 {
   289         -                  Trace.WriteLine(String.Format(
          289  +                  Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   290    290                         CultureInfo.CurrentCulture,
   291    291                         "Close (Pool) Failure: {0}",
   292    292                         HandleToString()));
   293    293                 }
   294    294   #endif
   295    295             }
   296    296             else
   297    297             {
   298    298                 if (unbindFunctions)
   299    299                 {
   300    300                     if (SQLiteFunction.UnbindAllFunctions(this, _flags, false))
   301    301                     {
   302    302   #if !NET_COMPACT_20 && TRACE_CONNECTION
   303         -                      Trace.WriteLine(String.Format(
          303  +                      Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   304    304                             CultureInfo.CurrentCulture,
   305    305                             "UnbindFunctions Success: {0}",
   306    306                             HandleToString()));
   307    307   #endif
   308    308                     }
   309    309                     else
   310    310                     {
   311    311   #if !NET_COMPACT_20 && TRACE_CONNECTION
   312         -                      Trace.WriteLine(String.Format(
          312  +                      Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   313    313                             CultureInfo.CurrentCulture,
   314    314                             "UnbindFunctions Failure: {0}",
   315    315                             HandleToString()));
   316    316   #endif
   317    317                     }
   318    318                 }
   319    319   
................................................................................
   885    885           SQLiteConnection.OnChanged(null, new ConnectionEventArgs(
   886    886               SQLiteConnectionEventType.OpenedFromPool, null, null,
   887    887               null, null, _sql, strFilename, new object[] {
   888    888               typeof(SQLite3), strFilename, vfsName, connectionFlags,
   889    889               openFlags, maxPoolSize, usePool, _poolVersion }));
   890    890   
   891    891   #if !NET_COMPACT_20 && TRACE_CONNECTION
   892         -        Trace.WriteLine(String.Format(
          892  +        Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   893    893               CultureInfo.CurrentCulture,
   894    894               "Open (Pool): {0}", HandleToString()));
   895    895   #endif
   896    896         }
   897    897   
   898    898         if (_sql == null)
   899    899         {
................................................................................
   916    916             else
   917    917   #endif
   918    918             {
   919    919               n = UnsafeNativeMethods.sqlite3_open_v2(ToUTF8(strFilename), ref db, openFlags, ToUTF8(vfsName));
   920    920             }
   921    921   
   922    922   #if !NET_COMPACT_20 && TRACE_CONNECTION
   923         -          Trace.WriteLine(String.Format(
          923  +          Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   924    924                 CultureInfo.CurrentCulture,
   925    925                 "Open: {0}", db));
   926    926   #endif
   927    927   
   928    928             if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
   929    929             _sql = new SQLiteConnectionHandle(db, true);
   930    930           }
................................................................................
  1241   1241           //       data classes.
  1242   1242           //
  1243   1243           string baseSchemaName = (cnn != null) ? cnn._baseSchemaName : null;
  1244   1244   
  1245   1245           if (!String.IsNullOrEmpty(baseSchemaName))
  1246   1246           {
  1247   1247             strSql = strSql.Replace(
  1248         -              String.Format(CultureInfo.InvariantCulture,
         1248  +              UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture,
  1249   1249                 "[{0}].", baseSchemaName), String.Empty);
  1250   1250   
  1251   1251             strSql = strSql.Replace(
  1252         -              String.Format(CultureInfo.InvariantCulture,
         1252  +              UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture,
  1253   1253                 "{0}.", baseSchemaName), String.Empty);
  1254   1254           }
  1255   1255         }
  1256   1256   
  1257   1257         SQLiteConnectionFlags flags =
  1258   1258             (cnn != null) ? cnn.Flags : SQLiteConnectionFlags.Default;
  1259   1259   
................................................................................
  1262   1262             ForceLogPrepare() ||
  1263   1263   #endif
  1264   1264             ((flags & SQLiteConnectionFlags.LogPrepare) == SQLiteConnectionFlags.LogPrepare))
  1265   1265         {
  1266   1266             if ((strSql == null) || (strSql.Length == 0) || (strSql.Trim().Length == 0))
  1267   1267                 SQLiteLog.LogMessage("Preparing {<nothing>}...");
  1268   1268             else
  1269         -              SQLiteLog.LogMessage(String.Format(
         1269  +              SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
  1270   1270                     CultureInfo.CurrentCulture, "Preparing {{{0}}}...", strSql));
  1271   1271         }
  1272   1272   
  1273   1273         IntPtr stmt = IntPtr.Zero;
  1274   1274         IntPtr ptr = IntPtr.Zero;
  1275   1275         int len = 0;
  1276   1276         SQLiteErrorCode n = SQLiteErrorCode.Schema;
................................................................................
  1309   1309   #else
  1310   1310               n = UnsafeNativeMethods.sqlite3_prepare(_sql, psql, b.Length - 1, ref stmt, ref ptr);
  1311   1311   #endif
  1312   1312               len = -1;
  1313   1313   #endif
  1314   1314   
  1315   1315   #if !NET_COMPACT_20 && TRACE_STATEMENT
  1316         -            Trace.WriteLine(String.Format(
         1316  +            Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  1317   1317                   CultureInfo.CurrentCulture,
  1318   1318                   "Prepare ({0}): {1}", n, stmt));
  1319   1319   #endif
  1320   1320   
  1321   1321               if ((n == SQLiteErrorCode.Ok) && (stmt != IntPtr.Zero))
  1322   1322               {
  1323   1323                 if (statementHandle != null) statementHandle.Dispose();
................................................................................
  1445   1445         }
  1446   1446       }
  1447   1447   
  1448   1448       protected static void LogBind(SQLiteStatementHandle handle, int index)
  1449   1449       {
  1450   1450           IntPtr handleIntPtr = handle;
  1451   1451   
  1452         -        SQLiteLog.LogMessage(String.Format(
         1452  +        SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
  1453   1453               CultureInfo.CurrentCulture,
  1454   1454               "Binding statement {0} paramter #{1} as NULL...",
  1455   1455               handleIntPtr, index));
  1456   1456       }
  1457   1457   
  1458   1458       protected static void LogBind(SQLiteStatementHandle handle, int index, ValueType value)
  1459   1459       {
  1460   1460           IntPtr handleIntPtr = handle;
  1461   1461   
  1462         -        SQLiteLog.LogMessage(String.Format(
         1462  +        SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
         1463  +            CultureInfo.CurrentCulture,
  1463   1464               "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...",
  1464   1465               handleIntPtr, index, value.GetType(), value));
  1465   1466       }
  1466   1467   
  1467   1468       private static string FormatDateTime(DateTime value)
  1468   1469       {
  1469   1470           StringBuilder result = new StringBuilder();
................................................................................
  1477   1478           return result.ToString();
  1478   1479       }
  1479   1480   
  1480   1481       protected static void LogBind(SQLiteStatementHandle handle, int index, DateTime value)
  1481   1482       {
  1482   1483           IntPtr handleIntPtr = handle;
  1483   1484   
  1484         -        SQLiteLog.LogMessage(String.Format(
         1485  +        SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
         1486  +            CultureInfo.CurrentCulture,
  1485   1487               "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...",
  1486   1488               handleIntPtr, index, typeof(DateTime), FormatDateTime(value)));
  1487   1489       }
  1488   1490   
  1489   1491       protected static void LogBind(SQLiteStatementHandle handle, int index, string value)
  1490   1492       {
  1491   1493           IntPtr handleIntPtr = handle;
  1492   1494   
  1493         -        SQLiteLog.LogMessage(String.Format(
         1495  +        SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
         1496  +            CultureInfo.CurrentCulture,
  1494   1497               "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...",
  1495   1498               handleIntPtr, index, typeof(String), (value != null) ? value : "<null>"));
  1496   1499       }
  1497   1500   
  1498   1501       private static string ToHexadecimalString(
  1499   1502           byte[] array
  1500   1503           )
................................................................................
  1512   1515           return result.ToString();
  1513   1516       }
  1514   1517   
  1515   1518       protected static void LogBind(SQLiteStatementHandle handle, int index, byte[] value)
  1516   1519       {
  1517   1520           IntPtr handleIntPtr = handle;
  1518   1521   
  1519         -        SQLiteLog.LogMessage(String.Format(
         1522  +        SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
         1523  +            CultureInfo.CurrentCulture,
  1520   1524               "Binding statement {0} paramter #{1} as type {2} with value {{{3}}}...",
  1521   1525               handleIntPtr, index, typeof(Byte[]), (value != null) ? ToHexadecimalString(value) : "<null>"));
  1522   1526       }
  1523   1527   
  1524   1528       internal override void Bind_Double(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, double value)
  1525   1529       {
  1526   1530           SQLiteStatementHandle handle = stmt._sqlite_stmt;
................................................................................
  1528   1532           if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
  1529   1533           {
  1530   1534               LogBind(handle, index, value);
  1531   1535           }
  1532   1536   
  1533   1537   #if !PLATFORM_COMPACTFRAMEWORK
  1534   1538           SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_double(handle, index, value);
         1539  +        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1535   1540   #elif !SQLITE_STANDARD
  1536   1541           SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_double_interop(handle, index, ref value);
         1542  +        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1537   1543   #else
  1538   1544           throw new NotImplementedException();
  1539   1545   #endif
  1540         -        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1541   1546       }
  1542   1547   
  1543   1548       internal override void Bind_Int32(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, int value)
  1544   1549       {
  1545   1550           SQLiteStatementHandle handle = stmt._sqlite_stmt;
  1546   1551   
  1547   1552           if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
................................................................................
  1592   1597   #if !PLATFORM_COMPACTFRAMEWORK
  1593   1598           if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
  1594   1599           {
  1595   1600               LogBind(handle, index, value);
  1596   1601           }
  1597   1602   
  1598   1603           SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_int64(handle, index, value);
         1604  +        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1599   1605   #elif !SQLITE_STANDARD
  1600   1606           SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_int64_interop(handle, index, ref value);
         1607  +        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1601   1608   #else
  1602   1609           throw new NotImplementedException();
  1603   1610   #endif
  1604         -        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1605   1611       }
  1606   1612   
  1607   1613       internal override void Bind_UInt64(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, ulong value)
  1608   1614       {
  1609   1615           SQLiteStatementHandle handle = stmt._sqlite_stmt;
  1610   1616   
  1611   1617   #if !PLATFORM_COMPACTFRAMEWORK
  1612   1618           if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
  1613   1619           {
  1614   1620               LogBind(handle, index, value);
  1615   1621           }
  1616   1622   
  1617   1623           SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_uint64(handle, index, value);
         1624  +        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1618   1625   #elif !SQLITE_STANDARD
  1619   1626           SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_uint64_interop(handle, index, ref value);
         1627  +        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1620   1628   #else
  1621   1629           throw new NotImplementedException();
  1622   1630   #endif
  1623         -        if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1624   1631       }
  1625   1632   
  1626   1633       internal override void Bind_Text(SQLiteStatement stmt, SQLiteConnectionFlags flags, int index, string value)
  1627   1634       {
  1628   1635           SQLiteStatementHandle handle = stmt._sqlite_stmt;
  1629   1636   
  1630   1637   #if !PLATFORM_COMPACTFRAMEWORK
................................................................................
  1680   1687   #if !PLATFORM_COMPACTFRAMEWORK
  1681   1688                       if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
  1682   1689                       {
  1683   1690                           LogBind(handle, index, value);
  1684   1691                       }
  1685   1692   
  1686   1693                       SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_int64(handle, index, value);
         1694  +                    if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
         1695  +                    break;
  1687   1696   #elif !SQLITE_STANDARD
  1688   1697                       SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_int64_interop(handle, index, ref value);
         1698  +                    if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
         1699  +                    break;
  1689   1700   #else
  1690   1701                       throw new NotImplementedException();
  1691   1702   #endif
  1692         -                    if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1693         -                    break;
  1694   1703                   }
  1695   1704               case SQLiteDateFormats.JulianDay:
  1696   1705                   {
  1697   1706                       double value = ToJulianDay(dt);
  1698   1707   
  1699   1708   #if !PLATFORM_COMPACTFRAMEWORK
  1700   1709                       if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
  1701   1710                       {
  1702   1711                           LogBind(handle, index, value);
  1703   1712                       }
  1704   1713   
  1705   1714                       SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_double(handle, index, value);
         1715  +                    if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
         1716  +                    break;
  1706   1717   #elif !SQLITE_STANDARD
  1707   1718                       SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_double_interop(handle, index, ref value);
         1719  +                    if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
         1720  +                    break;
  1708   1721   #else
  1709   1722                       throw new NotImplementedException();
  1710   1723   #endif
  1711         -                    if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1712         -                    break;
  1713   1724                   }
  1714   1725               case SQLiteDateFormats.UnixEpoch:
  1715   1726                   {
  1716   1727                       long value = Convert.ToInt64(dt.Subtract(UnixEpoch).TotalSeconds);
  1717   1728   
  1718   1729   #if !PLATFORM_COMPACTFRAMEWORK
  1719   1730                       if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
  1720   1731                       {
  1721   1732                           LogBind(handle, index, value);
  1722   1733                       }
  1723   1734   
  1724   1735                       SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_int64(handle, index, value);
         1736  +                    if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
         1737  +                    break;
  1725   1738   #elif !SQLITE_STANDARD
  1726   1739                       SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_bind_int64_interop(handle, index, ref value);
         1740  +                    if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
         1741  +                    break;
  1727   1742   #else
  1728   1743                       throw new NotImplementedException();
  1729   1744   #endif
  1730         -                    if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
  1731         -                    break;
  1732   1745                   }
  1733   1746               default:
  1734   1747                   {
  1735   1748                       byte[] b = ToUTF8(dt);
  1736   1749   
  1737   1750   #if !PLATFORM_COMPACTFRAMEWORK
  1738   1751                       if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
................................................................................
  1783   1796           SQLiteStatementHandle handle = stmt._sqlite_stmt;
  1784   1797           int value = UnsafeNativeMethods.sqlite3_bind_parameter_count(handle);
  1785   1798   
  1786   1799           if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
  1787   1800           {
  1788   1801               IntPtr handleIntPtr = handle;
  1789   1802   
  1790         -            SQLiteLog.LogMessage(String.Format(
         1803  +            SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
  1791   1804                   CultureInfo.CurrentCulture,
  1792   1805                   "Statement {0} paramter count is {1}.",
  1793   1806                   handleIntPtr, value));
  1794   1807           }
  1795   1808   
  1796   1809           return value;
  1797   1810       }
................................................................................
  1808   1821           name = UTF8ToString(UnsafeNativeMethods.sqlite3_bind_parameter_name(handle, index), -1);
  1809   1822   #endif
  1810   1823   
  1811   1824           if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
  1812   1825           {
  1813   1826               IntPtr handleIntPtr = handle;
  1814   1827   
  1815         -            SQLiteLog.LogMessage(String.Format(
         1828  +            SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
  1816   1829                   CultureInfo.CurrentCulture,
  1817   1830                   "Statement {0} paramter #{1} name is {{{2}}}.",
  1818   1831                   handleIntPtr, index, name));
  1819   1832           }
  1820   1833   
  1821   1834           return name;
  1822   1835       }
................................................................................
  1826   1839           SQLiteStatementHandle handle = stmt._sqlite_stmt;
  1827   1840           int index = UnsafeNativeMethods.sqlite3_bind_parameter_index(handle, ToUTF8(paramName));
  1828   1841   
  1829   1842           if ((flags & SQLiteConnectionFlags.LogBind) == SQLiteConnectionFlags.LogBind)
  1830   1843           {
  1831   1844               IntPtr handleIntPtr = handle;
  1832   1845   
  1833         -            SQLiteLog.LogMessage(String.Format(
         1846  +            SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
  1834   1847                   CultureInfo.CurrentCulture,
  1835   1848                   "Statement {0} paramter index of name {{{1}}} is #{2}.",
  1836   1849                   handleIntPtr, paramName, index));
  1837   1850           }
  1838   1851   
  1839   1852           return index;
  1840   1853       }
................................................................................
  1974   1987         notNull = (nnotNull == 1);
  1975   1988         primaryKey = (nprimaryKey == 1);
  1976   1989         autoIncrement = (nautoInc == 1);
  1977   1990       }
  1978   1991   
  1979   1992       internal override double GetDouble(SQLiteStatement stmt, int index)
  1980   1993       {
  1981         -      double value;
  1982   1994   #if !PLATFORM_COMPACTFRAMEWORK
  1983         -      value = UnsafeNativeMethods.sqlite3_column_double(stmt._sqlite_stmt, index);
         1995  +      return UnsafeNativeMethods.sqlite3_column_double(stmt._sqlite_stmt, index);
  1984   1996   #elif !SQLITE_STANDARD
  1985         -      value = 0.0;
         1997  +      double value = 0.0;
  1986   1998         UnsafeNativeMethods.sqlite3_column_double_interop(stmt._sqlite_stmt, index, ref value);
         1999  +      return value;
  1987   2000   #else
  1988   2001         throw new NotImplementedException();
  1989   2002   #endif
  1990         -      return value;
  1991   2003       }
  1992   2004   
  1993   2005       internal override sbyte GetSByte(SQLiteStatement stmt, int index)
  1994   2006       {
  1995   2007         return unchecked((sbyte)(GetInt32(stmt, index) & byte.MaxValue));
  1996   2008       }
  1997   2009   
................................................................................
  2018   2030       internal override uint GetUInt32(SQLiteStatement stmt, int index)
  2019   2031       {
  2020   2032         return unchecked((uint)GetInt32(stmt, index));
  2021   2033       }
  2022   2034   
  2023   2035       internal override long GetInt64(SQLiteStatement stmt, int index)
  2024   2036       {
  2025         -      long value;
  2026   2037   #if !PLATFORM_COMPACTFRAMEWORK
  2027         -      value = UnsafeNativeMethods.sqlite3_column_int64(stmt._sqlite_stmt, index);
         2038  +      return UnsafeNativeMethods.sqlite3_column_int64(stmt._sqlite_stmt, index);
  2028   2039   #elif !SQLITE_STANDARD
  2029         -      value = 0;
         2040  +      long value = 0;
  2030   2041         UnsafeNativeMethods.sqlite3_column_int64_interop(stmt._sqlite_stmt, index, ref value);
         2042  +      return value;
  2031   2043   #else
  2032   2044         throw new NotImplementedException();
  2033   2045   #endif
  2034         -      return value;
  2035   2046       }
  2036   2047   
  2037   2048       internal override ulong GetUInt64(SQLiteStatement stmt, int index)
  2038   2049       {
  2039   2050         return unchecked((ulong)GetInt64(stmt, index));
  2040   2051       }
  2041   2052   
................................................................................
  2249   2260         }
  2250   2261   
  2251   2262         return nCopied;
  2252   2263       }
  2253   2264   
  2254   2265       internal override double GetParamValueDouble(IntPtr ptr)
  2255   2266       {
  2256         -      double value;
  2257   2267   #if !PLATFORM_COMPACTFRAMEWORK
  2258         -      value = UnsafeNativeMethods.sqlite3_value_double(ptr);
         2268  +      return UnsafeNativeMethods.sqlite3_value_double(ptr);
  2259   2269   #elif !SQLITE_STANDARD
  2260         -      value = 0.0;
         2270  +      double value = 0.0;
  2261   2271         UnsafeNativeMethods.sqlite3_value_double_interop(ptr, ref value);
         2272  +      return value;
  2262   2273   #else
  2263   2274         throw new NotImplementedException();
  2264   2275   #endif
  2265         -      return value;
  2266   2276       }
  2267   2277   
  2268   2278       internal override int GetParamValueInt32(IntPtr ptr)
  2269   2279       {
  2270   2280         return UnsafeNativeMethods.sqlite3_value_int(ptr);
  2271   2281       }
  2272   2282   
  2273   2283       internal override long GetParamValueInt64(IntPtr ptr)
  2274   2284       {
  2275         -      Int64 value;
  2276   2285   #if !PLATFORM_COMPACTFRAMEWORK
  2277         -      value = UnsafeNativeMethods.sqlite3_value_int64(ptr);
         2286  +      return UnsafeNativeMethods.sqlite3_value_int64(ptr);
  2278   2287   #elif !SQLITE_STANDARD
  2279         -      value = 0;
         2288  +      Int64 value = 0;
  2280   2289         UnsafeNativeMethods.sqlite3_value_int64_interop(ptr, ref value);
         2290  +      return value;
  2281   2291   #else
  2282   2292         throw new NotImplementedException();
  2283   2293   #endif
  2284         -      return value;
  2285   2294       }
  2286   2295   
  2287   2296       internal override string GetParamValueText(IntPtr ptr)
  2288   2297       {
  2289   2298   #if !SQLITE_STANDARD
  2290   2299         int len = 0;
  2291   2300         return UTF8ToString(UnsafeNativeMethods.sqlite3_value_text_interop(ptr, ref len), len);
................................................................................
  2384   2393               _modules.Add(module.Name, module);
  2385   2394   
  2386   2395               if (_usePool)
  2387   2396               {
  2388   2397                   _usePool = false;
  2389   2398   
  2390   2399   #if !NET_COMPACT_20 && TRACE_CONNECTION
  2391         -                Trace.WriteLine(String.Format(
         2400  +                Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  2392   2401                       CultureInfo.CurrentCulture,
  2393   2402                       "CreateModule (Pool) Disabled: {0}",
  2394   2403                       HandleToString()));
  2395   2404   #endif
  2396   2405               }
  2397   2406           }
  2398   2407           else
................................................................................
  2631   2640       }
  2632   2641   
  2633   2642   #if INTEROP_CODEC || INTEROP_INCLUDE_SEE
  2634   2643       internal override void SetPassword(byte[] passwordBytes)
  2635   2644       {
  2636   2645         SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_key(_sql, passwordBytes, passwordBytes.Length);
  2637   2646         if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
         2647  +      _usePool = false;
  2638   2648       }
  2639   2649   
  2640   2650       internal override void ChangePassword(byte[] newPasswordBytes)
  2641   2651       {
  2642   2652         SQLiteErrorCode n = UnsafeNativeMethods.sqlite3_rekey(_sql, newPasswordBytes, (newPasswordBytes == null) ? 0 : newPasswordBytes.Length);
  2643   2653         if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, GetLastError());
         2654  +      _usePool = false;
  2644   2655       }
  2645   2656   #endif
  2646   2657   
  2647   2658       internal override void SetProgressHook(int nOps, SQLiteProgressCallback func)
  2648   2659       {
  2649   2660           UnsafeNativeMethods.sqlite3_progress_handler(_sql, nOps, func, IntPtr.Zero);
  2650   2661       }

Changes to System.Data.SQLite/SQLite3_UTF16.cs.

     8      8   namespace System.Data.SQLite
     9      9   {
    10     10     using System;
    11     11     using System.Collections.Generic;
    12     12   
    13     13   #if !NET_COMPACT_20 && TRACE_CONNECTION
    14     14     using System.Diagnostics;
    15         -  using System.Globalization;
    16     15   #endif
    17     16   
           17  +  using System.Globalization;
    18     18     using System.IO;
    19     19     using System.Runtime.InteropServices;
           20  +
    20     21   
    21     22     /// <summary>
    22     23     /// Alternate SQLite3 object, overriding many text behaviors to support UTF-16 (Unicode)
    23     24     /// </summary>
    24     25     internal sealed class SQLite3_UTF16 : SQLite3
    25     26     {
    26     27       /// <summary>
................................................................................
   158    159               SQLiteConnectionEventType.OpenedFromPool, null, null,
   159    160               null, null, _sql, strFilename, new object[] {
   160    161               typeof(SQLite3_UTF16), strFilename, vfsName,
   161    162               connectionFlags, openFlags, maxPoolSize, usePool,
   162    163               _poolVersion }));
   163    164   
   164    165   #if !NET_COMPACT_20 && TRACE_CONNECTION
   165         -        Trace.WriteLine(String.Format(
          166  +        Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   166    167               CultureInfo.CurrentCulture,
   167    168               "Open16 (Pool): {0}",
   168    169               HandleToString()));
   169    170   #endif
   170    171         }
   171    172   
   172    173         if (_sql == null)
................................................................................
   197    198               //       a flags parameter.
   198    199               //
   199    200               if (((openFlags & SQLiteOpenFlagsEnum.Create) != SQLiteOpenFlagsEnum.Create) && !File.Exists(strFilename))
   200    201                 throw new SQLiteException(SQLiteErrorCode.CantOpen, strFilename);
   201    202   
   202    203               if (vfsName != null)
   203    204               {
   204         -              throw new SQLiteException(SQLiteErrorCode.CantOpen, String.Format(
          205  +              throw new SQLiteException(SQLiteErrorCode.CantOpen, UnsafeNativeMethods.StringFormat(
          206  +                CultureInfo.CurrentCulture,
   205    207                   "cannot open using UTF-16 and VFS \"{0}\": need interop assembly", vfsName));
   206    208               }
   207    209   
   208    210               n = UnsafeNativeMethods.sqlite3_open16(strFilename, ref db);
   209    211             }
   210    212   
   211    213   #if !NET_COMPACT_20 && TRACE_CONNECTION
   212         -          Trace.WriteLine(String.Format(
          214  +          Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   213    215                 CultureInfo.CurrentCulture,
   214    216                 "Open16: {0}", db));
   215    217   #endif
   216    218   
   217    219             if (n != SQLiteErrorCode.Ok) throw new SQLiteException(n, null);
   218    220             _sql = new SQLiteConnectionHandle(db, true);
   219    221           }

Changes to System.Data.SQLite/SQLiteBase.cs.

   947    947   
   948    948         /// <summary>
   949    949         /// Prevent this <see cref="SQLiteConnection" /> object instance from
   950    950         /// loading extensions.
   951    951         /// </summary>
   952    952         NoLoadExtension = 0x200,
   953    953   
          954  +#if INTEROP_VIRTUAL_TABLE
   954    955         /// <summary>
   955    956         /// Prevent this <see cref="SQLiteConnection" /> object instance from
   956    957         /// creating virtual table modules.
   957    958         /// </summary>
   958    959         NoCreateModule = 0x400,
          960  +#endif
   959    961   
   960    962         /// <summary>
   961    963         /// Skip binding any functions provided by other managed assemblies when
   962    964         /// opening the connection.
   963    965         /// </summary>
   964    966         NoBindFunctions = 0x800,
   965    967   
          968  +#if INTEROP_VIRTUAL_TABLE
   966    969         /// <summary>
   967    970         /// Skip setting the logging related properties of the
   968    971         /// <see cref="SQLiteModule" /> object instance that was passed to
   969    972         /// the <see cref="SQLiteConnection.CreateModule" /> method.
   970    973         /// </summary>
   971    974         NoLogModule = 0x1000,
   972    975   
................................................................................
   977    980         LogModuleError = 0x2000,
   978    981   
   979    982         /// <summary>
   980    983         /// Enable logging of certain virtual table module exceptions that cannot
   981    984         /// be easily discovered via other means.
   982    985         /// </summary>
   983    986         LogModuleException = 0x4000,
          987  +#endif
   984    988   
   985    989         /// <summary>
   986    990         /// Enable tracing of potentially important [non-fatal] error conditions
   987    991         /// that cannot be easily reported through other means.
   988    992         /// </summary>
   989    993         TraceWarning = 0x8000,
   990    994   
................................................................................
  1161   1165         /// </summary>
  1162   1166         ConvertAndBindAndGetAllAsInvariantText = BindAndGetAllAsText |
  1163   1167                                                  ConvertAndBindInvariantText,
  1164   1168   
  1165   1169         /// <summary>
  1166   1170         /// Enable all logging.
  1167   1171         /// </summary>
         1172  +#if INTEROP_VIRTUAL_TABLE
  1168   1173         LogAll = LogPrepare | LogPreBind | LogBind |
  1169   1174                  LogCallbackException | LogBackup | LogModuleError |
  1170   1175                  LogModuleException,
         1176  +#else
         1177  +      LogAll = LogPrepare | LogPreBind | LogBind |
         1178  +               LogCallbackException | LogBackup,
         1179  +#endif
  1171   1180   
  1172   1181         /// <summary>
  1173   1182         /// The default extra flags for new connections.
  1174   1183         /// </summary>
         1184  +#if INTEROP_VIRTUAL_TABLE
  1175   1185         Default = LogCallbackException | LogModuleException,
         1186  +#else
         1187  +      Default = LogCallbackException,
         1188  +#endif
  1176   1189   
  1177   1190         /// <summary>
  1178   1191         /// The default extra flags for new connections with all logging enabled.
  1179   1192         /// </summary>
  1180   1193         DefaultAndLogAll = Default | LogAll
  1181   1194     }
  1182   1195   

Changes to System.Data.SQLite/SQLiteCommandBuilder.cs.

    98     98       /// <summary>
    99     99       /// Returns a valid named parameter
   100    100       /// </summary>
   101    101       /// <param name="parameterName">The name of the parameter</param>
   102    102       /// <returns>Error</returns>
   103    103       protected override string GetParameterName(string parameterName)
   104    104       {
   105         -      return String.Format(CultureInfo.InvariantCulture, "@{0}", parameterName);
          105  +      return UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "@{0}", parameterName);
   106    106       }
   107    107   
   108    108       /// <summary>
   109    109       /// Returns a named parameter for the given ordinal
   110    110       /// </summary>
   111    111       /// <param name="parameterOrdinal">The i of the parameter</param>
   112    112       /// <returns>Error</returns>
   113    113       protected override string GetParameterName(int parameterOrdinal)
   114    114       {
   115         -      return String.Format(CultureInfo.InvariantCulture, "@param{0}", parameterOrdinal);
          115  +      return UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "@param{0}", parameterOrdinal);
   116    116       }
   117    117   
   118    118       /// <summary>
   119    119       /// Returns a placeholder character for the specified parameter i.
   120    120       /// </summary>
   121    121       /// <param name="parameterOrdinal">The index of the parameter to provide a placeholder for</param>
   122    122       /// <returns>Returns a named parameter</returns>

Changes to System.Data.SQLite/SQLiteConnection.cs.

   294    294     /// <b>False</b> - Store GUID columns as text
   295    295     /// </description>
   296    296     /// <description>N</description>
   297    297     /// <description>True</description>
   298    298     /// </item>
   299    299     /// <item>
   300    300     /// <description>Cache Size</description>
   301         -  /// <description>{size in bytes}</description>
          301  +  /// <description>
          302  +  /// If the argument N is positive then the suggested cache size is set to N.
          303  +  /// If the argument N is negative, then the number of cache pages is adjusted
          304  +  /// to use approximately abs(N*1024) bytes of memory. Backwards compatibility
          305  +  /// note: The behavior of cache_size with a negative N was different in SQLite
          306  +  /// versions prior to 3.7.10. In version 3.7.9 and earlier, the number of
          307  +  /// pages in the cache was set to the absolute value of N.
          308  +  /// </description>
   302    309     /// <description>N</description>
   303    310     /// <description>2000</description>
   304    311     /// </item>
   305    312     /// <item>
   306    313     /// <description>Synchronous</description>
   307    314     /// <description>
   308    315     /// <b>Normal</b> - Normal file flushing behavior
................................................................................
   803    810       /// <param name="connectionString">The connection string to use.</param>
   804    811       public SQLiteConnection(string connectionString)
   805    812           : this(connectionString, false)
   806    813       {
   807    814           // do nothing.
   808    815       }
   809    816   
          817  +#if INTEROP_VIRTUAL_TABLE
   810    818       /// <summary>
   811    819       /// Initializes the connection with a pre-existing native connection handle.
   812    820       /// This constructor overload is intended to be used only by the private
   813    821       /// <see cref="SQLiteModule.CreateOrConnect" /> method.
   814    822       /// </summary>
   815    823       /// <param name="db">
   816    824       /// The native connection handle to use.
................................................................................
   832    840           _flags = SQLiteConnectionFlags.None;
   833    841   
   834    842           _connectionState = (db != IntPtr.Zero) ?
   835    843               ConnectionState.Open : ConnectionState.Closed;
   836    844   
   837    845           _connectionString = null; /* unknown */
   838    846       }
          847  +#endif
   839    848   
   840    849       /// <summary>
   841    850       /// Initializes the connection with the specified connection string.
   842    851       /// </summary>
   843    852       /// <param name="connectionString">
   844    853       /// The connection string to use.
   845    854       /// </param>
................................................................................
   877    886   
   878    887                 if (_versionNumber >= 3007014)
   879    888                     SQLiteConnectionHandle.closeConnection = SQLiteBase.CloseConnectionV2;
   880    889             }
   881    890         }
   882    891   #endif
   883    892   
   884         -#if INTEROP_LOG
          893  +#if USE_INTEROP_DLL && INTEROP_LOG
   885    894         if (UnsafeNativeMethods.sqlite3_config_log_interop() == SQLiteErrorCode.Ok)
   886    895         {
   887    896             UnsafeNativeMethods.sqlite3_log(
   888    897                 SQLiteErrorCode.Ok, SQLiteConvert.ToUTF8("logging initialized."));
   889    898         }
   890    899   #endif
   891    900   
................................................................................
   925    934             {
   926    935               string str = row[0].ToString();
   927    936               if (String.Compare(str, "main", StringComparison.OrdinalIgnoreCase) != 0
   928    937                 && String.Compare(str, "temp", StringComparison.OrdinalIgnoreCase) != 0)
   929    938               {
   930    939                 using (SQLiteCommand cmd = CreateCommand())
   931    940                 {
   932         -                cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "ATTACH DATABASE '{0}' AS [{1}]", row[1], row[0]);
          941  +                cmd.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "ATTACH DATABASE '{0}' AS [{1}]", row[1], row[0]);
   933    942                   cmd.ExecuteNonQuery();
   934    943                 }
   935    944               }
   936    945             }
   937    946           }
   938    947         }
   939    948       }
................................................................................
  1158   1167                       break;
  1159   1168               }
  1160   1169           }
  1161   1170           catch (Exception e)
  1162   1171           {
  1163   1172               if ((_flags & SQLiteConnectionFlags.LogBackup) == SQLiteConnectionFlags.LogBackup)
  1164   1173               {
  1165         -                SQLiteLog.LogMessage(String.Format(
         1174  +                SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
  1166   1175                       CultureInfo.CurrentCulture,
  1167   1176                       "Caught exception while backing up database: {0}", e));
  1168   1177               }
  1169   1178   
  1170   1179               throw;
  1171   1180           }
  1172   1181           finally
................................................................................
  1444   1453       ///////////////////////////////////////////////////////////////////////////////////////////////
  1445   1454   
  1446   1455       /// <summary>
  1447   1456       /// Attempts to unbind the specified <see cref="SQLiteFunction" /> object
  1448   1457       /// instance to this connection.
  1449   1458       /// </summary>
  1450   1459       /// <param name="functionAttribute">
  1451         -    /// The <see cref="SQLiteFunctionAttribute"/> object instance containing
         1460  +    /// The <see cref="SQLiteFunctionAttribute" /> object instance containing
  1452   1461       /// the metadata for the function to be unbound.
  1453   1462       /// </param>
  1454   1463       /// <returns>Non-zero if the function was unbound.</returns>
  1455   1464       public bool UnbindFunction(
  1456   1465           SQLiteFunctionAttribute functionAttribute
  1457   1466           )
  1458   1467       {
................................................................................
  1628   1637       protected override void Dispose(bool disposing)
  1629   1638       {
  1630   1639   #if !NET_COMPACT_20 && TRACE_WARNING
  1631   1640           if ((_flags & SQLiteConnectionFlags.TraceWarning) == SQLiteConnectionFlags.TraceWarning)
  1632   1641           {
  1633   1642               if (_noDispose)
  1634   1643               {
  1635         -                System.Diagnostics.Trace.WriteLine(String.Format(
         1644  +                System.Diagnostics.Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  1636   1645                       CultureInfo.CurrentCulture,
  1637   1646                       "WARNING: Disposing of connection \"{0}\" with the no-dispose flag set.",
  1638   1647                       _connectionString));
  1639   1648               }
  1640   1649           }
  1641   1650   #endif
  1642   1651   
................................................................................
  2069   2078         if (UnsafeNativeMethods.GetSettingValue("No_SQLiteConnectionNewParser", null) != null)
  2070   2079             arParts = SQLiteConvert.Split(s, ';');
  2071   2080         else
  2072   2081             arParts = SQLiteConvert.NewSplit(s, ';', true, ref error);
  2073   2082   
  2074   2083         if (arParts == null)
  2075   2084         {
  2076         -          throw new ArgumentException(String.Format(CultureInfo.CurrentCulture,
         2085  +          throw new ArgumentException(UnsafeNativeMethods.StringFormat(
         2086  +              CultureInfo.CurrentCulture,
  2077   2087                 "Invalid ConnectionString format, cannot parse: {0}", (error != null) ?
  2078   2088                 error : "could not split connection string into properties"));
  2079   2089         }
  2080   2090   
  2081   2091         int x = (arParts != null) ? arParts.Length : 0;
  2082   2092         // For each semi-colon piece, split into key and value pairs by the presence of the = sign
  2083   2093         for (n = 0; n < x; n++)
................................................................................
  2093   2103           int indexOf = arParts[n].IndexOf('=');
  2094   2104   
  2095   2105           if (indexOf != -1)
  2096   2106             ls.Add(UnwrapString(arParts[n].Substring(0, indexOf).Trim()), UnwrapString(arParts[n].Substring(indexOf + 1).Trim()));
  2097   2107           else if (allowNameOnly)
  2098   2108             ls.Add(UnwrapString(arParts[n].Trim()), String.Empty);
  2099   2109           else
  2100         -          throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Invalid ConnectionString format for part \"{0}\", no equal sign found", arParts[n]));
         2110  +          throw new ArgumentException(UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture, "Invalid ConnectionString format for part \"{0}\", no equal sign found", arParts[n]));
  2101   2111         }
  2102   2112         return ls;
  2103   2113       }
  2104   2114   
  2105   2115       /// <summary>
  2106   2116       /// Parses a connection string using the built-in (i.e. framework provided)
  2107   2117       /// connection string parser class and returns the key/value pairs.  An
................................................................................
  2293   2303       public void EnableExtensions(
  2294   2304           bool enable
  2295   2305           )
  2296   2306       {
  2297   2307           CheckDisposed();
  2298   2308   
  2299   2309           if (_sql == null)
  2300         -            throw new InvalidOperationException(String.Format(
         2310  +            throw new InvalidOperationException(UnsafeNativeMethods.StringFormat(
  2301   2311                   CultureInfo.CurrentCulture,
  2302   2312                   "Database connection not valid for {0} extensions.",
  2303   2313                   enable ? "enabling" : "disabling"));
  2304   2314   
  2305   2315           if ((_flags & SQLiteConnectionFlags.NoLoadExtension) == SQLiteConnectionFlags.NoLoadExtension)
  2306   2316               throw new SQLiteException("Loading extensions is disabled for this database connection.");
  2307   2317   
................................................................................
  2416   2426   
  2417   2427           StringBuilder result = new StringBuilder();
  2418   2428   
  2419   2429           int length = array.Length;
  2420   2430   
  2421   2431           for (int index = 0; index < length; index++)
  2422   2432   #if NET_COMPACT_20
  2423         -            result.Append(String.Format("{0:x2}", array[index]));
         2433  +            result.Append(UnsafeNativeMethods.StringFormat(
         2434  +                CultureInfo.InvariantCulture,
         2435  +                "{0:x2}", array[index]));
  2424   2436   #else
  2425   2437               result.AppendFormat("{0:x2}", array[index]);
  2426   2438   #endif
  2427   2439   
  2428   2440           return result.ToString();
  2429   2441       }
  2430   2442   
................................................................................
  2466   2478           for (int index = 0; index < text.Length; index += 2)
  2467   2479           {
  2468   2480               string value = text.Substring(index, 2);
  2469   2481   
  2470   2482               if (!TryParseByte(value,
  2471   2483                       NumberStyles.HexNumber, out result[index / 2]))
  2472   2484               {
  2473         -                error = String.Format(
         2485  +                error = UnsafeNativeMethods.StringFormat(
  2474   2486                       CultureInfo.CurrentCulture,
  2475   2487                       "string contains \"{0}\", which cannot be converted to a byte value",
  2476   2488                       value);
  2477   2489   
  2478   2490                   return null;
  2479   2491               }
  2480   2492           }
................................................................................
  2622   2634   #if !NET_COMPACT_20 && TRACE_WARNING
  2623   2635         bool uri = false;
  2624   2636   #endif
  2625   2637         bool fullUri = false;
  2626   2638         string fileName;
  2627   2639   
  2628   2640         if (Convert.ToInt32(FindKey(opts, "Version", DefaultVersion.ToString()), CultureInfo.InvariantCulture) != DefaultVersion)
  2629         -        throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, "Only SQLite Version {0} is supported at this time", DefaultVersion));
         2641  +        throw new NotSupportedException(UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture, "Only SQLite Version {0} is supported at this time", DefaultVersion));
  2630   2642   
  2631   2643   #if INTEROP_INCLUDE_ZIPVFS
  2632   2644         bool useZipVfs = false;
  2633   2645         string zipVfsVersion = FindKey(opts, "ZipVfsVersion", DefaultZipVfsVersion);
  2634   2646   
  2635   2647         if (zipVfsVersion != null)
  2636   2648         {
................................................................................
  2646   2658             else if (String.Compare(zipVfsVersion, ZipVfs_V3) == 0)
  2647   2659             {
  2648   2660                 UnsafeNativeMethods.zipvfsInit_v3(0);
  2649   2661                 useZipVfs = true;
  2650   2662             }
  2651   2663             else
  2652   2664             {
  2653         -              throw new NotSupportedException(String.Format(
         2665  +              throw new NotSupportedException(UnsafeNativeMethods.StringFormat(
  2654   2666                     CultureInfo.CurrentCulture, "Only ZipVFS versions {0}, {1}, and {2} are supported at this time",
  2655   2667                     ZipVfs_Automatic, ZipVfs_V2, ZipVfs_V3));
  2656   2668             }
  2657   2669         }
  2658   2670   #endif
  2659   2671   
  2660   2672         fileName = FindKey(opts, "Data Source", DefaultDataSource);
................................................................................
  2662   2674         if (String.IsNullOrEmpty(fileName))
  2663   2675         {
  2664   2676           fileName = FindKey(opts, "Uri", DefaultUri);
  2665   2677           if (String.IsNullOrEmpty(fileName))
  2666   2678           {
  2667   2679             fileName = FindKey(opts, "FullUri", DefaultFullUri);
  2668   2680             if (String.IsNullOrEmpty(fileName))
  2669         -            throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, "Data Source cannot be empty.  Use {0} to open an in-memory database", MemoryFileName));
         2681  +            throw new ArgumentException(UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture, "Data Source cannot be empty.  Use {0} to open an in-memory database", MemoryFileName));
  2670   2682             else
  2671   2683               fullUri = true;
  2672   2684           }
  2673   2685           else
  2674   2686           {
  2675   2687             fileName = MapUriPath(fileName);
  2676   2688   #if !NET_COMPACT_20 && TRACE_WARNING
................................................................................
  2684   2696   #if !NET_COMPACT_20 && TRACE_WARNING
  2685   2697         if ((_flags & SQLiteConnectionFlags.TraceWarning) == SQLiteConnectionFlags.TraceWarning)
  2686   2698         {
  2687   2699             if (!uri && !fullUri && !isMemory && !String.IsNullOrEmpty(fileName) &&
  2688   2700                 fileName.StartsWith("\\", StringComparison.OrdinalIgnoreCase) &&
  2689   2701                 !fileName.StartsWith("\\\\", StringComparison.OrdinalIgnoreCase))
  2690   2702             {
  2691         -              System.Diagnostics.Trace.WriteLine(String.Format(
         2703  +              System.Diagnostics.Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  2692   2704                     CultureInfo.CurrentCulture,
  2693   2705                     "WARNING: Detected a possibly malformed UNC database file name \"{0}\" that " +
  2694   2706                     "may have originally started with two backslashes; however, four leading " +
  2695   2707                     "backslashes may be required, e.g.: \"Data Source=\\\\\\{0};\"",
  2696   2708                     fileName));
  2697   2709             }
  2698   2710         }
................................................................................
  2766   2778           if (hexPassword != null)
  2767   2779           {
  2768   2780               string error = null;
  2769   2781               byte[] hexPasswordBytes = FromHexString(hexPassword, ref error);
  2770   2782   
  2771   2783               if (hexPasswordBytes == null)
  2772   2784               {
  2773         -                throw new FormatException(String.Format(
         2785  +                throw new FormatException(UnsafeNativeMethods.StringFormat(
  2774   2786                       CultureInfo.CurrentCulture,
  2775   2787                       "Cannot parse 'HexPassword' property value into byte values: {0}",
  2776   2788                       error));
  2777   2789               }
  2778   2790   
  2779   2791               _sql.SetPassword(hexPasswordBytes);
  2780   2792           }
................................................................................
  2810   2822   
  2811   2823             if (boolValue)
  2812   2824             {
  2813   2825                 using (SQLiteCommand cmd = CreateCommand())
  2814   2826                 {
  2815   2827                     if (_busyTimeout != DefaultBusyTimeout)
  2816   2828                     {
  2817         -                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA busy_timeout={0}", _busyTimeout);
         2829  +                      cmd.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA busy_timeout={0}", _busyTimeout);
  2818   2830                         cmd.ExecuteNonQuery();
  2819   2831                     }
  2820   2832   
  2821   2833                     int intValue;
  2822   2834   
  2823   2835                     if (!fullUri && !isMemory)
  2824   2836                     {
  2825   2837                         strValue = FindKey(opts, "Page Size", DefaultPageSize.ToString());
  2826   2838                         intValue = Convert.ToInt32(strValue, CultureInfo.InvariantCulture);
  2827   2839                         if (intValue != DefaultPageSize)
  2828   2840                         {
  2829         -                          cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA page_size={0}", intValue);
         2841  +                          cmd.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA page_size={0}", intValue);
  2830   2842                             cmd.ExecuteNonQuery();
  2831   2843                         }
  2832   2844                     }
  2833   2845   
  2834   2846                     strValue = FindKey(opts, "Max Page Count", DefaultMaxPageCount.ToString());
  2835   2847                     intValue = Convert.ToInt32(strValue, CultureInfo.InvariantCulture);
  2836   2848                     if (intValue != DefaultMaxPageCount)
  2837   2849                     {
  2838         -                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA max_page_count={0}", intValue);
         2850  +                      cmd.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA max_page_count={0}", intValue);
  2839   2851                         cmd.ExecuteNonQuery();
  2840   2852                     }
  2841   2853   
  2842   2854                     strValue = FindKey(opts, "Legacy Format", DefaultLegacyFormat.ToString());
  2843   2855                     boolValue = SQLiteConvert.ToBoolean(strValue);
  2844   2856                     if (boolValue != DefaultLegacyFormat)
  2845   2857                     {
  2846         -                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA legacy_file_format={0}", boolValue ? "ON" : "OFF");
         2858  +                      cmd.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA legacy_file_format={0}", boolValue ? "ON" : "OFF");
  2847   2859                         cmd.ExecuteNonQuery();
  2848   2860                     }
  2849   2861   
  2850   2862                     strValue = FindKey(opts, "Synchronous", DefaultSynchronous.ToString());
  2851   2863                     enumValue = TryParseEnum(typeof(SQLiteSynchronousEnum), strValue, true);
  2852   2864                     if (!(enumValue is SQLiteSynchronousEnum) || ((SQLiteSynchronousEnum)enumValue != DefaultSynchronous))
  2853   2865                     {
  2854         -                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA synchronous={0}", strValue);
         2866  +                      cmd.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA synchronous={0}", strValue);
  2855   2867                         cmd.ExecuteNonQuery();
  2856   2868                     }
  2857   2869   
  2858   2870                     strValue = FindKey(opts, "Cache Size", DefaultCacheSize.ToString());
  2859   2871                     intValue = Convert.ToInt32(strValue, CultureInfo.InvariantCulture);
  2860   2872                     if (intValue != DefaultCacheSize)
  2861   2873                     {
  2862         -                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA cache_size={0}", intValue);
         2874  +                      cmd.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA cache_size={0}", intValue);
  2863   2875                         cmd.ExecuteNonQuery();
  2864   2876                     }
  2865   2877   
  2866   2878                     strValue = FindKey(opts, "Journal Mode", DefaultJournalMode.ToString());
  2867   2879                     enumValue = TryParseEnum(typeof(SQLiteJournalModeEnum), strValue, true);
  2868   2880                     if (!(enumValue is SQLiteJournalModeEnum) || ((SQLiteJournalModeEnum)enumValue != DefaultJournalMode))
  2869   2881                     {
................................................................................
  2870   2882                         string pragmaStr = "PRAGMA journal_mode={0}";
  2871   2883   
  2872   2884   #if INTEROP_INCLUDE_ZIPVFS
  2873   2885                         if (useZipVfs)
  2874   2886                             pragmaStr = "PRAGMA zipvfs_journal_mode={0}";
  2875   2887   #endif
  2876   2888   
  2877         -                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, pragmaStr, strValue);
         2889  +                      cmd.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, pragmaStr, strValue);
  2878   2890                         cmd.ExecuteNonQuery();
  2879   2891                     }
  2880   2892   
  2881   2893                     strValue = FindKey(opts, "Foreign Keys", DefaultForeignKeys.ToString());
  2882   2894                     boolValue = SQLiteConvert.ToBoolean(strValue);
  2883   2895                     if (boolValue != DefaultForeignKeys)
  2884   2896                     {
  2885         -                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA foreign_keys={0}", boolValue ? "ON" : "OFF");
         2897  +                      cmd.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA foreign_keys={0}", boolValue ? "ON" : "OFF");
  2886   2898                         cmd.ExecuteNonQuery();
  2887   2899                     }
  2888   2900   
  2889   2901                     strValue = FindKey(opts, "Recursive Triggers", DefaultRecursiveTriggers.ToString());
  2890   2902                     boolValue = SQLiteConvert.ToBoolean(strValue);
  2891   2903                     if (boolValue != DefaultRecursiveTriggers)
  2892   2904                     {
  2893         -                      cmd.CommandText = String.Format(CultureInfo.InvariantCulture, "PRAGMA recursive_triggers={0}", boolValue ? "ON" : "OFF");
         2905  +                      cmd.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA recursive_triggers={0}", boolValue ? "ON" : "OFF");
  2894   2906                         cmd.ExecuteNonQuery();
  2895   2907                     }
  2896   2908                 }
  2897   2909             }
  2898   2910   
  2899   2911             if (_progressHandler != null)
  2900   2912                 _sql.SetProgressHook(_progressOps, _progressCallback);
................................................................................
  3421   3433               {
  3422   3434                   if (sourceId == null)
  3423   3435                       sourceId = "0000000000000000000000000000000000000000";
  3424   3436   
  3425   3437                   if (sourceTimeStamp == null)
  3426   3438                       sourceTimeStamp = "0000-00-00 00:00:00 UTC";
  3427   3439   
  3428         -                return String.Format("{0} {1}", sourceId, sourceTimeStamp);
         3440  +                return UnsafeNativeMethods.StringFormat(
         3441  +                    CultureInfo.InvariantCulture,
         3442  +                    "{0} {1}", sourceId, sourceTimeStamp);
  3429   3443               }
  3430   3444               else
  3431   3445               {
  3432   3446                   return null;
  3433   3447               }
  3434   3448           }
  3435   3449       }
................................................................................
  3495   3509               throw new InvalidOperationException("Database connection not valid for shutdown.");
  3496   3510   
  3497   3511           _sql.Close(true); /* NOTE: MUST be closed before shutdown. */
  3498   3512           SQLiteErrorCode rc = _sql.Shutdown();
  3499   3513   
  3500   3514   #if !NET_COMPACT_20 && TRACE_CONNECTION
  3501   3515           if (rc != SQLiteErrorCode.Ok)
  3502         -            System.Diagnostics.Trace.WriteLine(String.Format(
         3516  +            System.Diagnostics.Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  3503   3517                   CultureInfo.CurrentCulture,
  3504   3518                   "Shutdown (Instance) Failed: {0}", rc));
  3505   3519   #endif
  3506   3520   
  3507   3521           return rc;
  3508   3522       }
  3509   3523   
................................................................................
  3525   3539           )
  3526   3540       {
  3527   3541           SQLiteErrorCode rc = SQLite3.StaticShutdown(directories);
  3528   3542   
  3529   3543           if (rc != SQLiteErrorCode.Ok)
  3530   3544           {
  3531   3545   #if !NET_COMPACT_20 && TRACE_CONNECTION
  3532         -            System.Diagnostics.Trace.WriteLine(String.Format(
         3546  +            System.Diagnostics.Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  3533   3547                   CultureInfo.CurrentCulture,
  3534   3548                   "Shutdown (Static) Failed: {0}", rc));
  3535   3549   #endif
  3536   3550   
  3537   3551               if (!noThrow)
  3538   3552                   throw new SQLiteException(rc, null);
  3539   3553           }
................................................................................
  4109   4123   
  4110   4124         tbl.BeginLoadData();
  4111   4125   
  4112   4126         if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
  4113   4127   
  4114   4128         string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;
  4115   4129   
  4116         -      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table' OR [type] LIKE 'view'", strCatalog, master), this))
         4130  +      using (SQLiteCommand cmdTables = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table' OR [type] LIKE 'view'", strCatalog, master), this))
  4117   4131         using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
  4118   4132         {
  4119   4133           while (rdTables.Read())
  4120   4134           {
  4121   4135             if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), StringComparison.OrdinalIgnoreCase) == 0)
  4122   4136             {
  4123   4137               try
  4124   4138               {
  4125         -              using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this))
         4139  +              using (SQLiteCommand cmd = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdTables.GetString(2)), this))
  4126   4140                 using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader(CommandBehavior.SchemaOnly))
  4127   4141                 using (DataTable tblSchema = rd.GetSchemaTable(true, true))
  4128   4142                 {
  4129   4143                   foreach (DataRow schemaRow in tblSchema.Rows)
  4130   4144                   {
  4131   4145                     if (String.Compare(schemaRow[SchemaTableColumn.ColumnName].ToString(), strColumn, StringComparison.OrdinalIgnoreCase) == 0
  4132   4146                       || strColumn == null)
................................................................................
  4212   4226   
  4213   4227         tbl.BeginLoadData();
  4214   4228   
  4215   4229         if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
  4216   4230   
  4217   4231         string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;
  4218   4232   
  4219         -      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
         4233  +      using (SQLiteCommand cmdTables = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
  4220   4234         using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
  4221   4235         {
  4222   4236           while (rdTables.Read())
  4223   4237           {
  4224   4238             maybeRowId = false;
  4225   4239             primaryKeys.Clear();
  4226   4240             if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, StringComparison.OrdinalIgnoreCase) == 0)
  4227   4241             {
  4228   4242               // First, look for any rowid indexes -- which sqlite defines are INTEGER PRIMARY KEY columns.
  4229   4243               // Such indexes are not listed in the indexes list but count as indexes just the same.
  4230   4244               try
  4231   4245               {
  4232         -              using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this))
         4246  +              using (SQLiteCommand cmdTable = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this))
  4233   4247                 using (SQLiteDataReader rdTable = cmdTable.ExecuteReader())
  4234   4248                 {
  4235   4249                   while (rdTable.Read())
  4236   4250                   {
  4237   4251                     if (rdTable.GetInt32(5) != 0)
  4238   4252                     {
  4239   4253                       primaryKeys.Add(rdTable.GetInt32(0));
................................................................................
  4252   4266               {
  4253   4267                 row = tbl.NewRow();
  4254   4268   
  4255   4269                 row["TABLE_CATALOG"] = strCatalog;
  4256   4270                 row["TABLE_NAME"] = rdTables.GetString(2);
  4257   4271                 row["INDEX_CATALOG"] = strCatalog;
  4258   4272                 row["PRIMARY_KEY"] = true;
  4259         -              row["INDEX_NAME"] = String.Format(CultureInfo.InvariantCulture, "{1}_PK_{0}", rdTables.GetString(2), master);
         4273  +              row["INDEX_NAME"] = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "{1}_PK_{0}", rdTables.GetString(2), master);
  4260   4274                 row["UNIQUE"] = true;
  4261   4275   
  4262   4276                 if (String.Compare((string)row["INDEX_NAME"], strIndex, StringComparison.OrdinalIgnoreCase) == 0
  4263   4277                 || strIndex == null)
  4264   4278                 {
  4265   4279                   tbl.Rows.Add(row);
  4266   4280                 }
................................................................................
  4267   4281   
  4268   4282                 primaryKeys.Clear();
  4269   4283               }
  4270   4284   
  4271   4285               // Now fetch all the rest of the indexes.
  4272   4286               try
  4273   4287               {
  4274         -              using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_list([{1}])", strCatalog, rdTables.GetString(2)), this))
         4288  +              using (SQLiteCommand cmd = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_list([{1}])", strCatalog, rdTables.GetString(2)), this))
  4275   4289                 using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
  4276   4290                 {
  4277   4291                   while (rd.Read())
  4278   4292                   {
  4279   4293                     if (String.Compare(rd.GetString(1), strIndex, StringComparison.OrdinalIgnoreCase) == 0
  4280   4294                     || strIndex == null)
  4281   4295                     {
................................................................................
  4285   4299                       row["TABLE_NAME"] = rdTables.GetString(2);
  4286   4300                       row["INDEX_CATALOG"] = strCatalog;
  4287   4301                       row["INDEX_NAME"] = rd.GetString(1);
  4288   4302                       row["UNIQUE"] = SQLiteConvert.ToBoolean(rd.GetValue(2), CultureInfo.InvariantCulture, false);
  4289   4303                       row["PRIMARY_KEY"] = false;
  4290   4304   
  4291   4305                       // get the index definition
  4292         -                    using (SQLiteCommand cmdIndexes = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{2}] WHERE [type] LIKE 'index' AND [name] LIKE '{1}'", strCatalog, rd.GetString(1).Replace("'", "''"), master), this))
         4306  +                    using (SQLiteCommand cmdIndexes = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{2}] WHERE [type] LIKE 'index' AND [name] LIKE '{1}'", strCatalog, rd.GetString(1).Replace("'", "''"), master), this))
  4293   4307                       using (SQLiteDataReader rdIndexes = cmdIndexes.ExecuteReader())
  4294   4308                       {
  4295   4309                         while (rdIndexes.Read())
  4296   4310                         {
  4297   4311                           if (rdIndexes.IsDBNull(4) == false)
  4298   4312                             row["INDEX_DEFINITION"] = rdIndexes.GetString(4);
  4299   4313                           break;
................................................................................
  4301   4315                       }
  4302   4316   
  4303   4317                       // Now for the really hard work.  Figure out which index is the primary key index.
  4304   4318                       // The only way to figure it out is to check if the index was an autoindex and if we have a non-rowid
  4305   4319                       // primary key, and all the columns in the given index match the primary key columns
  4306   4320                       if (primaryKeys.Count > 0 && rd.GetString(1).StartsWith("sqlite_autoindex_" + rdTables.GetString(2), StringComparison.InvariantCultureIgnoreCase) == true)
  4307   4321                       {
  4308         -                      using (SQLiteCommand cmdDetails = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rd.GetString(1)), this))
         4322  +                      using (SQLiteCommand cmdDetails = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rd.GetString(1)), this))
  4309   4323                         using (SQLiteDataReader rdDetails = cmdDetails.ExecuteReader())
  4310   4324                         {
  4311   4325                           int nMatches = 0;
  4312   4326                           while (rdDetails.Read())
  4313   4327                           {
  4314   4328                             if (primaryKeys.Contains(rdDetails.GetInt32(1)) == false)
  4315   4329                             {
................................................................................
  4358   4372   
  4359   4373         tbl.BeginLoadData();
  4360   4374   
  4361   4375         if (String.IsNullOrEmpty(table)) table = null;
  4362   4376         if (String.IsNullOrEmpty(catalog)) catalog = "main";
  4363   4377         string master = (String.Compare(catalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;
  4364   4378   
  4365         -      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT [type], [name], [tbl_name], [rootpage], [sql], [rowid] FROM [{0}].[{1}] WHERE [type] LIKE 'trigger'", catalog, master), this))
         4379  +      using (SQLiteCommand cmd = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT [type], [name], [tbl_name], [rootpage], [sql], [rowid] FROM [{0}].[{1}] WHERE [type] LIKE 'trigger'", catalog, master), this))
  4366   4380         using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
  4367   4381         {
  4368   4382           while (rd.Read())
  4369   4383           {
  4370   4384             if (String.Compare(rd.GetString(1), triggerName, StringComparison.OrdinalIgnoreCase) == 0
  4371   4385               || triggerName == null)
  4372   4386             {
................................................................................
  4413   4427         tbl.Columns.Add("TABLE_DEFINITION", typeof(string));
  4414   4428         tbl.BeginLoadData();
  4415   4429   
  4416   4430         if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
  4417   4431   
  4418   4432         string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;
  4419   4433   
  4420         -      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT [type], [name], [tbl_name], [rootpage], [sql], [rowid] FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
         4434  +      using (SQLiteCommand cmd = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT [type], [name], [tbl_name], [rootpage], [sql], [rowid] FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
  4421   4435         using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
  4422   4436         {
  4423   4437           while (rd.Read())
  4424   4438           {
  4425   4439             strItem = rd.GetString(0);
  4426   4440             if (String.Compare(rd.GetString(2), 0, "SQLITE_", 0, 7, StringComparison.OrdinalIgnoreCase) == 0)
  4427   4441               strItem = "SYSTEM_TABLE";
................................................................................
  4479   4493   
  4480   4494         tbl.BeginLoadData();
  4481   4495   
  4482   4496         if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
  4483   4497   
  4484   4498         string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;
  4485   4499   
  4486         -      using (SQLiteCommand cmd = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'view'", strCatalog, master), this))
         4500  +      using (SQLiteCommand cmd = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'view'", strCatalog, master), this))
  4487   4501         using (SQLiteDataReader rd = (SQLiteDataReader)cmd.ExecuteReader())
  4488   4502         {
  4489   4503           while (rd.Read())
  4490   4504           {
  4491   4505             if (String.Compare(rd.GetString(1), strView, StringComparison.OrdinalIgnoreCase) == 0
  4492   4506               || String.IsNullOrEmpty(strView))
  4493   4507             {
................................................................................
  4628   4642   
  4629   4643         if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
  4630   4644   
  4631   4645         string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;
  4632   4646   
  4633   4647         tbl.BeginLoadData();
  4634   4648   
  4635         -      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
         4649  +      using (SQLiteCommand cmdTables = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
  4636   4650         using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
  4637   4651         {
  4638   4652           while (rdTables.Read())
  4639   4653           {
  4640   4654             maybeRowId = false;
  4641   4655             primaryKeys.Clear();
  4642   4656             if (String.IsNullOrEmpty(strTable) || String.Compare(rdTables.GetString(2), strTable, StringComparison.OrdinalIgnoreCase) == 0)
  4643   4657             {
  4644   4658               try
  4645   4659               {
  4646         -              using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this))
         4660  +              using (SQLiteCommand cmdTable = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA [{0}].table_info([{1}])", strCatalog, rdTables.GetString(2)), this))
  4647   4661                 using (SQLiteDataReader rdTable = cmdTable.ExecuteReader())
  4648   4662                 {
  4649   4663                   while (rdTable.Read())
  4650   4664                   {
  4651   4665                     if (rdTable.GetInt32(5) == 1) // is a primary key
  4652   4666                     {
  4653   4667                       primaryKeys.Add(new KeyValuePair<int, string>(rdTable.GetInt32(0), rdTable.GetString(1)));
................................................................................
  4662   4676               {
  4663   4677               }
  4664   4678               // This is a rowid row
  4665   4679               if (primaryKeys.Count == 1 && maybeRowId == true)
  4666   4680               {
  4667   4681                 row = tbl.NewRow();
  4668   4682                 row["CONSTRAINT_CATALOG"] = strCatalog;
  4669         -              row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "{1}_PK_{0}", rdTables.GetString(2), master);
         4683  +              row["CONSTRAINT_NAME"] = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "{1}_PK_{0}", rdTables.GetString(2), master);
  4670   4684                 row["TABLE_CATALOG"] = strCatalog;
  4671   4685                 row["TABLE_NAME"] = rdTables.GetString(2);
  4672   4686                 row["COLUMN_NAME"] = primaryKeys[0].Value;
  4673   4687                 row["INDEX_NAME"] = row["CONSTRAINT_NAME"];
  4674   4688                 row["ORDINAL_POSITION"] = 0; // primaryKeys[0].Key;
  4675   4689                 row["COLLATION_NAME"] = "BINARY";
  4676   4690                 row["SORT_MODE"] = "ASC";
  4677   4691                 row["CONFLICT_OPTION"] = 2;
  4678   4692   
  4679   4693                 if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, (string)row["INDEX_NAME"], StringComparison.OrdinalIgnoreCase) == 0)
  4680   4694                   tbl.Rows.Add(row);
  4681   4695               }
  4682   4696   
  4683         -            using (SQLiteCommand cmdIndexes = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{2}] WHERE [type] LIKE 'index' AND [tbl_name] LIKE '{1}'", strCatalog, rdTables.GetString(2).Replace("'", "''"), master), this))
         4697  +            using (SQLiteCommand cmdIndexes = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{2}] WHERE [type] LIKE 'index' AND [tbl_name] LIKE '{1}'", strCatalog, rdTables.GetString(2).Replace("'", "''"), master), this))
  4684   4698               using (SQLiteDataReader rdIndexes = cmdIndexes.ExecuteReader())
  4685   4699               {
  4686   4700                 while (rdIndexes.Read())
  4687   4701                 {
  4688   4702                   int ordinal = 0;
  4689   4703                   if (String.IsNullOrEmpty(strIndex) || String.Compare(strIndex, rdIndexes.GetString(1), StringComparison.OrdinalIgnoreCase) == 0)
  4690   4704                   {
  4691   4705                     try
  4692   4706                     {
  4693         -                    using (SQLiteCommand cmdIndex = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rdIndexes.GetString(1)), this))
         4707  +                    using (SQLiteCommand cmdIndex = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA [{0}].index_info([{1}])", strCatalog, rdIndexes.GetString(1)), this))
  4694   4708                       using (SQLiteDataReader rdIndex = cmdIndex.ExecuteReader())
  4695   4709                       {
  4696   4710                         while (rdIndex.Read())
  4697   4711                         {
  4698   4712                           row = tbl.NewRow();
  4699   4713                           row["CONSTRAINT_CATALOG"] = strCatalog;
  4700   4714                           row["CONSTRAINT_NAME"] = rdIndexes.GetString(1);
................................................................................
  4786   4800   
  4787   4801         if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
  4788   4802   
  4789   4803         string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;
  4790   4804   
  4791   4805         tbl.BeginLoadData();
  4792   4806   
  4793         -      using (SQLiteCommand cmdViews = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'view'", strCatalog, master), this))
         4807  +      using (SQLiteCommand cmdViews = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'view'", strCatalog, master), this))
  4794   4808         using (SQLiteDataReader rdViews = cmdViews.ExecuteReader())
  4795   4809         {
  4796   4810           while (rdViews.Read())
  4797   4811           {
  4798   4812             if (String.IsNullOrEmpty(strView) || String.Compare(strView, rdViews.GetString(2), StringComparison.OrdinalIgnoreCase) == 0)
  4799   4813             {
  4800         -            using (SQLiteCommand cmdViewSelect = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdViews.GetString(2)), this))
         4814  +            using (SQLiteCommand cmdViewSelect = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}]", strCatalog, rdViews.GetString(2)), this))
  4801   4815               {
  4802   4816                 strSql = rdViews.GetString(4).Replace('\r', ' ').Replace('\n', ' ').Replace('\t', ' ');
  4803   4817                 n = CultureInfo.InvariantCulture.CompareInfo.IndexOf(strSql, " AS ", CompareOptions.IgnoreCase);
  4804   4818                 if (n < 0)
  4805   4819                   continue;
  4806   4820   
  4807   4821                 strSql = strSql.Substring(n + 4);
................................................................................
  4891   4905   
  4892   4906         if (String.IsNullOrEmpty(strCatalog)) strCatalog = "main";
  4893   4907   
  4894   4908         string master = (String.Compare(strCatalog, "temp", StringComparison.OrdinalIgnoreCase) == 0) ? _tempmasterdb : _masterdb;
  4895   4909   
  4896   4910         tbl.BeginLoadData();
  4897   4911   
  4898         -      using (SQLiteCommand cmdTables = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
         4912  +      using (SQLiteCommand cmdTables = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT * FROM [{0}].[{1}] WHERE [type] LIKE 'table'", strCatalog, master), this))
  4899   4913         using (SQLiteDataReader rdTables = cmdTables.ExecuteReader())
  4900   4914         {
  4901   4915           while (rdTables.Read())
  4902   4916           {
  4903   4917             if (String.IsNullOrEmpty(strTable) || String.Compare(strTable, rdTables.GetString(2), StringComparison.OrdinalIgnoreCase) == 0)
  4904   4918             {
  4905   4919               try
  4906   4920               {
  4907   4921                 using (SQLiteCommandBuilder builder = new SQLiteCommandBuilder())
  4908         -              using (SQLiteCommand cmdKey = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].foreign_key_list([{1}])", strCatalog, rdTables.GetString(2)), this))
         4922  +              using (SQLiteCommand cmdKey = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA [{0}].foreign_key_list([{1}])", strCatalog, rdTables.GetString(2)), this))
  4909   4923                 using (SQLiteDataReader rdKey = cmdKey.ExecuteReader())
  4910   4924                 {
  4911   4925                   while (rdKey.Read())
  4912   4926                   {
  4913   4927                     row = tbl.NewRow();
  4914   4928                     row["CONSTRAINT_CATALOG"] = strCatalog;
  4915         -                  row["CONSTRAINT_NAME"] = String.Format(CultureInfo.InvariantCulture, "FK_{0}_{1}_{2}", rdTables[2], rdKey.GetInt32(0), rdKey.GetInt32(1));
         4929  +                  row["CONSTRAINT_NAME"] = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "FK_{0}_{1}_{2}", rdTables[2], rdKey.GetInt32(0), rdKey.GetInt32(1));
  4916   4930                     row["TABLE_CATALOG"] = strCatalog;
  4917   4931                     row["TABLE_NAME"] = builder.UnquoteIdentifier(rdTables.GetString(2));
  4918   4932                     row["CONSTRAINT_TYPE"] = "FOREIGN KEY";
  4919   4933                     row["IS_DEFERRABLE"] = false;
  4920   4934                     row["INITIALLY_DEFERRED"] = false;
  4921   4935                     row["FKEY_ID"] = rdKey[0];
  4922   4936                     row["FKEY_FROM_COLUMN"] = builder.UnquoteIdentifier(rdKey[3].ToString());
................................................................................
  5062   5076           {
  5063   5077               try
  5064   5078               {
  5065   5079                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
  5066   5080                           SQLiteConnectionFlags.LogCallbackException)
  5067   5081                   {
  5068   5082                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
  5069         -                        String.Format(CultureInfo.CurrentCulture,
         5083  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
  5070   5084                           "Caught exception in \"Progress\" method: {1}",
  5071   5085                           e)); /* throw */
  5072   5086                   }
  5073   5087               }
  5074   5088               catch
  5075   5089               {
  5076   5090                   // do nothing.
................................................................................
  5115   5129           {
  5116   5130               try
  5117   5131               {
  5118   5132                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
  5119   5133                           SQLiteConnectionFlags.LogCallbackException)
  5120   5134                   {
  5121   5135                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
  5122         -                        String.Format(CultureInfo.CurrentCulture,
         5136  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
  5123   5137                           "Caught exception in \"Authorize\" method: {1}",
  5124   5138                           e)); /* throw */
  5125   5139                   }
  5126   5140               }
  5127   5141               catch
  5128   5142               {
  5129   5143                   // do nothing.
................................................................................
  5164   5178           {
  5165   5179               try
  5166   5180               {
  5167   5181                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
  5168   5182                           SQLiteConnectionFlags.LogCallbackException)
  5169   5183                   {
  5170   5184                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
  5171         -                        String.Format(CultureInfo.CurrentCulture,
         5185  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
  5172   5186                           "Caught exception in \"Update\" method: {1}",
  5173   5187                           e)); /* throw */
  5174   5188                   }
  5175   5189               }
  5176   5190               catch
  5177   5191               {
  5178   5192                   // do nothing.
................................................................................
  5255   5269           {
  5256   5270               try
  5257   5271               {
  5258   5272                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
  5259   5273                           SQLiteConnectionFlags.LogCallbackException)
  5260   5274                   {
  5261   5275                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
  5262         -                        String.Format(CultureInfo.CurrentCulture,
         5276  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
  5263   5277                           "Caught exception in \"Trace\" method: {1}",
  5264   5278                           e)); /* throw */
  5265   5279                   }
  5266   5280               }
  5267   5281               catch
  5268   5282               {
  5269   5283                   // do nothing.
................................................................................
  5317   5331           {
  5318   5332               try
  5319   5333               {
  5320   5334                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
  5321   5335                           SQLiteConnectionFlags.LogCallbackException)
  5322   5336                   {
  5323   5337                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
  5324         -                        String.Format(CultureInfo.CurrentCulture,
         5338  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
  5325   5339                           "Caught exception in \"Commit\" method: {1}",
  5326   5340                           e)); /* throw */
  5327   5341                   }
  5328   5342               }
  5329   5343               catch
  5330   5344               {
  5331   5345                   // do nothing.
................................................................................
  5359   5373           {
  5360   5374               try
  5361   5375               {
  5362   5376                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
  5363   5377                           SQLiteConnectionFlags.LogCallbackException)
  5364   5378                   {
  5365   5379                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
  5366         -                        String.Format(CultureInfo.CurrentCulture,
         5380  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
  5367   5381                           "Caught exception in \"Rollback\" method: {1}",
  5368   5382                           e)); /* throw */
  5369   5383                   }
  5370   5384               }
  5371   5385               catch
  5372   5386               {
  5373   5387                   // do nothing.

Changes to System.Data.SQLite/SQLiteConvert.cs.

  1148   1148               case TypeCode.Decimal:
  1149   1149                   return ((decimal)obj) != Decimal.Zero ? true : false;
  1150   1150               case TypeCode.String:
  1151   1151                   return viaFramework ?
  1152   1152                       Convert.ToBoolean(obj, provider) :
  1153   1153                       ToBoolean(ToStringWithProvider(obj, provider));
  1154   1154               default:
  1155         -                throw new SQLiteException(String.Format(
         1155  +                throw new SQLiteException(UnsafeNativeMethods.StringFormat(
  1156   1156                       CultureInfo.CurrentCulture,
  1157   1157                       "Cannot convert type {0} to boolean",
  1158   1158                       typeCode));
  1159   1159           }
  1160   1160       }
  1161   1161   
  1162   1162       /// <summary>
................................................................................
  1439   1439           DbType dbType,
  1440   1440           SQLiteConnectionFlags flags,
  1441   1441           string typeName
  1442   1442           )
  1443   1443       {
  1444   1444           if ((flags & SQLiteConnectionFlags.TraceWarning) == SQLiteConnectionFlags.TraceWarning)
  1445   1445           {
  1446         -            Trace.WriteLine(String.Format(
         1446  +            Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  1447   1447                   CultureInfo.CurrentCulture,
  1448   1448                   "WARNING: Type mapping failed, returning default name \"{0}\" for type {1}.",
  1449   1449                   typeName, dbType));
  1450   1450           }
  1451   1451       }
  1452   1452   
  1453   1453       /// <summary>
................................................................................
  1468   1468           SQLiteConnectionFlags flags,
  1469   1469           DbType? dbType
  1470   1470           )
  1471   1471       {
  1472   1472           if (!String.IsNullOrEmpty(typeName) &&
  1473   1473               ((flags & SQLiteConnectionFlags.TraceWarning) == SQLiteConnectionFlags.TraceWarning))
  1474   1474           {
  1475         -            Trace.WriteLine(String.Format(
         1475  +            Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  1476   1476                   CultureInfo.CurrentCulture,
  1477   1477                   "WARNING: Type mapping failed, returning default type {0} for name \"{1}\".",
  1478   1478                   dbType, typeName));
  1479   1479           }
  1480   1480       }
  1481   1481   #endif
  1482   1482   

Changes to System.Data.SQLite/SQLiteDataReader.cs.

  1076   1076                 }
  1077   1077               }
  1078   1078             }
  1079   1079   
  1080   1080             if (wantDefaultValue)
  1081   1081             {
  1082   1082               // Determine the default value for the column, which sucks because we have to query the schema for each column
  1083         -            using (SQLiteCommand cmdTable = new SQLiteCommand(String.Format(CultureInfo.InvariantCulture, "PRAGMA [{0}].TABLE_INFO([{1}])",
         1083  +            using (SQLiteCommand cmdTable = new SQLiteCommand(UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "PRAGMA [{0}].TABLE_INFO([{1}])",
  1084   1084                 row[SchemaTableOptionalColumn.BaseCatalogName],
  1085   1085                 row[SchemaTableColumn.BaseTableName]
  1086   1086                 ), _command.Connection))
  1087   1087               using (DbDataReader rdTable = cmdTable.ExecuteReader())
  1088   1088               {
  1089   1089                 // Find the matching column
  1090   1090                 while (rdTable.Read())

Changes to System.Data.SQLite/SQLiteEnlistment.cs.

    92     92           // NOTE: When in "strict" mode, throw an exception if the isolation
    93     93           //       level is not recognized; otherwise, fallback to the default
    94     94           //       isolation level specified by the caller.
    95     95           //
    96     96           if (throwOnUnsupported)
    97     97           {
    98     98               throw new InvalidOperationException(
    99         -                String.Format(CultureInfo.InvariantCulture,
           99  +                UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
   100    100                   "unsupported isolation level {0}", isolationLevel));
   101    101           }
   102    102   
   103    103           return defaultIsolationLevel;
   104    104       }
   105    105   
   106    106       ///////////////////////////////////////////////////////////////////////////

Changes to System.Data.SQLite/SQLiteException.cs.

     5      5    * Released to the public domain, use at your own risk!
     6      6    ********************************************************/
     7      7   
     8      8   namespace System.Data.SQLite
     9      9   {
    10     10     using System;
    11     11     using System.Data.Common;
           12  +  using System.Globalization;
    12     13   
    13     14   #if !PLATFORM_COMPACTFRAMEWORK
    14     15     using System.Reflection;
    15     16     using System.Runtime.Serialization;
    16     17     using System.Security.Permissions;
    17     18   #endif
    18     19   
................................................................................
   178    179       /// <param name="message">Optional detailed error message.</param>
   179    180       /// <returns>Error message text for the return code.</returns>
   180    181       private static string GetStockErrorMessage(
   181    182           SQLiteErrorCode errorCode,
   182    183           string message
   183    184           )
   184    185       {
   185         -        return String.Format("{0}{1}{2}",
          186  +        return UnsafeNativeMethods.StringFormat(
          187  +            CultureInfo.CurrentCulture,
          188  +            "{0}{1}{2}",
   186    189               GetErrorString(errorCode),
   187    190   #if !NET_COMPACT_20
   188    191               Environment.NewLine, message).Trim();
   189    192   #else
   190    193               "\r\n", message).Trim();
   191    194   #endif
   192    195       }

Changes to System.Data.SQLite/SQLiteFunction.cs.

   413    413           {
   414    414               try
   415    415               {
   416    416                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
   417    417                           SQLiteConnectionFlags.LogCallbackException)
   418    418                   {
   419    419                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
   420         -                        String.Format(CultureInfo.CurrentCulture,
          420  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
   421    421                           "Caught exception in \"Invoke\" method: {0}",
   422    422                           e)); /* throw */
   423    423                   }
   424    424               }
   425    425               catch
   426    426               {
   427    427                   // do nothing.
................................................................................
   451    451           {
   452    452               try
   453    453               {
   454    454                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
   455    455                           SQLiteConnectionFlags.LogCallbackException)
   456    456                   {
   457    457                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
   458         -                        String.Format(CultureInfo.CurrentCulture,
          458  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
   459    459                           "Caught exception in \"Compare\" (UTF8) method: {0}",
   460    460                           e)); /* throw */
   461    461                   }
   462    462               }
   463    463               catch
   464    464               {
   465    465                   // do nothing.
................................................................................
   498    498           {
   499    499               try
   500    500               {
   501    501                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
   502    502                           SQLiteConnectionFlags.LogCallbackException)
   503    503                   {
   504    504                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
   505         -                        String.Format(CultureInfo.CurrentCulture,
          505  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
   506    506                           "Caught exception in \"Compare\" (UTF16) method: {0}",
   507    507                           e)); /* throw */
   508    508                   }
   509    509               }
   510    510               catch
   511    511               {
   512    512                   // do nothing.
................................................................................
   571    571           {
   572    572               try
   573    573               {
   574    574                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
   575    575                           SQLiteConnectionFlags.LogCallbackException)
   576    576                   {
   577    577                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
   578         -                        String.Format(CultureInfo.CurrentCulture,
          578  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
   579    579                           "Caught exception in \"Step\" method: {1}",
   580    580                           e)); /* throw */
   581    581                   }
   582    582               }
   583    583               catch
   584    584               {
   585    585                   // do nothing.
................................................................................
   626    626           {
   627    627               try
   628    628               {
   629    629                   if ((_flags & SQLiteConnectionFlags.LogCallbackException) ==
   630    630                           SQLiteConnectionFlags.LogCallbackException)
   631    631                   {
   632    632                       SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
   633         -                        String.Format(CultureInfo.CurrentCulture,
          633  +                        UnsafeNativeMethods.StringFormat(CultureInfo.CurrentCulture,
   634    634                           "Caught exception in \"Final\" method: {1}",
   635    635                           e)); /* throw */
   636    636                   }
   637    637               }
   638    638               catch
   639    639               {
   640    640                   // do nothing.

Changes to System.Data.SQLite/SQLiteFunctionAttribute.cs.


Changes to System.Data.SQLite/SQLiteKeyReader.cs.

    54     54               {
    55     55                   _command = cnn.CreateCommand();
    56     56                   for (int n = 0; n < columns.Length; n++)
    57     57                   {
    58     58                       columns[n] = builder.QuoteIdentifier(columns[n]);
    59     59                   }
    60     60               }
    61         -            _command.CommandText = String.Format(CultureInfo.InvariantCulture, "SELECT {0} FROM [{1}].[{2}] WHERE ROWID = ?", String.Join(",", columns), database, table);
           61  +            _command.CommandText = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, "SELECT {0} FROM [{1}].[{2}] WHERE ROWID = ?", String.Join(",", columns), database, table);
    62     62               _command.Parameters.AddWithValue(null, (long)0);
    63     63           }
    64     64   
    65     65           internal bool IsValid
    66     66           {
    67     67               set
    68     68               {

Changes to System.Data.SQLite/SQLiteLog.cs.

   100    100           /// <summary>
   101    101           /// The default log event handler.
   102    102           /// </summary>
   103    103           private static SQLiteLogEventHandler _defaultHandler;
   104    104   
   105    105           ///////////////////////////////////////////////////////////////////////
   106    106   
   107         -#if !INTEROP_LOG
          107  +#if !USE_INTEROP_DLL || !INTEROP_LOG
   108    108           /// <summary>
   109    109           /// The log callback passed to native SQLite engine.  This must live
   110    110           /// as long as the SQLite library has a pointer to it.
   111    111           /// </summary>
   112    112           private static SQLiteLogCallback _callback;
   113    113   
   114    114           ///////////////////////////////////////////////////////////////////////
................................................................................
   174    174                   if (_domainUnload == null)
   175    175                   {
   176    176                       _domainUnload = new EventHandler(DomainUnload);
   177    177                       AppDomain.CurrentDomain.DomainUnload += _domainUnload;
   178    178                   }
   179    179   #endif
   180    180   
   181         -#if !INTEROP_LOG
          181  +#if !USE_INTEROP_DLL || !INTEROP_LOG
   182    182                   //
   183    183                   // NOTE: Create an instance of the SQLite wrapper class.
   184    184                   //
   185    185                   if (_sql == null)
   186    186                   {
   187    187                       _sql = new SQLite3(
   188    188                           SQLiteDateFormats.Default, DateTimeKind.Unspecified,
................................................................................
   241    241   
   242    242                   //
   243    243                   // NOTE: Disable logging.  If necessary, it can be re-enabled
   244    244                   //       later by the Initialize method.
   245    245                   //
   246    246                   _enabled = false;
   247    247   
   248         -#if !INTEROP_LOG
          248  +#if !USE_INTEROP_DLL || !INTEROP_LOG
   249    249                   //
   250    250                   // BUGBUG: This will cause serious problems if other AppDomains
   251    251                   //         have any open SQLite connections; however, there is
   252    252                   //         currently no way around this limitation.
   253    253                   //
   254    254                   if (_sql != null)
   255    255                   {
................................................................................
   555    555               {
   556    556                   type = "trace";
   557    557               }
   558    558   
   559    559               if ((errorCode != null) &&
   560    560                   !Object.ReferenceEquals(errorCode, String.Empty))
   561    561               {
   562         -                Trace.WriteLine(String.Format(
          562  +                Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   563    563                       CultureInfo.CurrentCulture, "SQLite {0} ({1}): {2}",
   564    564                       type, errorCode, message));
   565    565               }
   566    566               else
   567    567               {
   568         -                Trace.WriteLine(String.Format(
          568  +                Trace.WriteLine(UnsafeNativeMethods.StringFormat(
   569    569                       CultureInfo.CurrentCulture, "SQLite {0}: {1}",
   570    570                       type, message));
   571    571               }
   572    572   #endif
   573    573           }
   574    574       }
   575    575   }

Changes to System.Data.SQLite/SQLiteModule.cs.

  6163   6163                   //
  6164   6164                   try
  6165   6165                   {
  6166   6166                       if (LogExceptionsNoThrow)
  6167   6167                       {
  6168   6168                           /* throw */
  6169   6169                           SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
  6170         -                            String.Format(CultureInfo.CurrentCulture,
         6170  +                            UnsafeNativeMethods.StringFormat(
         6171  +                            CultureInfo.CurrentCulture,
  6171   6172                               "Caught exception in \"{0}\" method: {1}",
  6172   6173                               destroy ? "xDestroy" : "xDisconnect", e));
  6173   6174                       }
  6174   6175                   }
  6175   6176                   catch
  6176   6177                   {
  6177   6178                       // do nothing.
................................................................................
  6222   6223               )
  6223   6224           {
  6224   6225               try
  6225   6226               {
  6226   6227                   if (logErrors)
  6227   6228                   {
  6228   6229                       SQLiteLog.LogMessage(SQLiteErrorCode.Error,
  6229         -                        String.Format(CultureInfo.CurrentCulture,
         6230  +                        UnsafeNativeMethods.StringFormat(
         6231  +                        CultureInfo.CurrentCulture,
  6230   6232                           "Virtual table error: {0}", error)); /* throw */
  6231   6233                   }
  6232   6234               }
  6233   6235               catch
  6234   6236               {
  6235   6237                   // do nothing.
  6236   6238               }
................................................................................
  6269   6271               catch (Exception e) /* NOTE: Must catch ALL. */
  6270   6272               {
  6271   6273                   try
  6272   6274                   {
  6273   6275                       if (logExceptions)
  6274   6276                       {
  6275   6277                           SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
  6276         -                            String.Format(CultureInfo.CurrentCulture,
         6278  +                            UnsafeNativeMethods.StringFormat(
         6279  +                            CultureInfo.CurrentCulture,
  6277   6280                               "Caught exception in \"SetTableError\" method: {0}",
  6278   6281                               e)); /* throw */
  6279   6282                       }
  6280   6283                   }
  6281   6284                   catch
  6282   6285                   {
  6283   6286                       // do nothing.
................................................................................
  6670   6673   
  6671   6674               if ((tables != null) &&
  6672   6675                   tables.TryGetValue(pVtab, out table))
  6673   6676               {
  6674   6677                   return table;
  6675   6678               }
  6676   6679   
  6677         -            SetTableError(pVtab, String.Format(
         6680  +            SetTableError(pVtab, UnsafeNativeMethods.StringFormat(
  6678   6681                   CultureInfo.CurrentCulture,
  6679   6682                   "managed table for {0} not found", pVtab));
  6680   6683   
  6681   6684               return null;
  6682   6685           }
  6683   6686   
  6684   6687           ///////////////////////////////////////////////////////////////////////
................................................................................
  6764   6767   
  6765   6768               if ((cursors != null) &&
  6766   6769                   cursors.TryGetValue(pCursor, out cursor))
  6767   6770               {
  6768   6771                   return cursor;
  6769   6772               }
  6770   6773   
  6771         -            SetTableError(pVtab, String.Format(
         6774  +            SetTableError(pVtab, UnsafeNativeMethods.StringFormat(
  6772   6775                   CultureInfo.CurrentCulture,
  6773   6776                   "managed cursor for {0} not found", pCursor));
  6774   6777   
  6775   6778               return null;
  6776   6779           }
  6777   6780   
  6778   6781           ///////////////////////////////////////////////////////////////////////
................................................................................
  6850   6853           /// </returns>
  6851   6854           protected virtual string GetFunctionKey(
  6852   6855               int argumentCount,
  6853   6856               string name,
  6854   6857               SQLiteFunction function
  6855   6858               )
  6856   6859           {
  6857         -            return String.Format("{0}:{1}", argumentCount, name);
         6860  +            return UnsafeNativeMethods.StringFormat(
         6861  +                CultureInfo.InvariantCulture,
         6862  +                "{0}:{1}", argumentCount, name);
  6858   6863           }
  6859   6864           #endregion
  6860   6865   
  6861   6866           ///////////////////////////////////////////////////////////////////////
  6862   6867   
  6863   6868           #region Table Declaration Helper Methods
  6864   6869           /// <summary>
................................................................................
  8675   8680                   catch (Exception e)
  8676   8681                   {
  8677   8682                       try
  8678   8683                       {
  8679   8684                           if (LogExceptionsNoThrow)
  8680   8685                           {
  8681   8686                               SQLiteLog.LogMessage(SQLiteBase.COR_E_EXCEPTION,
  8682         -                                String.Format(CultureInfo.CurrentCulture,
         8687  +                                UnsafeNativeMethods.StringFormat(
         8688  +                                CultureInfo.CurrentCulture,
  8683   8689                                   "Caught exception in \"Dispose\" method: {0}",
  8684   8690                                   e)); /* throw */
  8685   8691                           }
  8686   8692                       }
  8687   8693                       catch
  8688   8694                       {
  8689   8695                           // do nothing.

Changes to System.Data.SQLite/SQLiteModuleCommon.cs.

    19     19       public class SQLiteModuleCommon : SQLiteModuleNoop /* NOT SEALED */
    20     20       {
    21     21           #region Private Constants
    22     22           /// <summary>
    23     23           /// The CREATE TABLE statement used to declare the schema for the
    24     24           /// virtual table.
    25     25           /// </summary>
    26         -        private static readonly string declareSql = String.Format(
    27         -            CultureInfo.CurrentCulture, "CREATE TABLE {0}(x);",
    28         -            typeof(SQLiteModuleCommon).Name);
           26  +        private static readonly string declareSql =
           27  +            UnsafeNativeMethods.StringFormat(
           28  +                CultureInfo.InvariantCulture, "CREATE TABLE {0}(x);",
           29  +                typeof(SQLiteModuleCommon).Name);
    29     30           #endregion
    30     31   
    31     32           ///////////////////////////////////////////////////////////////////////
    32     33   
    33     34           #region Private Data
    34     35           /// <summary>
    35     36           /// Non-zero if different object instances with the same value should
................................................................................
   114    115           protected virtual SQLiteErrorCode CursorTypeMismatchError(
   115    116               SQLiteVirtualTableCursor cursor,
   116    117               Type type
   117    118               )
   118    119           {
   119    120               if (type != null)
   120    121               {
   121         -                SetCursorError(cursor,
   122         -                    String.Format("not a \"{0}\" cursor", type));
          122  +                SetCursorError(cursor, UnsafeNativeMethods.StringFormat(
          123  +                    CultureInfo.CurrentCulture, "not a \"{0}\" cursor",
          124  +                    type));
   123    125               }
   124    126               else
   125    127               {
   126    128                   SetCursorError(cursor, "cursor type mismatch");
   127    129               }
   128    130   
   129    131               return SQLiteErrorCode.Error;

Changes to System.Data.SQLite/SQLiteModuleEnumerable.cs.

   499    499               SQLiteIndex index
   500    500               )
   501    501           {
   502    502               CheckDisposed();
   503    503   
   504    504               if (!table.BestIndex(index))
   505    505               {
   506         -                SetTableError(table, String.Format(CultureInfo.CurrentCulture,
          506  +                SetTableError(table, UnsafeNativeMethods.StringFormat(
          507  +                    CultureInfo.CurrentCulture,
   507    508                       "failed to select best index for virtual table \"{0}\"",
   508    509                       table.TableName));
   509    510   
   510    511                   return SQLiteErrorCode.Error;
   511    512               }
   512    513   
   513    514               return SQLiteErrorCode.Ok;
................................................................................
   826    827               SQLiteVirtualTable table,
   827    828               SQLiteValue[] values,
   828    829               ref long rowId
   829    830               )
   830    831           {
   831    832               CheckDisposed();
   832    833   
   833         -            SetTableError(table, String.Format(CultureInfo.CurrentCulture,
          834  +            SetTableError(table, UnsafeNativeMethods.StringFormat(
          835  +                CultureInfo.CurrentCulture,
   834    836                   "virtual table \"{0}\" is read-only", table.TableName));
   835    837   
   836    838               return SQLiteErrorCode.Error;
   837    839           }
   838    840   
   839    841           ///////////////////////////////////////////////////////////////////////
   840    842   
................................................................................
   855    857               string newName
   856    858               )
   857    859           {
   858    860               CheckDisposed();
   859    861   
   860    862               if (!table.Rename(newName))
   861    863               {
   862         -                SetTableError(table, String.Format(CultureInfo.CurrentCulture,
          864  +                SetTableError(table, UnsafeNativeMethods.StringFormat(
          865  +                    CultureInfo.CurrentCulture,
   863    866                       "failed to rename virtual table from \"{0}\" to \"{1}\"",
   864    867                       table.TableName, newName));
   865    868   
   866    869                   return SQLiteErrorCode.Error;
   867    870               }
   868    871   
   869    872               return SQLiteErrorCode.Ok;

Changes to System.Data.SQLite/SQLiteParameterCollection.cs.

   423    423   
   424    424         foreach(SQLiteParameter p in _parameterList)
   425    425         {
   426    426           y ++;
   427    427           s = p.ParameterName;
   428    428           if (s == null)
   429    429           {
   430         -          s = String.Format(CultureInfo.InvariantCulture, ";{0}", nUnnamed);
          430  +          s = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, ";{0}", nUnnamed);
   431    431             nUnnamed++;
   432    432           }
   433    433   
   434    434           int x;
   435    435           bool isMapped = false;
   436    436   
   437    437           if (activeStatement == null)
................................................................................
   452    452             stmt = null;
   453    453           }
   454    454   
   455    455           // If the parameter has a name, but the SQL statement uses unnamed references, this can happen -- attempt to map
   456    456           // the parameter by its index in the collection
   457    457           if (isMapped == false)
   458    458           {
   459         -          s = String.Format(CultureInfo.InvariantCulture, ";{0}", y);
          459  +          s = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, ";{0}", y);
   460    460   
   461    461             stmt = activeStatement;
   462    462             for (n = 0; n < x; n++)
   463    463             {
   464    464               if (stmt == null) stmt = _command._statementList[n];
   465    465               if (stmt._paramNames != null)
   466    466               {

Changes to System.Data.SQLite/SQLiteStatement.cs.

     1      1   /********************************************************
     2      2    * ADO.NET 2.0 Data Provider for SQLite Version 3.X
     3      3    * Written by Robert Simpson (robert@blackcastlesoft.com)
     4         - * 
            4  + *
     5      5    * Released to the public domain, use at your own risk!
     6      6    ********************************************************/
     7      7   
     8      8   namespace System.Data.SQLite
     9      9   {
    10     10     using System;
    11     11     using System.Globalization;
................................................................................
    81     81           _paramValues = new SQLiteParameter[n];
    82     82   
    83     83           for (x = 0; x < n; x++)
    84     84           {
    85     85             s = _sql.Bind_ParamName(this, _flags, x + 1);
    86     86             if (String.IsNullOrEmpty(s))
    87     87             {
    88         -            s = String.Format(CultureInfo.InvariantCulture, ";{0}", nCmdStart);
           88  +            s = UnsafeNativeMethods.StringFormat(CultureInfo.InvariantCulture, ";{0}", nCmdStart);
    89     89               nCmdStart++;
    90     90               _unnamedParameters++;
    91     91             }
    92     92             _paramNames[x] = s;
    93     93             _paramValues[x] = null;
    94     94           }
    95     95         }
................................................................................
   200    200       /// this statement, and if so, keeps a reference to the parameter so it can be bound later.
   201    201       /// </summary>
   202    202       /// <param name="s">The parameter name to map</param>
   203    203       /// <param name="p">The parameter to assign it</param>
   204    204       internal bool MapParameter(string s, SQLiteParameter p)
   205    205       {
   206    206         if (_paramNames == null) return false;
   207         -      
          207  +
   208    208         int startAt = 0;
   209    209         if (s.Length > 0)
   210    210         {
   211    211           if (":$@;".IndexOf(s[0]) == -1)
   212    212             startAt = 1;
   213    213         }
   214    214   
................................................................................
   254    254         if ((obj != null) && (objType == DbType.Object))
   255    255             objType = SQLiteConvert.TypeToDbType(obj.GetType());
   256    256   
   257    257         if ((_flags & SQLiteConnectionFlags.LogPreBind) == SQLiteConnectionFlags.LogPreBind)
   258    258         {
   259    259             IntPtr handle = _sqlite_stmt;
   260    260   
   261         -          SQLiteLog.LogMessage(String.Format(
          261  +          SQLiteLog.LogMessage(UnsafeNativeMethods.StringFormat(
          262  +              CultureInfo.CurrentCulture,
   262    263                 "Binding statement {0} paramter #{1} with database type {2} and raw value {{{3}}}...",
   263    264                 handle, index, objType, obj));
   264    265         }
   265    266   
   266    267         if ((obj == null) || Convert.IsDBNull(obj))
   267    268         {
   268    269             _sql.Bind_Null(this, _flags, index);

Changes to System.Data.SQLite/UnsafeNativeMethods.cs.

   117    117         /// <summary>
   118    118         /// For now, this method simply calls the Initialize method.
   119    119         /// </summary>
   120    120         static UnsafeNativeMethods()
   121    121         {
   122    122             Initialize();
   123    123         }
          124  +
          125  +      /////////////////////////////////////////////////////////////////////////
          126  +
          127  +      /// <summary>
          128  +      /// This type is only present when running on Mono.
          129  +      /// </summary>
          130  +      private static readonly string MonoRuntimeType = "Mono.Runtime";
          131  +
          132  +      /// <summary>
          133  +      /// Keeps track of whether we are running on Mono.  Initially null, it is
          134  +      /// set by the <see cref="IsMono" /> method on its first call.  Later, it
          135  +      /// is returned verbatim by the <see cref="IsMono" /> method.
          136  +      /// </summary>
          137  +      private static bool? isMono = null;
          138  +
          139  +      /// <summary>
          140  +      /// Determines whether or not this assembly is running on Mono.
          141  +      /// </summary>
          142  +      /// <returns>
          143  +      /// Non-zero if this assembly is running on Mono.
          144  +      /// </returns>
          145  +      private static bool IsMono()
          146  +      {
          147  +          try
          148  +          {
          149  +              lock (staticSyncRoot)
          150  +              {
          151  +                  if (isMono == null)
          152  +                      isMono = (Type.GetType(MonoRuntimeType) != null);
          153  +
          154  +                  return (bool)isMono;
          155  +              }
          156  +          }
          157  +          catch
          158  +          {
          159  +              // do nothing.
          160  +          }
          161  +
          162  +          return false;
          163  +      }
          164  +
          165  +      /////////////////////////////////////////////////////////////////////////
          166  +
          167  +      /// <summary>
          168  +      /// This is a wrapper around the
          169  +      /// <see cref="String.Format(IFormatProvider,String,Object[])" /> method.
          170  +      /// On Mono, it has to call the method overload without the
          171  +      /// <see cref="IFormatProvider" /> parameter, due to a bug in Mono.
          172  +      /// </summary>
          173  +      /// <param name="provider">
          174  +      /// This is used for culture-specific formatting.
          175  +      /// </param>
          176  +      /// <param name="format">
          177  +      /// The format string.
          178  +      /// </param>
          179  +      /// <param name="args">
          180  +      /// An array the objects to format.
          181  +      /// </param>
          182  +      /// <returns>
          183  +      /// The resulting string.
          184  +      /// </returns>
          185  +      internal static string StringFormat(
          186  +          IFormatProvider provider,
          187  +          string format,
          188  +          params object[] args
          189  +          )
          190  +      {
          191  +          if (IsMono())
          192  +              return String.Format(format, args);
          193  +          else
          194  +              return String.Format(provider, format, args);
          195  +      }
   124    196   
   125    197         /////////////////////////////////////////////////////////////////////////
   126    198         /// <summary>
   127    199         /// Attempts to initialize this class by pre-loading the native SQLite
   128    200         /// library for the processor architecture of the current process.
   129    201         /// </summary>
   130    202         internal static void Initialize()
................................................................................
   297    369   #if !PLATFORM_COMPACTFRAMEWORK
   298    370             bool expand = true;
   299    371   
   300    372             if (Environment.GetEnvironmentVariable("No_Expand") != null)
   301    373             {
   302    374                 expand = false;
   303    375             }
   304         -          else if (Environment.GetEnvironmentVariable(String.Format(
   305         -                  "No_Expand_{0}", name)) != null)
          376  +          else if (Environment.GetEnvironmentVariable(StringFormat(
          377  +                  CultureInfo.InvariantCulture, "No_Expand_{0}",
          378  +                  name)) != null)
   306    379             {
   307    380                 expand = false;
   308    381             }
   309    382   
   310    383             value = Environment.GetEnvironmentVariable(name);
   311    384   
   312    385             if (expand && !String.IsNullOrEmpty(value))
................................................................................
   323    396                 if (fileName == null)
   324    397                     return @default;
   325    398   
   326    399                 XmlDocument document = new XmlDocument();
   327    400   
   328    401                 document.Load(fileName);
   329    402   
   330         -              XmlElement element = document.SelectSingleNode(String.Format(
          403  +              XmlElement element = document.SelectSingleNode(StringFormat(
          404  +                  CultureInfo.InvariantCulture,
   331    405                     "/configuration/appSettings/add[@key='{0}']", name)) as
   332    406                     XmlElement;
   333    407   
   334    408                 if (element != null)
   335    409                 {
   336    410                     if (element.HasAttribute("value"))
   337    411                         value = element.GetAttribute("value");
................................................................................
   350    424   #else
   351    425             catch (Exception)
   352    426   #endif
   353    427             {
   354    428   #if !NET_COMPACT_20 && TRACE_SHARED
   355    429                 try
   356    430                 {
   357         -                  Trace.WriteLine(String.Format(
          431  +                  Trace.WriteLine(StringFormat(
   358    432                         CultureInfo.CurrentCulture,
   359    433                         "Native library pre-loader failed to get setting " +
   360    434                         "\"{0}\" value: {1}", name, e)); /* throw */
   361    435                 }
   362    436                 catch
   363    437                 {
   364    438                     // do nothing.
................................................................................
   466    540                     directory, XmlConfigFileName);
   467    541   
   468    542                 if (File.Exists(xmlConfigFileName))
   469    543                 {
   470    544   #if !NET_COMPACT_20 && TRACE_DETECTION
   471    545                     try
   472    546                     {
   473         -                      Trace.WriteLine(String.Format(
          547  +                      Trace.WriteLine(StringFormat(
   474    548                             CultureInfo.CurrentCulture,
   475    549                             "Native library pre-loader found XML configuration file " +
   476    550                             "via code base for currently executing assembly: \"{0}\"",
   477    551                             xmlConfigFileName)); /* throw */
   478    552                     }
   479    553                     catch
   480    554                     {
................................................................................
   489    563                 List<string> matches = null;
   490    564   
   491    565                 if (CheckForArchitecturesAndPlatforms(directory, ref matches) > 0)
   492    566                 {
   493    567   #if !NET_COMPACT_20 && TRACE_DETECTION
   494    568                     try
   495    569                     {
   496         -                      Trace.WriteLine(String.Format(
          570  +                      Trace.WriteLine(StringFormat(
   497    571                             CultureInfo.CurrentCulture,
   498    572                             "Native library pre-loader found native sub-directories " +
   499    573                             "via code base for currently executing assembly: \"{0}\"",
   500    574                             ListToString(matches))); /* throw */
   501    575                     }
   502    576                     catch
   503    577                     {
................................................................................
   516    590   #else
   517    591             catch (Exception)
   518    592   #endif
   519    593             {
   520    594   #if !NET_COMPACT_20 && TRACE_SHARED
   521    595                 try
   522    596                 {
   523         -                  Trace.WriteLine(String.Format(
          597  +                  Trace.WriteLine(StringFormat(
   524    598                         CultureInfo.CurrentCulture,
   525    599                         "Native library pre-loader failed to check code base " +
   526    600                         "for currently executing assembly: {0}", e)); /* throw */
   527    601                 }
   528    602                 catch
   529    603                 {
   530    604                     // do nothing.
................................................................................
   583    657   #else
   584    658             catch (Exception)
   585    659   #endif
   586    660             {
   587    661   #if !NET_COMPACT_20 && TRACE_SHARED
   588    662                 try
   589    663                 {
   590         -                  Trace.WriteLine(String.Format(
          664  +                  Trace.WriteLine(StringFormat(
   591    665                         CultureInfo.CurrentCulture,
   592    666                         "Native library pre-loader failed to get directory " +
   593    667                         "for currently executing assembly: {0}", e)); /* throw */
   594    668                 }
   595    669                 catch
   596    670                 {
   597    671                     // do nothing.
................................................................................
   953   1027   #if !NET_COMPACT_20 && TRACE_DETECTION
   954   1028                 try
   955   1029                 {
   956   1030                     //
   957   1031                     // NOTE: Show that we hit a fairly unusual situation (i.e.
   958   1032                     //       the "wrong" processor architecture was detected).
   959   1033                     //
   960         -                  Trace.WriteLine(String.Format(
         1034  +                  Trace.WriteLine(StringFormat(
   961   1035                         CultureInfo.CurrentCulture,
   962   1036                         "Native library pre-loader detected {0}-bit pointer " +
   963   1037                         "size with processor architecture \"{1}\", using " +
   964   1038                         "processor architecture \"{2}\" instead...",
   965   1039                         IntPtr.Size * 8 /* bits */, savedProcessorArchitecture,
   966   1040                         processorArchitecture)); /* throw */
   967   1041                 }
................................................................................
  1172   1246   #if !NET_COMPACT_20 && TRACE_PRELOAD
  1173   1247                 try
  1174   1248                 {
  1175   1249                     //
  1176   1250                     // NOTE: Show exactly where we are trying to load the native
  1177   1251                     //       SQLite library from.
  1178   1252                     //
  1179         -                  Trace.WriteLine(String.Format(
         1253  +                  Trace.WriteLine(StringFormat(
  1180   1254                         CultureInfo.CurrentCulture,
  1181   1255                         "Native library pre-loader is trying to load native " +
  1182   1256                         "SQLite library \"{0}\"...", fileName)); /* throw */
  1183   1257                 }
  1184   1258                 catch
  1185   1259                 {
  1186   1260                     // do nothing.
................................................................................
  1212   1286                     int lastError = Marshal.GetLastWin32Error(); /* throw */
  1213   1287   
  1214   1288                     //
  1215   1289                     // NOTE: Show where we failed to load the native SQLite
  1216   1290                     //       library from along with the Win32 error code and
  1217   1291                     //       exception information.
  1218   1292                     //
  1219         -                  Trace.WriteLine(String.Format(
         1293  +                  Trace.WriteLine(StringFormat(
  1220   1294                         CultureInfo.CurrentCulture,
  1221   1295                         "Native library pre-loader failed to load native " +
  1222   1296                         "SQLite library \"{0}\" (getLastError = {1}): {2}",
  1223   1297                         fileName, lastError, e)); /* throw */
  1224   1298                 }
  1225   1299                 catch
  1226   1300                 {
................................................................................
  2952   3026                   if (localHandle != IntPtr.Zero)
  2953   3027                       SQLiteBase.CloseConnection(this, localHandle);
  2954   3028   #endif
  2955   3029   
  2956   3030   #if !NET_COMPACT_20 && TRACE_HANDLE
  2957   3031                   try
  2958   3032                   {
  2959         -                    Trace.WriteLine(String.Format(
         3033  +                    Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  2960   3034                           CultureInfo.CurrentCulture,
  2961   3035                           "CloseConnection: {0}", localHandle)); /* throw */
  2962   3036                   }
  2963   3037                   catch
  2964   3038                   {
  2965   3039                   }
  2966   3040   #endif
................................................................................
  2987   3061   #else
  2988   3062               catch (SQLiteException)
  2989   3063   #endif
  2990   3064               {
  2991   3065   #if !NET_COMPACT_20 && TRACE_HANDLE
  2992   3066                   try
  2993   3067                   {
  2994         -                    Trace.WriteLine(String.Format(
         3068  +                    Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  2995   3069                           CultureInfo.CurrentCulture,
  2996   3070                           "CloseConnection: {0}, exception: {1}",
  2997   3071                           handle, e)); /* throw */
  2998   3072                   }
  2999   3073                   catch
  3000   3074                   {
  3001   3075                   }
................................................................................
  3140   3214   
  3141   3215                   if (localHandle != IntPtr.Zero)
  3142   3216                       SQLiteBase.FinalizeStatement(cnn, localHandle);
  3143   3217   
  3144   3218   #if !NET_COMPACT_20 && TRACE_HANDLE
  3145   3219                   try
  3146   3220                   {
  3147         -                    Trace.WriteLine(String.Format(
         3221  +                    Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  3148   3222                           CultureInfo.CurrentCulture,
  3149   3223                           "FinalizeStatement: {0}", localHandle)); /* throw */
  3150   3224                   }
  3151   3225                   catch
  3152   3226                   {
  3153   3227                   }
  3154   3228   #endif
................................................................................
  3175   3249   #else
  3176   3250               catch (SQLiteException)
  3177   3251   #endif
  3178   3252               {
  3179   3253   #if !NET_COMPACT_20 && TRACE_HANDLE
  3180   3254                   try
  3181   3255                   {
  3182         -                    Trace.WriteLine(String.Format(
         3256  +                    Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  3183   3257                           CultureInfo.CurrentCulture,
  3184   3258                           "FinalizeStatement: {0}, exception: {1}",
  3185   3259                           handle, e)); /* throw */
  3186   3260                   }
  3187   3261                   catch
  3188   3262                   {
  3189   3263                   }
................................................................................
  3313   3387   
  3314   3388                   if (localHandle != IntPtr.Zero)
  3315   3389                       SQLiteBase.FinishBackup(cnn, localHandle);
  3316   3390   
  3317   3391   #if !NET_COMPACT_20 && TRACE_HANDLE
  3318   3392                   try
  3319   3393                   {
  3320         -                    Trace.WriteLine(String.Format(
         3394  +                    Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  3321   3395                           CultureInfo.CurrentCulture,
  3322   3396                           "FinishBackup: {0}", localHandle)); /* throw */
  3323   3397                   }
  3324   3398                   catch
  3325   3399                   {
  3326   3400                   }
  3327   3401   #endif
................................................................................
  3348   3422   #else
  3349   3423               catch (SQLiteException)
  3350   3424   #endif
  3351   3425               {
  3352   3426   #if !NET_COMPACT_20 && TRACE_HANDLE
  3353   3427                   try
  3354   3428                   {
  3355         -                    Trace.WriteLine(String.Format(
         3429  +                    Trace.WriteLine(UnsafeNativeMethods.StringFormat(
  3356   3430                           CultureInfo.CurrentCulture,
  3357   3431                           "FinishBackup: {0}, exception: {1}",
  3358   3432                           handle, e)); /* throw */
  3359   3433                   }
  3360   3434                   catch
  3361   3435                   {
  3362   3436                   }

Changes to Tests/authorizer.eagle.

   120    120       set filter $name; set data [list]
   121    121       set code [catch {sql execute $db $value} result]
   122    122       set result [lindex [split [string map [list \r\n \n] $result] \n] 0]
   123    123       lappend results [list $name $data $code $result]
   124    124     }
   125    125     lappend results [isTableInDb tDeny]
   126    126   
   127         -  set results
          127  +  string map \
          128  +      [list "SQLiteException (0x80004005):" "SQLiteException:"] $results
   128    129   } -cleanup {
   129    130     catch {object invoke $connection remove_Authorize $callback}
   130    131     catch {object removecallback $callback}
   131    132   
   132    133     cleanupDb $fileName
   133    134   
   134    135     freeDbConnection
................................................................................
   157    158   {{0 DropIndex i1 t1 main {}}} 0 0} {Recursive {{0 Recursive {} {} {} {}}} 0 -1}\
   158    159   {DropTable {{0 DropTable t1 {} main {}}} 0 0} {Transaction {{0 Transaction\
   159    160   BEGIN {} {} {}} {0 Transaction COMMIT {} {} {}}} 0 -1} {Savepoint {{0 Savepoint\
   160    161   BEGIN s1 {} {}} {0 Savepoint RELEASE s1 {} {}}} 0 -1} {Attach {{0 Attach\
   161    162   :memory: {} {} {}}} 0 -1} {Detach {{0 Detach d1 {} {} {}}} 0 -1} {CreateVtable\
   162    163   {{0 CreateVtable t3 fts4 main {}}} 0 0} {DropVtable {{0 DropVtable t3 fts4 main\
   163    164   {}}} 0 0} {CreateTable {{0 CreateTable tDeny {} main {}}} 1\
   164         -{System.Data.SQLite.SQLiteException (0x80004005): authorization denied}} False}}
          165  +{System.Data.SQLite.SQLiteException: authorization denied}} False}}
   165    166   
   166    167   ###############################################################################
   167    168   
   168    169   runSQLiteTestEpilogue
   169    170   runTestEpilogue

Changes to Tests/basic.eagle.

  1570   1570         BuildTempSchema $connection
  1571   1571   } -cleanup {
  1572   1572     cleanupDb $fileName
  1573   1573   
  1574   1574     freeDbConnection
  1575   1575   
  1576   1576     unset -nocomplain providerServices connection db fileName
  1577         -} -constraints {eagle command.object SQLite System.Data.SQLite\
         1577  +} -constraints {eagle monoToDo command.object SQLite System.Data.SQLite\
  1578   1578   System.Data.SQLite.Linq} -result {}}
  1579   1579   
  1580   1580   ###############################################################################
  1581   1581   
  1582   1582   runTest {test data-1.30 {EF6 ISQLiteSchemaExtensions.BuildTempSchema} -setup {
  1583   1583     setupDb [set fileName data-1.30.db]
  1584   1584   } -body {
................................................................................
  1592   1592         BuildTempSchema $connection
  1593   1593   } -cleanup {
  1594   1594     cleanupDb $fileName
  1595   1595   
  1596   1596     freeDbConnection
  1597   1597   
  1598   1598     unset -nocomplain providerServices connection db fileName
  1599         -} -constraints {eagle command.object SQLite System.Data.SQLite\
         1599  +} -constraints {eagle monoToDo command.object SQLite System.Data.SQLite\
  1600   1600   System.Data.SQLite.EF6} -result {}}
  1601   1601   
  1602   1602   ###############################################################################
  1603   1603   
  1604   1604   runTest {test data-1.31 {VARCHAR / NVARCHAR types with spaces} -body {
  1605   1605     list [object invoke -flags +NonPublic System.Data.SQLite.SQLiteConvert \
  1606   1606         TypeNameToDbType null VARCHAR None] \
................................................................................
  2379   2379         "SELECT replicate('1234', 4);"} output] $output
  2380   2380   
  2381   2381     set result
  2382   2382   } -cleanup {
  2383   2383     cleanupDb $fileName
  2384   2384   
  2385   2385     unset -nocomplain output result db fileName
  2386         -} -constraints \
  2387         -{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} -match \
  2388         -regexp -result {^0 12341234 1 \{System\.Data\.SQLite\.SQLiteException\
  2389         -\(0x80004005\): SQL logic error or missing database.*?\} 0 1234123412341234$}}
         2386  +} -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
         2387  +System.Data.SQLite SQLiteInterop\
         2388  +defineConstant.System.Data.SQLite.INTEROP_EXTENSION_FUNCTIONS} -match regexp \
         2389  +-result {^0 12341234 1 \{System\.Data\.SQLite\.SQLiteException \(0x80004005\):\
         2390  +SQL logic error or missing database.*?\} 0 1234123412341234$}}
  2390   2391   
  2391   2392   ###############################################################################
  2392   2393   
  2393   2394   runTest {test data-1.50 {column name and index lookup} -setup {
  2394   2395     setupDb [set fileName data-1.50.db]
  2395   2396   } -body {
  2396   2397     sql execute $db {
................................................................................
  2694   2695   
  2695   2696     unset -nocomplain result connection
  2696   2697   
  2697   2698     cleanupDb $fileName
  2698   2699   
  2699   2700     unset -nocomplain db fileName
  2700   2701   } -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
  2701         -System.Data.SQLite} -result {1 {} 1.01 {}}}
         2702  +System.Data.SQLite SQLiteInterop} -result {1 {} 1.01 {}}}
  2702   2703   
  2703   2704   ###############################################################################
  2704   2705   
  2705   2706   runTest {test data-1.57 {regexp extension} -setup {
  2706   2707     setupDb [set fileName data-1.57.db]
  2707   2708   } -body {
  2708   2709     unset -nocomplain pattern result
................................................................................
  2754   2755   
  2755   2756     unset -nocomplain pattern result connection
  2756   2757   
  2757   2758     cleanupDb $fileName
  2758   2759   
  2759   2760     unset -nocomplain db fileName
  2760   2761   } -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
  2761         -System.Data.SQLite} -result {0 1 1 {unmatched '('} 0 1 1 {unmatched '('} 0 0 1\
  2762         -{unmatched '('} 0 0 1 {unmatched '('}}}
         2762  +System.Data.SQLite SQLiteInterop} -result {0 1 1 {unmatched '('} 0 1 1\
         2763  +{unmatched '('} 0 0 1 {unmatched '('} 0 0 1 {unmatched '('}}}
  2763   2764   
  2764   2765   ###############################################################################
  2765   2766   
  2766   2767   reportSQLiteResources $test_channel
  2767   2768   
  2768   2769   ###############################################################################
  2769   2770   
................................................................................
  2836   2837   
  2837   2838     unset -nocomplain result connection
  2838   2839   
  2839   2840     cleanupDb $fileName
  2840   2841   
  2841   2842     unset -nocomplain db fileName
  2842   2843   } -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
  2843         -System.Data.SQLite} -result {0 4 -1 1.75}}
         2844  +System.Data.SQLite SQLiteInterop} -result {0 4 -1 1.75}}
  2844   2845   
  2845   2846   ###############################################################################
  2846   2847   
  2847   2848   runTest {test data-1.60 {per-connection type mappings} -setup {
  2848   2849     setupDb [set fileName data-1.60.db] "" "" "" UseConnectionTypes
  2849   2850   } -body {
  2850   2851     set connection [getDbConnection]
................................................................................
  3168   3169     cleanupDb $fileName
  3169   3170     restoreSQLiteConnectionEnvironment
  3170   3171   
  3171   3172     freeDbConnection
  3172   3173   
  3173   3174     unset -nocomplain connection db fileName
  3174   3175   } -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
  3175         -System.Data.SQLite} -result {Default Default}}
         3176  +System.Data.SQLite} -match regexp -result \
         3177  +{^Default Default|LogCallbackException LogCallbackException$}}
  3176   3178   
  3177   3179   ###############################################################################
  3178   3180   
  3179   3181   runTest {test data-1.69 {set env(DefaultFlags_SQLiteConnection)} -setup {
  3180   3182     saveSQLiteConnectionEnvironment
  3181   3183   
  3182   3184     set env(DefaultFlags_SQLiteConnection) "DetectTextAffinity, DetectStringType"
................................................................................
  3276   3278   
  3277   3279     unset -nocomplain x result connection
  3278   3280   
  3279   3281     cleanupDb $fileName
  3280   3282   
  3281   3283     unset -nocomplain db fileName
  3282   3284   } -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
  3283         -System.Data.SQLite} -match regexp -result {^\{fts5: \d{4}-\d{2}-\d{2}\
  3284         -\d{2}:\d{2}:\d{2} [0-9a-f]{40}\} \{\} \{\} \{\} \{\} \{\} \{rowid 3 x horse\
  3285         -rowid 4 x house\}$}}
         3285  +System.Data.SQLite SQLiteInterop} -match regexp -result \
         3286  +{^\{fts5: \d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [0-9a-f]{40}\} \{\} \{\} \{\}\
         3287  +\{\} \{\} \{rowid 3 x horse rowid 4 x house\}$}}
  3286   3288   
  3287   3289   ###############################################################################
  3288   3290   
  3289   3291   runTest {test data-1.72 {unbind function from a connection} -setup {
  3290   3292     set fileName data-1.72.db
  3291   3293   } -body {
  3292   3294     set id [object invoke Interpreter.GetActive NextId]

Changes to Tests/linq.eagle.

    87     87     } else {
    88     88       lappend result [string trim $error]
    89     89     }
    90     90   
    91     91     set result
    92     92   } -cleanup {
    93     93     unset -nocomplain code output error result
    94         -} -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll testExec\
    95         -file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} \
    96         --result {0 {{ NewUnitPrice = 21.0 } { NewUnitPrice = 21.1 } { NewUnitPrice =\
    97         -21.05 } { NewUnitPrice = 23.0 } { NewUnitPrice = 23.3 } { NewUnitPrice = 23.25\
    98         -} { NewUnitPrice = 21.0 } { NewUnitPrice = 21.4 } { NewUnitPrice = 21.35 }}}}
           94  +} -constraints {eagle System.Data.SQLite.dll_v4.0.30319 monoToDo SQLite\
           95  +file_System.Data.SQLite.dll testExec file_System.Data.SQLite.Linq.dll\
           96  +file_testlinq.exe file_northwindEF.db} -result {0 {{ NewUnitPrice = 21.0 } {\
           97  +NewUnitPrice = 21.1 } { NewUnitPrice = 21.05 } { NewUnitPrice = 23.0 } {\
           98  +NewUnitPrice = 23.3 } { NewUnitPrice = 23.25 } { NewUnitPrice = 21.0 } {\
           99  +NewUnitPrice = 21.4 } { NewUnitPrice = 21.35 }}}}
    99    100   
   100    101   ###############################################################################
   101    102   
   102    103   runSQLiteTestFilesEpilogue
   103    104   runSQLiteTestEpilogue
   104    105   runTestEpilogue

Changes to Tests/speed.eagle.

   172    172     }
   173    173   
   174    174     set result
   175    175   } -cleanup {
   176    176     cleanupDb $fileName
   177    177   
   178    178     unset -nocomplain time sql table column result char db fileName
   179         -} -time true -constraints {eagle monoBug28 command.sql compile.DATA SQLite\
          179  +} -time true -constraints {eagle monoBug40 command.sql compile.DATA SQLite\
   180    180   System.Data.SQLite} -result {3 3 3 3}}
   181    181   
   182    182   ###############################################################################
   183    183   
   184    184   #
   185    185   # NOTE: Report after test.
   186    186   #

Changes to Tests/stress.eagle.

  1643   1643     rename cleanupLogging ""
  1644   1644     rename setupLogging ""
  1645   1645   
  1646   1646     unset -nocomplain result thread index workload priority noWorkload \
  1647   1647         priorities srcDb db fileName compiled options count times logFileName \
  1648   1648         logListener event timeout connection indicators iterations exitOnFail \
  1649   1649         coTaskMem noTrace failures status workloadNames workloadCallbacks
  1650         -} -time true -constraints {eagle command.object monoBug28 command.sql\
         1650  +} -time true -constraints {eagle command.object monoBug40 command.sql\
  1651   1651   compile.DATA SQLite System.Data.SQLite compileCSharp} -result {0}}
  1652   1652   
  1653   1653   ###############################################################################
  1654   1654   
  1655   1655   #
  1656   1656   # NOTE: Report after test.
  1657   1657   #

Changes to Tests/tkt-47c6fa04d3.eagle.

   113    113         [expr {$code eq "Ok" ? [catch {
   114    114           object invoke -alias _Dynamic${id}.Test${id} GetDataTable
   115    115         } result] : [set result ""]}] $result [getRowsFromDataTable $result]
   116    116   } -cleanup {
   117    117     cleanupDb $fileName
   118    118   
   119    119     unset -nocomplain result results errors code sql dataSource id db fileName
   120         -} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
          120  +} -constraints {eagle command.object monoBug40 command.sql compile.DATA SQLite\
   121    121   System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
   122    122   System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 System#Data#DataTable#\d+\
   123    123   \{\{\{id 2\} \{min 2\} \{max 3\} \{sum 5\}\} \{\{id 2\} \{min 1\} \{max 2\}\
   124    124   \{sum 3\}\}\}$}}
   125    125   
   126    126   ###############################################################################
   127    127   
   128    128   runSQLiteTestEpilogue
   129    129   runTestEpilogue

Changes to Tests/tkt-4a791e70ab.eagle.

    67     67         [expr {$code eq "Ok" ? [catch {
    68     68           object invoke _Dynamic${id}.Test${id} Main
    69     69         } result] : [set result ""]}] $result
    70     70   } -cleanup {
    71     71     cleanupDb $fileName
    72     72   
    73     73     unset -nocomplain result results errors code dataSource id db fileName
    74         -} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
           74  +} -constraints {eagle command.object monoBug40 command.sql compile.DATA SQLite\
    75     75   System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
    76     76   System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 \{\}$}}
    77     77   
    78     78   ###############################################################################
    79     79   
    80     80   runSQLiteTestEpilogue
    81     81   runTestEpilogue

Changes to Tests/tkt-56b42d99c1.eagle.

    95     95         [expr {$code eq "Ok" ? [catch {
    96     96           object invoke _Dynamic${id}.Test${id} TryEnlistInTransaction
    97     97         } result] : [set result ""]}] $result
    98     98   } -cleanup {
    99     99     cleanupDb $fileName
   100    100   
   101    101     unset -nocomplain result results errors code dataSource id db fileName
   102         -} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
          102  +} -constraints {eagle command.object monoBug40 command.sql compile.DATA SQLite\
   103    103   System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
   104    104   System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 True$}}
   105    105   
   106    106   ###############################################################################
   107    107   
   108    108   runTest {test tkt-56b42d99c1-1.2 {enlisted transaction isolation} -setup {
   109    109     setupDb [set fileName tkt-56b42d99c1-1.2.db]
................................................................................
   172    172         [expr {$code eq "Ok" ? [catch {
   173    173           object invoke _Dynamic${id}.Test${id} Main
   174    174         } result] : [set result ""]}] $result
   175    175   } -cleanup {
   176    176     cleanupDb $fileName
   177    177   
   178    178     unset -nocomplain result results errors code sql dataSource id db fileName
   179         -} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
          179  +} -constraints {eagle command.object monoBug40 command.sql compile.DATA SQLite\
   180    180   System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
   181    181   System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 0$}}
   182    182   
   183    183   ###############################################################################
   184    184   
   185    185   runTest {test tkt-56b42d99c1-1.3 {enlisted transaction isolation} -setup {
   186    186     setupDb [set fileName tkt-56b42d99c1-1.3.db]
................................................................................
   403    403         [expr {$code eq "Ok" ? [catch {
   404    404           object invoke _Dynamic${id}.Test${id} Main
   405    405         } result] : [set result ""]}] $result
   406    406   } -cleanup {
   407    407     cleanupDb $fileName
   408    408   
   409    409     unset -nocomplain result results errors code sql dataSource id db fileName
   410         -} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
          410  +} -constraints {eagle command.object monoBug40 command.sql compile.DATA SQLite\
   411    411   System.Data.SQLite compileCSharp} -match regexp -result {^Ok\
   412    412   System#CodeDom#Compiler#CompilerResults#\d+ \{\} 0 1$}}
   413    413   
   414    414   ###############################################################################
   415    415   
   416    416   set flags MapIsolationLevels
   417    417   

Changes to Tests/tkt-964063da16.eagle.

    25     25         System.Data.SQLite.SQLiteConnection \
    26     26         "Data Source=:memory:;NoDefaultFlags=False;"]
    27     27   
    28     28     $connection Open
    29     29     $connection Flags
    30     30   } -cleanup {
    31     31     unset -nocomplain connection
    32         -} -constraints {eagle command.object SQLite System.Data.SQLite} -result \
    33         -{Default}}
           32  +} -constraints {eagle command.object SQLite System.Data.SQLite} -match regexp \
           33  +-result {^Default|LogCallbackException$}}
    34     34   
    35     35   ###############################################################################
    36     36   
    37     37   runTest {test tkt-964063da16-1.2 {pre-existing connection flags} -body {
    38     38     set connection [object create -alias \
    39     39         System.Data.SQLite.SQLiteConnection \
    40     40         "Data Source=:memory:;NoDefaultFlags=True;"]
................................................................................
    53     53         System.Data.SQLite.SQLiteConnection \
    54     54         "Data Source=:memory:;NoDefaultFlags=False;"]
    55     55   
    56     56     $connection Flags NoExtensionFunctions; $connection Open
    57     57     $connection Flags
    58     58   } -cleanup {
    59     59     unset -nocomplain connection
    60         -} -constraints {eagle command.object SQLite System.Data.SQLite} -result \
    61         -{NoExtensionFunctions, Default}}
           60  +} -constraints {eagle command.object SQLite System.Data.SQLite} -match regexp \
           61  +-result {^Default, NoExtensionFunctions|NoExtensionFunctions,\
           62  +Default|LogCallbackException, NoExtensionFunctions$}}
    62     63   
    63     64   ###############################################################################
    64     65   
    65     66   runTest {test tkt-964063da16-1.4 {pre-existing connection flags} -body {
    66     67     set connection [object create -alias \
    67     68         System.Data.SQLite.SQLiteConnection \
    68     69         "Data Source=:memory:;NoDefaultFlags=True;"]

Changes to Tests/tkt-9d353b0bd8.eagle.

    50     50       lappend result [string trim $error]
    51     51     }
    52     52   
    53     53     set result
    54     54   } -cleanup {
    55     55     unset -nocomplain code output error result
    56     56   } -constraints {eagle monoToDo SQLite file_System.Data.SQLite.dll testExec\
    57         -file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db} \
    58         --result {0 {inserted 1}}}
           57  +file_System.Data.SQLite.Linq.dll file_testlinq.exe file_northwindEF.db\
           58  +System.Data.SQLite.dll_v4.0.30319} -result {0 {inserted 1}}}
    59     59   
    60     60   ###############################################################################
    61     61   
    62     62   runSQLiteTestFilesEpilogue
    63     63   runSQLiteTestEpilogue
    64     64   runTestEpilogue

Changes to Tests/tkt-e06c4caff3.eagle.

    27     27   
    28     28     sql execute $db "INSERT INTO t1 (x) VALUES(?);" \
    29     29         [list param1 Double [set NaN [object invoke Double NaN]]]
    30     30   } -cleanup {
    31     31     cleanupDb $fileName
    32     32   
    33     33     unset -nocomplain NaN db fileName
    34         -} -constraints {eagle command.object monoBug28 command.sql compile.DATA SQLite\
           34  +} -constraints {eagle command.object monoBug40 command.sql compile.DATA SQLite\
    35     35   System.Data.SQLite} -returnCodes 1 -match regexp -result [string map [list \n\
    36     36   \r\n] {^System\.Data\.SQLite\.SQLiteException \(0x80004005\): constraint failed
    37     37   NOT NULL constraint failed: t1\.x
    38     38   .*$}]}
    39     39   
    40     40   ###############################################################################
    41     41   

Changes to Tests/tkt-f8dbab8baf.eagle.

   127    127         [expr {[info exists rows(count)] ? $rows(count) : -1}] \
   128    128         [expr {[info exists rows(names)] ? $rows(names) : ""}]
   129    129   } -cleanup {
   130    130     cleanupDb $fileName
   131    131   
   132    132     unset -nocomplain rows db fileName
   133    133   } -constraints \
   134         -{eagle monoBug28 command.sql compile.DATA SQLite System.Data.SQLite} \
          134  +{eagle monoBug40 command.sql compile.DATA SQLite System.Data.SQLite} \
   135    135   -returnCodes 1 -match regexp -result [string map [list \n \r\n] \
   136    136   {^System\.Data\.SQLite\.SQLiteException \(0x80004005\): SQL logic error or\
   137    137   missing database
   138    138   no such table: t1.*$}]}
   139    139   
   140    140   ###############################################################################
   141    141   
   142    142   runSQLiteTestEpilogue
   143    143   runTestEpilogue

Changes to lib/System.Data.SQLite/common.eagle.

  1519   1519           #       so, make it easy to spot.
  1520   1520           #
  1521   1521           if {[string length $sourceId] == 0} then {
  1522   1522             set sourceId null
  1523   1523           }
  1524   1524   
  1525   1525           #
  1526         -        # NOTE: Yes, the SQLite interop assembly appears to be available.
         1526  +        # NOTE: Before actually adding the test constraint, make sure the
         1527  +        #       version is valid (i.e. not just that we could query it).
  1527   1528           #
  1528         -        addConstraint SQLiteInterop
         1529  +        if {$version ne "null"} then {
         1530  +          #
         1531  +          # NOTE: Yes, the SQLite interop assembly appears to be available.
         1532  +          #
         1533  +          addConstraint SQLiteInterop
  1529   1534   
  1530         -        tputs $channel [appendArgs "yes (" $version " " $sourceId ")\n"]
         1535  +          set answer yes
         1536  +        } else {
         1537  +          set answer no
         1538  +        }
         1539  +
         1540  +        tputs $channel [appendArgs $answer " (" $version " " $sourceId ")\n"]
  1531   1541         } else {
  1532   1542           tputs $channel no\n
  1533   1543         }
  1534   1544       }
  1535   1545   
  1536   1546       proc checkForSQLiteDefineConstant { channel name } {
  1537   1547         tputs $channel [appendArgs \

Changes to readme.htm.

   211    211   <p>
   212    212       <b>1.0.98.0 - August XX, 2015 <font color="red">(release scheduled)</font></b>
   213    213   </p>
   214    214   <ul>
   215    215       <li>Updated to <a href="https://www.sqlite.org/releaselog/3_8_11_1.html">SQLite 3.8.11.1</a>.</li>
   216    216       <li>Add full support for Visual Studio 2015 and the .NET Framework 4.6.</li>
   217    217       <li>Implement the Substring method for LINQ using the &quot;substr&quot; core SQL function.&nbsp;<b>** Potentially Incompatible Change **</b></li>
          218  +    <li>Prevent encrypted connections from being used with the connection pool. Pursuant to [89d3a159f1].&nbsp;<b>** Potentially Incompatible Change **</b></li>
   218    219       <li>Honor the second argument to Math.Round when using LINQ.&nbsp;<b>** Potentially Incompatible Change **</b></li>
   219    220       <li>Honor the pre-existing flags for connections during the Open method. Fix for [964063da16].&nbsp;<b>** Potentially Incompatible Change **</b></li>
   220    221       <li>Remove errant semi-colons from the SQL used by LINQ to INSERT and then SELECT rows with composite primary keys. Fix for [9d353b0bd8].</li>
   221    222       <li>Change the base type for the SQLiteConnectionFlags enumeration to long integer.&nbsp;<b>** Potentially Incompatible Change **</b></li>
   222    223       <li>Add extended return codes to the SQLiteErrorCode enumeration. Pursuant to [71bedaca19].&nbsp;<b>** Potentially Incompatible Change **</b></li>
   223    224       <li>Improve exception handling in all native callbacks implemented in the SQLiteConnection class.</li>
   224    225       <li>Add Progress event and ProgressOps connection string property to enable raising progress events during long-running queries.</li>

Changes to test/TestCases.cs.

    19     19     {
    20     20       private const int NumThreads = 8;
    21     21       private const int ThreadTimeout = 60000;
    22     22   
    23     23       private List<string> droptables = new List<string>();
    24     24       private List<string> maydroptable = new List<string>();
    25     25   
    26         -#if !INTEROP_LOG
           26  +#if !USE_INTEROP_DLL || !INTEROP_LOG
    27     27       private long logevents = 0;
    28     28   #endif
    29     29   
    30     30       internal TestCases()
    31     31       {
    32     32       }
    33     33   
................................................................................
  1636   1636           SQLiteErrorCode rc = cnn.ResultCode();
  1637   1637           SQLiteErrorCode xrc = cnn.ExtendedResultCode();
  1638   1638   
  1639   1639           cnn.Close();
  1640   1640         }
  1641   1641       }
  1642   1642   
  1643         -#if !INTEROP_LOG
         1643  +#if !USE_INTEROP_DLL || !INTEROP_LOG
  1644   1644       //Logging EventHandler
  1645   1645       public void OnLogEvent(object sender, LogEventArgs logEvent)
  1646   1646       {
  1647   1647           object errorCode = logEvent.ErrorCode;
  1648   1648           string err_msg = logEvent.Message;
  1649   1649           logevents++;
  1650   1650       }

Changes to testce/TestCases.cs.

   288    288         try { UserCollation(cnn); frm.WriteLine("SUCCESS - UserCollation"); passed++; }
   289    289         catch (Exception) { frm.WriteLine("FAIL - UserCollation"); failed++; }
   290    290   
   291    291         total++;
   292    292         try { Int64Properties(cnn); frm.WriteLine("SUCCESS - Int64Properties"); passed++; }
   293    293         catch (Exception) { frm.WriteLine("FAIL - Int64Properties"); failed++; }
   294    294   
          295  +#if INTEROP_VIRTUAL_TABLE
   295    296         total++;
   296    297         try { ManagedVirtualTable(cnn); frm.WriteLine("SUCCESS - ManagedVirtualTable"); passed++; }
   297    298         catch (Exception) { frm.WriteLine("FAIL - ManagedVirtualTable"); failed++; }
          299  +#endif
   298    300   
   299    301         total++;
   300    302         try { MultipleThreadStress(cnn); frm.WriteLine("SUCCESS - MultipleThreadStress"); passed++; }
   301    303         catch (Exception) { frm.WriteLine("FAIL - MultipleThreadStress"); failed++; }
   302    304   
   303    305         total++;
   304    306         try { SimpleRTree(cnn); frm.WriteLine("SUCCESS - SimpleRTree"); passed++; }
................................................................................
  1035   1037   
  1036   1038               return;
  1037   1039           }
  1038   1040   
  1039   1041           throw new NotSupportedException("not a SQLite connection");
  1040   1042       }
  1041   1043   
         1044  +#if INTEROP_VIRTUAL_TABLE
  1042   1045       // Make sure that managed virtual table support works on the .NET Compact Framework.
  1043   1046       internal void ManagedVirtualTable(DbConnection cnn)
  1044   1047       {
  1045   1048           SQLiteConnection cnn2 = cnn as SQLiteConnection;
  1046   1049   
  1047   1050           if (cnn2 != null)
  1048   1051           {
................................................................................
  1095   1098               }
  1096   1099   
  1097   1100               return;
  1098   1101           }
  1099   1102   
  1100   1103           throw new NotSupportedException("not a SQLite connection");
  1101   1104       }
         1105  +#endif
  1102   1106   
  1103   1107       private int nextId = 0;
  1104   1108       private const int MAX_THREADS = 3;
  1105   1109       private const int MAX_ITERATIONS = 100;
  1106   1110       private ManualResetEvent goEvent = new ManualResetEvent(false);
  1107   1111   
  1108   1112       private static int GetThreadId()

Changes to testce/testce.2005.csproj.

   101    101     </ItemGroup>
   102    102     <ItemGroup>
   103    103       <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite.Compact.2005.csproj">
   104    104         <Project>{AC139951-261A-4463-B6FA-AEBC25283A66}</Project>
   105    105         <Name>System.Data.SQLite.Compact.2005</Name>
   106    106       </ProjectReference>
   107    107     </ItemGroup>
          108  +  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\Targets\System.Data.SQLite.Properties.targets" />
   108    109     <Import Condition="'$(TargetFrameworkVersion)' == 'v1.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.v1.targets" />
   109    110     <Import Condition="'$(TargetFrameworkVersion)' == 'v2.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
   110    111     <Import Condition="'$(TargetFrameworkVersion)' == 'v3.5'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
   111    112     <ProjectExtensions>
   112    113       <VisualStudio>
   113    114         <FlavorProperties GUID="{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}">
   114    115           <HostingProcess disable="1" />
   115    116         </FlavorProperties>
   116    117       </VisualStudio>
   117    118     </ProjectExtensions>
   118    119   </Project>

Changes to testce/testce.2008.csproj.

   102    102     </ItemGroup>
   103    103     <ItemGroup>
   104    104       <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite.Compact.2008.csproj">
   105    105         <Project>{AC139951-261A-4463-B6FA-AEBC25283A66}</Project>
   106    106         <Name>System.Data.SQLite.Compact.2008</Name>
   107    107       </ProjectReference>
   108    108     </ItemGroup>
          109  +  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\Targets\System.Data.SQLite.Properties.targets" />
   109    110     <Import Condition="'$(TargetFrameworkVersion)' == 'v1.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.v1.targets" />
   110    111     <Import Condition="'$(TargetFrameworkVersion)' == 'v2.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
   111    112     <Import Condition="'$(TargetFrameworkVersion)' == 'v3.5'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
   112    113     <ProjectExtensions>
   113    114       <VisualStudio>
   114    115         <FlavorProperties GUID="{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}">
   115    116           <HostingProcess disable="1" />
   116    117         </FlavorProperties>
   117    118       </VisualStudio>
   118    119     </ProjectExtensions>
   119    120   </Project>

Changes to testce/testce.2012.csproj.

    86     86     </ItemGroup>
    87     87     <ItemGroup>
    88     88       <ProjectReference Include="..\System.Data.SQLite\System.Data.SQLite.Compact.2012.csproj">
    89     89         <Project>{AC139951-261A-4463-B6FA-AEBC25283A66}</Project>
    90     90         <Name>System.Data.SQLite.Compact.2012</Name>
    91     91       </ProjectReference>
    92     92     </ItemGroup>
           93  +  <Import Project="$(SQLiteNetDir)\System.Data.SQLite\Targets\System.Data.SQLite.Properties.targets" />
    93     94     <Import Condition="'$(TargetFrameworkVersion)' == 'v1.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.v1.targets" />
    94     95     <Import Condition="'$(TargetFrameworkVersion)' == 'v2.0'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
    95     96     <Import Condition="'$(TargetFrameworkVersion)' == 'v3.5'" Project="$(MSBuildBinPath)\Microsoft.CompactFramework.CSharp.targets" />
    96     97     <Import Project="$(MSBuildExtensionsPath)\Microsoft\$(TargetFrameworkIdentifier)\v8.0\Microsoft.$(TargetFrameworkIdentifier).CSharp.targets" />
    97     98     <ProjectExtensions>
    98     99       <VisualStudio>
    99    100         <FlavorProperties GUID="{fae04ec0-301f-11d3-bf4b-00c04f79efbc}">
   100    101           <HostingProcess disable="1" />
   101    102         </FlavorProperties>
   102    103       </VisualStudio>
   103    104     </ProjectExtensions>
   104    105   </Project>

Changes to testlinq/Program.cs.

    90     90   
    91     91                         return SkipTest(pageSize);
    92     92                     }
    93     93                 case "substring":
    94     94                     {
    95     95                         return SubStringTest();
    96     96                     }
           97  +#if USE_INTEROP_DLL && INTEROP_EXTENSION_FUNCTIONS
    97     98                 case "unionall":
    98     99                     {
    99    100                         return UnionAllTest();
   100    101                     }
          102  +#endif
   101    103                 case "endswith":
   102    104                     {
   103    105                         string value = null;
   104    106   
   105    107                         if (args.Length > 1)
   106    108                         {
   107    109                             value = args[1];
................................................................................
   140    142   
   141    143                                 return 1;
   142    144                             }
   143    145                         }
   144    146   
   145    147                         return EFTransactionTest(value);
   146    148                     }
          149  +#if NET_40 || NET_45 || NET_451 || NET_46
   147    150                 case "insert":
   148    151                     {
   149    152                         return InsertTest();
   150    153                     }
          154  +#endif
   151    155                 case "update":
   152    156                     {
   153    157                         return UpdateTest();
   154    158                     }
   155    159                 case "binaryguid":
   156    160                     {
   157    161                         bool value = false;
................................................................................
   364    368                     once = true;
   365    369                 }
   366    370             }
   367    371   
   368    372             return 0;
   369    373         }
   370    374   
          375  +#if USE_INTEROP_DLL && INTEROP_EXTENSION_FUNCTIONS
   371    376         //
   372    377         // NOTE: Used to test the fix for ticket [0a32885109].
   373    378         //
   374    379         private static int UnionAllTest()
   375    380         {
   376    381             using (northwindEFEntities db = new northwindEFEntities())
   377    382             {
................................................................................
   434    439                     Console.Write(customer.CustomerID);
   435    440                     once = true;
   436    441                 }
   437    442             }
   438    443   
   439    444             return 0;
   440    445         }
          446  +#endif
   441    447   
   442    448         //
   443    449         // NOTE: Used to test the fix for ticket [ccfa69fc32].
   444    450         //
   445    451         private static int EFTransactionTest(bool add)
   446    452         {
   447    453             //
................................................................................
   548    554   #endif
   549    555                 }
   550    556             }
   551    557   
   552    558             return 0;
   553    559         }
   554    560   
          561  +#if NET_40 || NET_45 || NET_451 || NET_46
   555    562         //
   556    563         // NOTE: Used to test the INSERT fix (i.e. an extra semi-colon in
   557    564         //       the SQL statement after the actual INSERT statement in
   558    565         //       the follow-up SELECT statement).
   559    566         //
   560    567         private static int InsertTest()
   561    568         {
   562         -          long[] orderIds = new long[] {
   563         -              0
   564         -          };
   565         -
   566    569             using (northwindEFEntities db = new northwindEFEntities())
   567    570             {
   568    571                 int[] counts = { 0 };
   569    572   
   570    573                 //
   571    574                 // NOTE: *REQUIRED* This is required so that the
   572    575                 //       Entity Framework is prevented from opening
................................................................................
   602    605                 }
   603    606   
   604    607                 Console.WriteLine("inserted {0}", counts[0]);
   605    608             }
   606    609   
   607    610             return 0;
   608    611         }
          612  +#endif
   609    613   
   610    614         //
   611    615         // NOTE: Used to test the UPDATE fix (i.e. the missing semi-colon
   612    616         //       in the SQL statement between the actual UPDATE statement
   613    617         //       and the follow-up SELECT statement).
   614    618         //
   615    619         private static int UpdateTest()

Changes to www/build.wiki.

   393    393         be able to simply delete these directories.
   394    394       </li>
   395    395   
   396    396       <li>Open a normal command prompt window with &quot;cmd.exe&quot;.</li>
   397    397   
   398    398       <li>Change the current directory to &quot;&lt;root&gt;\Setup&quot;.</li>
   399    399   
   400         -    <li>
   401         -      Enter the following command to set the environment variable used to pass
   402         -      the necessary extra arguments to MSBuild:
   403         -      <br />
   404         -      <br />
   405         -      <b>SET&nbsp;MSBUILD_ARGS=/property:UseInteropDll=false&nbsp;/property:UseSqliteStandard=true</b>
   406         -      <br />
   407         -      <br />
   408         -    </li>
   409         -
   410    400       <li>
   411    401         Enter the following command to build the managed-only binaries for Mono:
   412    402         <br />
   413    403         <br />
   414         -      <b>SET NOUSER=1</b>
   415         -      <br />
   416         -      <b>build.bat&nbsp;ReleaseManagedOnly</b>
          404  +      <b>build_mono.bat</b>
   417    405         <br />
   418    406         <br />
   419    407       </li>
   420    408   
   421    409       <li>
   422    410         Make sure everything succeeds with no errors; the log file
   423    411         &quot;%TEMP%\System.Data.SQLite.Build_ReleaseManagedOnly_Win32_&lt;year&gt;_Unknown.log&quot;
   424    412         may be checked if any errors should occur.
   425    413       </li>
   426    414     </ol>
   427    415   </nowiki>

Changes to www/news.wiki.

     5      5   <p>
     6      6       <b>1.0.98.0 - August XX, 2015 <font color="red">(release scheduled)</font></b>
     7      7   </p>
     8      8   <ul>
     9      9       <li>Updated to [https://www.sqlite.org/releaselog/3_8_11_1.html|SQLite 3.8.11.1].</li>
    10     10       <li>Add full support for Visual Studio 2015 and the .NET Framework 4.6.</li>
    11     11       <li>Implement the Substring method for LINQ using the &quot;substr&quot; core SQL function.&nbsp;<b>** Potentially Incompatible Change **</b></li>
           12  +    <li>Prevent encrypted connections from being used with the connection pool. Pursuant to [89d3a159f1].&nbsp;<b>** Potentially Incompatible Change **</b></li>
    12     13       <li>Honor the second argument to Math.Round when using LINQ.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    13     14       <li>Honor the pre-existing flags for connections during the Open method. Fix for [964063da16].&nbsp;<b>** Potentially Incompatible Change **</b></li>
    14     15       <li>Remove errant semi-colons from the SQL used by LINQ to INSERT and then SELECT rows with composite primary keys. Fix for [9d353b0bd8].</li>
    15     16       <li>Change the base type for the SQLiteConnectionFlags enumeration to long integer.&nbsp;<b>** Potentially Incompatible Change **</b></li>
    16     17       <li>Add extended return codes to the SQLiteErrorCode enumeration. Pursuant to [71bedaca19].&nbsp;<b>** Potentially Incompatible Change **</b></li>
    17     18       <li>Improve exception handling in all native callbacks implemented in the SQLiteConnection class.</li>
    18     19       <li>Add Progress event and ProgressOps connection string property to enable raising progress events during long-running queries.</li>