edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/context.rb;C487025 File: context.rb =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/context.rb;C487025 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/context.rb;fixes-2 @@ -1,8 +1,7 @@ require 'rexml/document' require 'fileutils' + ENV['HOME'] ||= ENV['USERPROFILE'] - - SVN_ROOT = Pathname.new 'c:/svn/trunk' DEFAULT_ROBOCOPY_OPTIONS = "/XF *#{EXCLUDED_EXTENSIONS.join(' *')} /NP /COPY:DAT /A-:R " @@ -665,14 +664,11 @@ @summaries = [] @tempdir = Dir.tmpdir end - - def spec_cmd(ruby, klass, options={}) - opts = {:runner => "ci", :formatter => "s"}.merge(options) - "#{UserEnvironment.mri} #{UserEnvironment.mspec}/bin/mspec #{opts[:runner]} -t #{ruby} -f#{opts[:formatter]} #{opts[:options]} -B #{UserEnvironment.config} #{UserEnvironment.rubyspec}/1.8/core/#{klass} #{opts[:out] ? "-o #{opts[:out]}" : ""}" - end - - def regression(ruby, klass) - cmd = spec_cmd(ruby, klass, :formatter => "m", :out => "#{tempdir}/out.txt") + + def regression(ruby, klass, method = nil) + cmd = "#{ruby} #{UserEnvironment.mspec}/bin/mspec-run -fm -V -G fail #{UserEnvironment.rubyspec}/1.8/core/#{klass}" + cmd += "/#{method}_spec.rb" unless method.nil? + cmd += " > #{tempdir}/out.txt" system cmd File.open("#{tempdir}/out.txt", 'r') do |f| lines = f.readlines @@ -697,9 +693,9 @@ end end - def why_regression(ruby, klass) -# cmd = "#{ruby} #{UserEnvironment.mspec}/bin/mspec-ci -fs -V -X #{UserEnvironment.tags} #{UserEnvironment.rubyspec}/1.8/core/#{klass}" - cmd = spec_cmd(ruby, klass, :options => "-V") + def why_regression(ruby, klass, method = nil) + cmd = "#{ruby} #{UserEnvironment.mspec}/bin/mspec-run -fs -V #{UserEnvironment.rubyspec}/1.8/core/#{klass}" + cmd += "/#{method}_spec.rb" unless method.nil? system cmd end @@ -710,9 +706,9 @@ end end - def test(ruby, klass) - cmd = "#{ruby} #{UserEnvironment.mspec}/bin/mspec-ci -fs #{UserEnvironment.rubyspec}/1.8/core/#{klass}" - cmd = spec_cmd(ruby, klass, :formatter => "s") + def test(ruby, klass, method = nil) + cmd = "#{ruby} #{UserEnvironment.mspec}/bin/mspec-run -fs #{UserEnvironment.rubyspec}/1.8/core/#{klass}" + cmd += "/#{method}_spec.rb" unless method.nil? system cmd end @@ -723,8 +719,10 @@ end end - def baseline(ruby, klass) - cmd = "#{ruby} #{UserEnvironment.mspec}/bin/mspec-tag -X #{UserEnvironment.tags} #{UserEnvironment.rubyspec}/1.8/core/#{klass} > #{tempdir}/out.txt" + def baseline(ruby, klass, method = nil) + cmd = "#{ruby} #{UserEnvironment.mspec}/bin/mspec-tag -N fail #{UserEnvironment.rubyspec}/1.8/core/#{klass}" + cmd += "/#{method}_spec.rb" unless method.nil? + cmd += " > #{tempdir}/out.txt" system cmd end @@ -786,10 +784,8 @@ UserEnvironment.const_set(:TAGS, "#{ENV['HOME']}\\dev\\ironruby-tags".gsub('\\', '/')) unless defined?(UserEnvironment::TAGS) UserEnvironment.const_set(:RUBYSPEC, "#{ENV['HOME']}\\dev\\rubyspec".gsub('\\', '/')) unless defined?(UserEnvironment::RUBYSPEC) UserEnvironment.const_set(:MSPEC, "#{ENV['HOME']}\\dev\\mspec".gsub('\\', '/')) unless defined?(UserEnvironment::MSPEC) - UserEnvironment.const_set(:CONFIG, "#{ENV['HOME']}\\default.mspec".gsub('\\', '/')) unless defined?(UserEnvironment::CONFIG) + UserEnvironment.const_set(:CONFIG, "#{ENV['HOME']}\\dev\\default.mspec".gsub('\\', '/')) unless defined?(UserEnvironment::CONFIG) end end UE = UserEnvironment.new - - =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/default.mspec.rb;C487042 File: default.mspec.rb =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/default.mspec.rb;C487042 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/default.mspec.rb;fixes-2 @@ -1,22 +1,15 @@ class MSpecScript # An ordered list of the directories containing specs to run # as the CI process. - root = 'rubyspec' set :ci_files, [ - "#{root}/1.8/core", - "#{root}/1.8/language" -# "#{root}/1.8/library" + "rubyspec/1.8/core", ] - # The set of substitutions to transform a spec filename # into a tag filename. set :tags_patterns, [ [%r(rubyspec/), 'ironruby-tags/'], [/_spec.rb$/, '_tags.txt'] ] - # The default implementation to run the specs. - # TODO: change this to rely on an environment variable - set :target, 'c:\vsl\merlin\main\bin\debug\ir.cmd' end =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Rakefile;C487025 File: Rakefile =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Rakefile;C487025 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Rakefile;fixes-2 @@ -19,6 +19,10 @@ EXCLUDED_EXTENSIONS = ['.old', '.suo', '.vspscc', '.vssscc', '.user', '.log', '.pdb', '.cache', '.swp'] EXCLUDED_DIRECTORIES = ['.svn', 'obj', '.', '..'] +# Alias HOME to USERPROFILE under Windows if HOME is not defined + +ENV['HOME'] = ENV['USERPROFILE'] unless ENV['HOME'] + require 'context' # Add some utility methods to Pathname to support filtered lists @@ -569,12 +573,16 @@ runner = MSpecRunner.new IronRuby.source_context do + iruby = "#{path_to_ir}" # TODO: enable interpreter for all tests + if ARGV.length == 0 - runner.send(:"#{method_name}_all_core", path_to_ir) + runner.send(:"#{method_name}_all_core", iruby) elsif ARGV.length == 1 - runner.send(:"#{method_name}", path_to_ir, ARGV.first) + runner.send(:"#{method_name}", iruby, ARGV.first) + elsif ARGV.length == 2 + runner.send(:"#{method_name}", iruby, ARGV[0], ARGV[1]) else - rake_output_message "usage: rake #{method_name} [class]" + rake_output_message "usage: rake #{method_name} [class] [method]" exit(-1) end end @@ -586,15 +594,16 @@ spec_env_ready = UserEnvironment.rubyspec? && UserEnvironment.mspec? && UserEnvironment.tags? && UserEnvironment.config? if not spec_env_ready - rake_output_message "\n" - rake_output_message "***** Missing rubyspec test environment! You must have rubyspec, mspec, ironruby-tags and default.mspec" - rake_output_message "***** 1. get GIT from http://code.google.com/p/msysgit/" - rake_output_message "***** 2. run: git clone git://github.com/jflam/ironruby-tags.git" - rake_output_message "***** 3. run: git clone git://github.com/jflam/mspec.git" - rake_output_message "***** 4. run: git clone git://github.com/jflam/rubyspec.git" - rake_output_message "***** 5. run: runfirst.cmd" - rake_output_message "***** 6. edit: %USERPROFILE%\.irconfig.rb (C:\Users\ironman\.irconfig.rb)" - rake_output_message "***** 7. edit: %USERPROFILE%\default.mspec (C:\Users\ironman\default.mspec)" + rake_output_message "\n" + rake_output_message "***** Missing rubyspec test environment! You must have rubyspec, mspec, ironruby-tags and default.mspec" + rake_output_message "***** 1. get GIT from http://code.google.com/p/msysgit/" + rake_output_message "***** 2. run: git clone git://github.com/jflam/ironruby-tags.git" + rake_output_message "***** 3. run: git clone git://github.com/jflam/mspec.git" + rake_output_message "***** 4. run: git clone git://github.com/jflam/rubyspec.git" + rake_output_message "***** 5. run: runfirst.cmd" + rake_output_message "***** 6. edit: #{ENV['USERPROFILE']}\\.irconfig.rb" + rake_output_message "***** 7. edit: #{ENV['USERPROFILE']}\\default.mspec" + exit(-1) end end @@ -627,4 +636,3 @@ Rake.application.options.show_task_pattern = Regexp.new('.') Rake.application.display_tasks_and_comments end - =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/runfirst.cmd;C487032 File: runfirst.cmd =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/runfirst.cmd;C487032 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/runfirst.cmd;fixes-2 @@ -1,3 +1,3 @@ sn -Vr *,31bf3856ad364e35 copy default.irconfig.rb "%USERPROFILE%\.irconfig.rb" -copy default.mspec.rb "%USERPROFILE%\default.mspec" +copy default.mspec.rb "%USERPROFILE%\dev\default.mspec" =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C480993 File: Initializers.Generated.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C480993 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;fixes-2 @@ -31,16 +31,16 @@ // Skipped primitive: __ClassSingleton // Skipped primitive: __MainSingleton - Ruby.Builtins.RubyModule def27 = DefineGlobalModule("Comparable", typeof(Ruby.Builtins.Comparable), new System.Action(LoadComparable_Instance), null, Ruby.Builtins.RubyModule.EmptyArray); - Ruby.Builtins.RubyModule def18 = DefineGlobalModule("Enumerable", typeof(Ruby.Builtins.Enumerable), new System.Action(LoadEnumerable_Instance), null, Ruby.Builtins.RubyModule.EmptyArray); + Ruby.Builtins.RubyModule def29 = DefineGlobalModule("Comparable", typeof(Ruby.Builtins.Comparable), new System.Action(LoadComparable_Instance), null, Ruby.Builtins.RubyModule.EmptyArray); + Ruby.Builtins.RubyModule def20 = DefineGlobalModule("Enumerable", typeof(Ruby.Builtins.Enumerable), new System.Action(LoadEnumerable_Instance), null, Ruby.Builtins.RubyModule.EmptyArray); Ruby.Builtins.RubyModule def3 = DefineGlobalModule("Errno", typeof(Ruby.Builtins.Errno), null, null, Ruby.Builtins.RubyModule.EmptyArray); Ruby.Builtins.RubyModule def13 = DefineModule("File::Constants", typeof(Ruby.Builtins.RubyFileOps.Constants), new System.Action(LoadFile__Constants_Instance), null, Ruby.Builtins.RubyModule.EmptyArray); // Skipped primitive: Kernel DefineGlobalModule("Marshal", typeof(Ruby.Builtins.RubyMarshal), new System.Action(LoadMarshal_Instance), new System.Action(LoadMarshal_Class), Ruby.Builtins.RubyModule.EmptyArray); DefineGlobalModule("Math", typeof(Ruby.Builtins.RubyMath), new System.Action(LoadMath_Instance), new System.Action(LoadMath_Class), Ruby.Builtins.RubyModule.EmptyArray); - Ruby.Builtins.RubyModule def23 = DefineGlobalModule("Precision", typeof(Ruby.Builtins.Precision), new System.Action(LoadPrecision_Instance), new System.Action(LoadPrecision_Class), Ruby.Builtins.RubyModule.EmptyArray); + Ruby.Builtins.RubyModule def25 = DefineGlobalModule("Precision", typeof(Ruby.Builtins.Precision), new System.Action(LoadPrecision_Instance), new System.Action(LoadPrecision_Class), Ruby.Builtins.RubyModule.EmptyArray); #if !SILVERLIGHT - DefineGlobalModule("Process", typeof(Ruby.Builtins.RubyProcess), new System.Action(LoadProcess_Instance), new System.Action(LoadProcess_Class), Ruby.Builtins.RubyModule.EmptyArray); + Ruby.Builtins.RubyModule def14 = DefineGlobalModule("Process", typeof(Ruby.Builtins.RubyProcess), new System.Action(LoadProcess_Instance), new System.Action(LoadProcess_Class), Ruby.Builtins.RubyModule.EmptyArray); #endif #if !SILVERLIGHT DefineGlobalModule("Signal", typeof(Ruby.Builtins.Signal), null, new System.Action(LoadSignal_Class), Ruby.Builtins.RubyModule.EmptyArray); @@ -49,18 +49,18 @@ ExtendClass(typeof(System.Type), new System.Action(LoadSystem__Type_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); // Skipped primitive: __ClassSingletonSingleton #if !SILVERLIGHT - object def1 = DefineSingleton(new System.Action(Load__Singleton_ArgFilesSingletonOps_Instance), null, new Ruby.Builtins.RubyModule[] {def18, }); + object def1 = DefineSingleton(new System.Action(Load__Singleton_ArgFilesSingletonOps_Instance), null, new Ruby.Builtins.RubyModule[] {def20, }); #endif #if !SILVERLIGHT - object def2 = DefineSingleton(new System.Action(Load__Singleton_EnvironmentSingletonOps_Instance), null, new Ruby.Builtins.RubyModule[] {def18, }); + object def2 = DefineSingleton(new System.Action(Load__Singleton_EnvironmentSingletonOps_Instance), null, new Ruby.Builtins.RubyModule[] {def20, }); #endif // Skipped primitive: Object - ExtendModule(typeof(System.Collections.Generic.IDictionary), new System.Action(LoadSystem__Collections__Generic__IDictionary_Instance), null, new Ruby.Builtins.RubyModule[] {def18, }); - ExtendModule(typeof(System.Collections.IEnumerable), new System.Action(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def18, }); - ExtendModule(typeof(System.Collections.IList), new System.Action(LoadSystem__Collections__IList_Instance), null, new Ruby.Builtins.RubyModule[] {def18, }); - Ruby.Builtins.RubyModule def31 = ExtendModule(typeof(System.IComparable), new System.Action(LoadSystem__IComparable_Instance), null, new Ruby.Builtins.RubyModule[] {def27, }); - ExtendClass(typeof(System.Scripting.Actions.TypeGroup), new System.Action(LoadSystem__Scripting__Actions__TypeGroup_Instance), null, new Ruby.Builtins.RubyModule[] {def18, }, null); - DefineGlobalClass("Array", typeof(Ruby.Builtins.RubyArray), Context.ObjectClass, new System.Action(LoadArray_Instance), new System.Action(LoadArray_Class), new Ruby.Builtins.RubyModule[] {def18, }, new System.Delegate[] { + ExtendModule(typeof(System.Collections.Generic.IDictionary), new System.Action(LoadSystem__Collections__Generic__IDictionary_Instance), null, new Ruby.Builtins.RubyModule[] {def20, }); + Ruby.Builtins.RubyModule def33 = ExtendModule(typeof(System.Collections.IEnumerable), new System.Action(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def20, }); + ExtendModule(typeof(System.Collections.IList), new System.Action(LoadSystem__Collections__IList_Instance), null, new Ruby.Builtins.RubyModule[] {def20, }); + ExtendModule(typeof(System.IComparable), new System.Action(LoadSystem__IComparable_Instance), null, new Ruby.Builtins.RubyModule[] {def29, }); + ExtendClass(typeof(System.Scripting.Actions.TypeGroup), new System.Action(LoadSystem__Scripting__Actions__TypeGroup_Instance), null, new Ruby.Builtins.RubyModule[] {def20, }, null); + DefineGlobalClass("Array", typeof(Ruby.Builtins.RubyArray), Context.ObjectClass, new System.Action(LoadArray_Instance), new System.Action(LoadArray_Class), new Ruby.Builtins.RubyModule[] {def20, }, new System.Delegate[] { new System.Func(Ruby.Builtins.ArrayOps.CreateArray), new System.Func(Ruby.Builtins.ArrayOps.CreateArray), new System.Func(Ruby.Builtins.ArrayOps.CreateArray), @@ -70,24 +70,24 @@ new System.Func(Ruby.Builtins.ArrayOps.CreateArray), }); DefineGlobalClass("Binding", typeof(Ruby.Builtins.Binding), Context.ObjectClass, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("ClrString", typeof(System.String), Context.ObjectClass, new System.Action(LoadClrString_Instance), null, new Ruby.Builtins.RubyModule[] {def31, }, null); - DefineGlobalClass("Dir", typeof(Ruby.Builtins.RubyDir), Context.ObjectClass, new System.Action(LoadDir_Instance), new System.Action(LoadDir_Class), new Ruby.Builtins.RubyModule[] {def18, }, null); - Ruby.Builtins.RubyClass def28 = Context.ExceptionClass = DefineGlobalClass("Exception", typeof(System.Exception), Context.ObjectClass, new System.Action(LoadException_Instance), new System.Action(LoadException_Class), Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("ClrString", typeof(System.String), Context.ObjectClass, new System.Action(LoadClrString_Instance), null, new Ruby.Builtins.RubyModule[] {def33, }, null); + DefineGlobalClass("Dir", typeof(Ruby.Builtins.RubyDir), Context.ObjectClass, new System.Action(LoadDir_Instance), new System.Action(LoadDir_Class), new Ruby.Builtins.RubyModule[] {def20, }, null); + Ruby.Builtins.RubyClass def30 = Context.ExceptionClass = DefineGlobalClass("Exception", typeof(System.Exception), Context.ObjectClass, new System.Action(LoadException_Instance), new System.Action(LoadException_Class), Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.ExceptionOps.Factory), }); Context.FalseClass = DefineGlobalClass("FalseClass", typeof(Ruby.Builtins.FalseClass), Context.ObjectClass, new System.Action(LoadFalseClass_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); #if !SILVERLIGHT - Ruby.Builtins.RubyClass def16 = DefineClass("File::Stat", typeof(System.IO.FileSystemInfo), Context.ObjectClass, new System.Action(LoadFile__Stat_Instance), null, new Ruby.Builtins.RubyModule[] {def27, }, new System.Delegate[] { + Ruby.Builtins.RubyClass def18 = DefineClass("File::Stat", typeof(System.IO.FileSystemInfo), Context.ObjectClass, new System.Action(LoadFile__Stat_Instance), null, new Ruby.Builtins.RubyModule[] {def29, }, new System.Delegate[] { new System.Func(Ruby.Builtins.RubyFileOps.RubyStatOps.Create), new System.Func(Ruby.Builtins.RubyFileOps.RubyStatOps.Create), }); #endif DefineGlobalClass("FileTest", typeof(Ruby.Builtins.FileTestOps), Context.ObjectClass, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("Hash", typeof(Ruby.Builtins.Hash), Context.ObjectClass, new System.Action(LoadHash_Instance), new System.Action(LoadHash_Class), new Ruby.Builtins.RubyModule[] {def18, }, new System.Delegate[] { + DefineGlobalClass("Hash", typeof(Ruby.Builtins.Hash), Context.ObjectClass, new System.Action(LoadHash_Instance), new System.Action(LoadHash_Class), new Ruby.Builtins.RubyModule[] {def20, }, new System.Delegate[] { new System.Func(Ruby.Builtins.HashOps.Hash), new System.Func(Ruby.Builtins.HashOps.Hash), }); - Ruby.Builtins.RubyClass def29 = DefineGlobalClass("IO", typeof(Ruby.Builtins.RubyIO), Context.ObjectClass, new System.Action(LoadIO_Instance), new System.Action(LoadIO_Class), new Ruby.Builtins.RubyModule[] {def13, }, new System.Delegate[] { + Ruby.Builtins.RubyClass def31 = DefineGlobalClass("IO", typeof(Ruby.Builtins.RubyIO), Context.ObjectClass, new System.Action(LoadIO_Instance), new System.Action(LoadIO_Class), new Ruby.Builtins.RubyModule[] {def13, }, new System.Delegate[] { new System.Func(Ruby.Builtins.RubyIOOps.CreateIO), new System.Func(Ruby.Builtins.RubyIOOps.CreateIO), new System.Func(Ruby.Builtins.RubyIOOps.CreateIO), @@ -96,124 +96,127 @@ DefineGlobalClass("Method", typeof(Ruby.Builtins.RubyMethod), Context.ObjectClass, new System.Action(LoadMethod_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); // Skipped primitive: Module Context.NilClass = DefineGlobalClass("NilClass", typeof(System.Scripting.None), Context.ObjectClass, new System.Action(LoadNilClass_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def22 = DefineGlobalClass("Numeric", typeof(Ruby.Builtins.Numeric), Context.ObjectClass, new System.Action(LoadNumeric_Instance), null, new Ruby.Builtins.RubyModule[] {def27, }, null); + Ruby.Builtins.RubyClass def24 = DefineGlobalClass("Numeric", typeof(Ruby.Builtins.Numeric), Context.ObjectClass, new System.Action(LoadNumeric_Instance), null, new Ruby.Builtins.RubyModule[] {def29, }, null); DefineGlobalClass("ObjectSpace", typeof(Ruby.Builtins.ObjectSpace), Context.ObjectClass, null, new System.Action(LoadObjectSpace_Class), Ruby.Builtins.RubyModule.EmptyArray, null); DefineGlobalClass("Proc", typeof(Ruby.Builtins.Proc), Context.ObjectClass, new System.Action(LoadProc_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.ProcOps.CreateProc), new System.Func(Ruby.Builtins.ProcOps.CreateProc), }); - DefineGlobalClass("Range", typeof(Ruby.Builtins.Range), Context.ObjectClass, new System.Action(LoadRange_Instance), null, new Ruby.Builtins.RubyModule[] {def18, }, new System.Delegate[] { + #if !SILVERLIGHT && !SILVERLIGHT + Ruby.Builtins.RubyClass def15 = DefineClass("Process::Status", typeof(Ruby.Builtins.RubyProcess.Status), Context.ObjectClass, new System.Action(LoadProcess__Status_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); + #endif + DefineGlobalClass("Range", typeof(Ruby.Builtins.Range), Context.ObjectClass, new System.Action(LoadRange_Instance), null, new Ruby.Builtins.RubyModule[] {def20, }, new System.Delegate[] { new System.Func(Ruby.Builtins.RangeOps.CreateRange), }); - DefineGlobalClass("Regexp", typeof(Ruby.Builtins.RubyRegex), Context.ObjectClass, new System.Action(LoadRegexp_Instance), new System.Action(LoadRegexp_Class), new Ruby.Builtins.RubyModule[] {def18, }, new System.Delegate[] { + DefineGlobalClass("Regexp", typeof(Ruby.Builtins.RubyRegex), Context.ObjectClass, new System.Action(LoadRegexp_Instance), new System.Action(LoadRegexp_Class), new Ruby.Builtins.RubyModule[] {def20, }, new System.Delegate[] { new System.Func(Ruby.Builtins.RegexpOps.Create), new System.Func(Ruby.Builtins.RegexpOps.Create), new System.Func(Ruby.Builtins.RegexpOps.Create), }); - DefineGlobalClass("String", typeof(Ruby.Builtins.MutableString), Context.ObjectClass, new System.Action(LoadString_Instance), null, new Ruby.Builtins.RubyModule[] {def18, def27, }, new System.Delegate[] { + DefineGlobalClass("String", typeof(Ruby.Builtins.MutableString), Context.ObjectClass, new System.Action(LoadString_Instance), null, new Ruby.Builtins.RubyModule[] {def20, def29, }, new System.Delegate[] { new System.Func(Ruby.Builtins.MutableStringOps.Create), new System.Func(Ruby.Builtins.MutableStringOps.Create), new System.Func(Ruby.Builtins.MutableStringOps.Create), }); - Ruby.Builtins.RubyClass def14 = DefineGlobalClass("Struct", typeof(Ruby.Builtins.RubyStruct), Context.ObjectClass, new System.Action(LoadStruct_Instance), null, new Ruby.Builtins.RubyModule[] {def18, }, new System.Delegate[] { + Ruby.Builtins.RubyClass def16 = DefineGlobalClass("Struct", typeof(Ruby.Builtins.RubyStruct), Context.ObjectClass, new System.Action(LoadStruct_Instance), null, new Ruby.Builtins.RubyModule[] {def20, }, new System.Delegate[] { new System.Func(Ruby.Builtins.RubyStructOps.CreateNamed), }); DefineGlobalClass("Symbol", typeof(System.Scripting.SymbolId), Context.ObjectClass, new System.Action(LoadSymbol_Instance), new System.Action(LoadSymbol_Class), Ruby.Builtins.RubyModule.EmptyArray, null); DefineGlobalClass("Thread", typeof(System.Threading.Thread), Context.ObjectClass, new System.Action(LoadThread_Instance), new System.Action(LoadThread_Class), Ruby.Builtins.RubyModule.EmptyArray, null); DefineGlobalClass("ThreadGroup", typeof(Ruby.Builtins.ThreadGroup), Context.ObjectClass, new System.Action(LoadThreadGroup_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("Time", typeof(System.DateTime), Context.ObjectClass, new System.Action(LoadTime_Instance), new System.Action(LoadTime_Class), new Ruby.Builtins.RubyModule[] {def27, }, new System.Delegate[] { + DefineGlobalClass("Time", typeof(System.DateTime), Context.ObjectClass, new System.Action(LoadTime_Instance), new System.Action(LoadTime_Class), new Ruby.Builtins.RubyModule[] {def29, }, new System.Delegate[] { new System.Func(Ruby.Builtins.TimeOps.Create), }); Context.TrueClass = DefineGlobalClass("TrueClass", typeof(Ruby.Builtins.TrueClass), Context.ObjectClass, new System.Action(LoadTrueClass_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); DefineGlobalClass("UnboundMethod", typeof(Ruby.Builtins.UnboundMethod), Context.ObjectClass, new System.Action(LoadUnboundMethod_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); // Skipped primitive: Class - Ruby.Builtins.RubyClass def12 = DefineGlobalClass("File", typeof(Ruby.Builtins.RubyFile), def29, new System.Action(LoadFile_Instance), new System.Action(LoadFile_Class), Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + Ruby.Builtins.RubyClass def12 = DefineGlobalClass("File", typeof(Ruby.Builtins.RubyFile), def31, new System.Action(LoadFile_Instance), new System.Action(LoadFile_Class), Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.RubyFileOps.CreateIO), new System.Func(Ruby.Builtins.RubyFileOps.CreateIO), new System.Func(Ruby.Builtins.RubyFileOps.CreateIO), new System.Func(Ruby.Builtins.RubyFileOps.CreateIO), }); - DefineGlobalClass("Float", typeof(System.Double), def22, new System.Action(LoadFloat_Instance), new System.Action(LoadFloat_Class), new Ruby.Builtins.RubyModule[] {def23, }, null); - Ruby.Builtins.RubyClass def17 = DefineGlobalClass("Integer", typeof(Ruby.Builtins.Integer), def22, new System.Action(LoadInteger_Instance), new System.Action(LoadInteger_Class), new Ruby.Builtins.RubyModule[] {def23, }, null); - DefineGlobalClass("NoMemoryError", typeof(Ruby.Builtins.NoMemoryError), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def25 = DefineGlobalClass("ScriptError", typeof(Ruby.Builtins.ScriptError), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("Float", typeof(System.Double), def24, new System.Action(LoadFloat_Instance), new System.Action(LoadFloat_Class), new Ruby.Builtins.RubyModule[] {def25, }, null); + Ruby.Builtins.RubyClass def19 = DefineGlobalClass("Integer", typeof(Ruby.Builtins.Integer), def24, new System.Action(LoadInteger_Instance), new System.Action(LoadInteger_Class), new Ruby.Builtins.RubyModule[] {def25, }, null); + DefineGlobalClass("NoMemoryError", typeof(Ruby.Builtins.NoMemoryError), def30, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def27 = DefineGlobalClass("ScriptError", typeof(Ruby.Builtins.ScriptError), def30, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.ScriptErrorOps.Factory), }); - Ruby.Builtins.RubyClass def24 = DefineGlobalClass("SignalException", typeof(Ruby.Builtins.SignalException), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def26 = Context.StandardErrorClass = DefineGlobalClass("StandardError", typeof(System.SystemException), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + Ruby.Builtins.RubyClass def26 = DefineGlobalClass("SignalException", typeof(Ruby.Builtins.SignalException), def30, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def28 = Context.StandardErrorClass = DefineGlobalClass("StandardError", typeof(System.SystemException), def30, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.SystemExceptionOps.Factory), }); #if !SILVERLIGHT - Ruby.Builtins.RubyClass def15 = DefineClass("Struct::Tms", typeof(Ruby.Builtins.RubyStructOps.Tms), def14, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + Ruby.Builtins.RubyClass def17 = DefineClass("Struct::Tms", typeof(Ruby.Builtins.RubyStructOps.Tms), def16, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.RubyStructOps.Tms.CreateInstance), new System.Func(Ruby.Builtins.RubyStructOps.Tms.CreateInstance), }); #endif - DefineGlobalClass("SystemExit", typeof(Ruby.Builtins.SystemExit), def28, new System.Action(LoadSystemExit_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("SystemExit", typeof(Ruby.Builtins.SystemExit), def30, new System.Action(LoadSystemExit_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.SystemExitOps.Factory), new System.Func(Ruby.Builtins.SystemExitOps.Factory), }); - DefineGlobalClass("ArgumentError", typeof(System.ArgumentException), def26, new System.Action(LoadArgumentError_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("ArgumentError", typeof(System.ArgumentException), def28, new System.Action(LoadArgumentError_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.ArgumentErrorOps.Factory), }); - DefineGlobalClass("Bignum", typeof(Microsoft.Scripting.Math.BigInteger), def17, new System.Action(LoadBignum_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("Fixnum", typeof(System.Int32), def17, new System.Action(LoadFixnum_Instance), new System.Action(LoadFixnum_Class), Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("IndexError", typeof(System.IndexOutOfRangeException), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("Bignum", typeof(Microsoft.Scripting.Math.BigInteger), def19, new System.Action(LoadBignum_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, null); + DefineGlobalClass("Fixnum", typeof(System.Int32), def19, new System.Action(LoadFixnum_Instance), new System.Action(LoadFixnum_Class), Ruby.Builtins.RubyModule.EmptyArray, null); + DefineGlobalClass("IndexError", typeof(System.IndexOutOfRangeException), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.IndexErrorOps.Factory), }); - DefineGlobalClass("Interrupt", typeof(Ruby.Builtins.Interrupt), def24, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def19 = DefineGlobalClass("IOError", typeof(System.IO.IOException), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("Interrupt", typeof(Ruby.Builtins.Interrupt), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def21 = DefineGlobalClass("IOError", typeof(System.IO.IOException), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.IOErrorOps.Factory), }); - DefineGlobalClass("LoadError", typeof(Ruby.Builtins.LoadError), def25, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("LoadError", typeof(Ruby.Builtins.LoadError), def27, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.LoadErrorOps.Factory), }); - DefineGlobalClass("LocalJumpError", typeof(Ruby.Builtins.LocalJumpError), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("LocalJumpError", typeof(Ruby.Builtins.LocalJumpError), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.LocalJumpErrorOps.Factory), }); - Ruby.Builtins.RubyClass def30 = DefineGlobalClass("NameError", typeof(System.MemberAccessException), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + Ruby.Builtins.RubyClass def32 = DefineGlobalClass("NameError", typeof(System.MemberAccessException), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.NameErrorOps.Factory), }); - DefineGlobalClass("NotImplementedError", typeof(Ruby.Builtins.NotImplementedError), def25, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("NotImplementedError", typeof(Ruby.Builtins.NotImplementedError), def27, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.NotImplementedErrorOps.Factory), }); - Ruby.Builtins.RubyClass def21 = DefineGlobalClass("RangeError", typeof(System.ArgumentOutOfRangeException), def26, new System.Action(LoadRangeError_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + Ruby.Builtins.RubyClass def23 = DefineGlobalClass("RangeError", typeof(System.ArgumentOutOfRangeException), def28, new System.Action(LoadRangeError_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.RangeErrorOps.Factory), }); - DefineGlobalClass("RegexpError", typeof(Ruby.Builtins.RegexpError), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("RegexpError", typeof(Ruby.Builtins.RegexpError), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.RegexpErrorOps.Factory), }); - DefineGlobalClass("RuntimeError", typeof(Ruby.Builtins.RuntimeError), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("SecurityError", typeof(System.Security.SecurityException), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("RuntimeError", typeof(Ruby.Builtins.RuntimeError), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + DefineGlobalClass("SecurityError", typeof(System.Security.SecurityException), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.SecurityErrorOps.Factory), }); - DefineGlobalClass("SyntaxError", typeof(Ruby.Builtins.SyntaxError), def25, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("SyntaxError", typeof(Ruby.Builtins.SyntaxError), def27, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.SyntaxErrorOps.Factory), }); - Ruby.Builtins.RubyClass def20 = DefineGlobalClass("SystemCallError", typeof(System.Runtime.InteropServices.ExternalException), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + Ruby.Builtins.RubyClass def22 = DefineGlobalClass("SystemCallError", typeof(System.Runtime.InteropServices.ExternalException), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.SystemCallErrorOps.Factory), }); - DefineGlobalClass("SystemStackError", typeof(Ruby.Builtins.SystemStackError), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("SystemStackError", typeof(Ruby.Builtins.SystemStackError), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.SystemStackErrorOps.Factory), }); - DefineGlobalClass("ThreadError", typeof(Ruby.Builtins.ThreadError), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("TypeError", typeof(System.InvalidOperationException), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("ThreadError", typeof(Ruby.Builtins.ThreadError), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + DefineGlobalClass("TypeError", typeof(System.InvalidOperationException), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.TypeErrorOps.Factory), }); - DefineGlobalClass("ZeroDivisionError", typeof(System.DivideByZeroException), def26, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("ZeroDivisionError", typeof(System.DivideByZeroException), def28, null, null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.ZeroDivisionErrorOps.Factory), }); - DefineGlobalClass("EOFError", typeof(Ruby.Builtins.EOFError), def19, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def4 = DefineClass("Errno::EACCES", typeof(Ruby.Builtins.Errno.AccessError), def20, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def5 = DefineClass("Errno::EBADF", typeof(Ruby.Builtins.Errno.BadFileDescriptorError), def20, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def6 = DefineClass("Errno::EDOM", typeof(Ruby.Builtins.Errno.DomainError), def20, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def7 = DefineClass("Errno::EEXIST", typeof(Ruby.Builtins.Errno.ExistError), def20, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def8 = DefineClass("Errno::EINVAL", typeof(Ruby.Builtins.Errno.InvalidError), def20, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def9 = DefineClass("Errno::ENOENT", typeof(Ruby.Builtins.Errno.NoEntryError), def20, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def10 = DefineClass("Errno::ENOTDIR", typeof(Ruby.Builtins.Errno.NotDirectoryError), def20, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - Ruby.Builtins.RubyClass def11 = DefineClass("Errno::EPIPE", typeof(Ruby.Builtins.Errno.PipeError), def20, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("FloatDomainError", typeof(Ruby.Builtins.FloatDomainError), def21, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("NoMethodError", typeof(System.MissingMethodException), def30, new System.Action(LoadNoMethodError_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { + DefineGlobalClass("EOFError", typeof(Ruby.Builtins.EOFError), def21, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def4 = DefineClass("Errno::EACCES", typeof(Ruby.Builtins.Errno.AccessError), def22, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def5 = DefineClass("Errno::EBADF", typeof(Ruby.Builtins.Errno.BadFileDescriptorError), def22, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def6 = DefineClass("Errno::EDOM", typeof(Ruby.Builtins.Errno.DomainError), def22, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def7 = DefineClass("Errno::EEXIST", typeof(Ruby.Builtins.Errno.ExistError), def22, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def8 = DefineClass("Errno::EINVAL", typeof(Ruby.Builtins.Errno.InvalidError), def22, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def9 = DefineClass("Errno::ENOENT", typeof(Ruby.Builtins.Errno.NoEntryError), def22, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def10 = DefineClass("Errno::ENOTDIR", typeof(Ruby.Builtins.Errno.NotDirectoryError), def22, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + Ruby.Builtins.RubyClass def11 = DefineClass("Errno::EPIPE", typeof(Ruby.Builtins.Errno.PipeError), def22, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + DefineGlobalClass("FloatDomainError", typeof(Ruby.Builtins.FloatDomainError), def23, null, null, Ruby.Builtins.RubyModule.EmptyArray, null); + DefineGlobalClass("NoMethodError", typeof(System.MissingMethodException), def32, new System.Action(LoadNoMethodError_Instance), null, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { new System.Func(Ruby.Builtins.NoMethodErrorOps.Factory), }); def12.SetConstant("Constants", def13); @@ -224,10 +227,13 @@ Context.ObjectClass.SetConstant("ENV", def2); #endif #if !SILVERLIGHT - def12.SetConstant("Stat", def16); + def12.SetConstant("Stat", def18); #endif + #if !SILVERLIGHT && !SILVERLIGHT + def14.SetConstant("Status", def15); + #endif #if !SILVERLIGHT - def14.SetConstant("Tms", def15); + def16.SetConstant("Tms", def17); #endif def3.SetConstant("EACCES", def4); def3.SetConstant("EBADF", def5); @@ -1145,6 +1151,7 @@ new System.Func(Ruby.Builtins.RubyFileOps.Exists), }); + #if !SILVERLIGHT module.DefineLibraryMethod("expand_path", 0x31, new System.Delegate[] { new System.Func(Ruby.Builtins.RubyFileOps.ExpandPath), new System.Func(Ruby.Builtins.RubyFileOps.ExpandPath), @@ -1152,6 +1159,7 @@ new System.Func(Ruby.Builtins.RubyFileOps.ExpandPath), }); + #endif module.DefineLibraryMethod("extname", 0x31, new System.Delegate[] { new System.Func(Ruby.Builtins.RubyFileOps.ExtName), new System.Func(Ruby.Builtins.RubyFileOps.ExtName), @@ -2197,10 +2205,13 @@ new System.Func(Ruby.Builtins.KernelOps.SendMessage), }); + #if !SILVERLIGHT module.DefineLibraryMethod("`", 0x2a, new System.Delegate[] { new System.Func(Ruby.Builtins.KernelOps.ExecuteCommand), + new System.Func(Ruby.Builtins.KernelOps.ExecuteCommand), }); + #endif module.DefineLibraryMethod("=~", 0x29, new System.Delegate[] { new System.Func(Ruby.Builtins.KernelOps.Match), }); @@ -2264,7 +2275,9 @@ #if !SILVERLIGHT module.DefineLibraryMethod("exec", 0x2a, new System.Delegate[] { - new System.Func(Ruby.Builtins.KernelOps.Execute), + new System.Action(Ruby.Builtins.KernelOps.Execute), + new System.Action(Ruby.Builtins.KernelOps.Execute), + new System.Action(Ruby.Builtins.KernelOps.Execute), }); #endif @@ -2544,6 +2557,14 @@ new System.Func(Ruby.Builtins.KernelOps.ToString), }); + #if !SILVERLIGHT + module.DefineLibraryMethod("system", 0x2a, new System.Delegate[] { + new System.Func(Ruby.Builtins.KernelOps.System), + new System.Func(Ruby.Builtins.KernelOps.System), + new System.Func(Ruby.Builtins.KernelOps.System), + }); + + #endif module.DefineLibraryMethod("taint", 0x29, new System.Delegate[] { new System.Func(Ruby.Builtins.KernelOps.Taint), }); @@ -2575,10 +2596,13 @@ private void LoadKernel_Class(Ruby.Builtins.RubyModule/*!*/ module) { + #if !SILVERLIGHT module.DefineLibraryMethod("`", 0x31, new System.Delegate[] { new System.Func(Ruby.Builtins.KernelOps.ExecuteCommand), + new System.Func(Ruby.Builtins.KernelOps.ExecuteCommand), }); + #endif module.DefineLibraryMethod("Array", 0x31, new System.Delegate[] { new System.Func(Ruby.Builtins.KernelOps.ToArray), }); @@ -2602,7 +2626,9 @@ #if !SILVERLIGHT module.DefineLibraryMethod("exec", 0x31, new System.Delegate[] { - new System.Func(Ruby.Builtins.KernelOps.Execute), + new System.Action(Ruby.Builtins.KernelOps.Execute), + new System.Action(Ruby.Builtins.KernelOps.Execute), + new System.Action(Ruby.Builtins.KernelOps.Execute), }); #endif @@ -2755,6 +2781,14 @@ new System.Func(Ruby.Builtins.KernelOps.ToString), }); + #if !SILVERLIGHT + module.DefineLibraryMethod("system", 0x31, new System.Delegate[] { + new System.Func(Ruby.Builtins.KernelOps.System), + new System.Func(Ruby.Builtins.KernelOps.System), + new System.Func(Ruby.Builtins.KernelOps.System), + }); + + #endif module.DefineLibraryMethod("throw", 0x31, new System.Delegate[] { new System.Action(Ruby.Builtins.KernelOps.Throw), }); @@ -3573,6 +3607,44 @@ } #endif + #if !SILVERLIGHT && !SILVERLIGHT + private void LoadProcess__Status_Instance(Ruby.Builtins.RubyModule/*!*/ module) { + + module.DefineLibraryMethod("coredump?", 0x29, new System.Delegate[] { + new System.Func(Ruby.Builtins.RubyProcess.Status.CoreDump), + }); + + module.DefineLibraryMethod("exited?", 0x29, new System.Delegate[] { + new System.Func(Ruby.Builtins.RubyProcess.Status.Exited), + }); + + module.DefineLibraryMethod("exitstatus", 0x29, new System.Delegate[] { + new System.Func(Ruby.Builtins.RubyProcess.Status.ExitStatus), + }); + + module.DefineLibraryMethod("pid", 0x29, new System.Delegate[] { + new System.Func(Ruby.Builtins.RubyProcess.Status.Pid), + }); + + module.DefineLibraryMethod("stopped?", 0x29, new System.Delegate[] { + new System.Func(Ruby.Builtins.RubyProcess.Status.Stopped), + }); + + module.DefineLibraryMethod("stopsig", 0x29, new System.Delegate[] { + new System.Func(Ruby.Builtins.RubyProcess.Status.StopSig), + }); + + module.DefineLibraryMethod("success?", 0x29, new System.Delegate[] { + new System.Func(Ruby.Builtins.RubyProcess.Status.Success), + }); + + module.DefineLibraryMethod("termsig", 0x29, new System.Delegate[] { + new System.Func(Ruby.Builtins.RubyProcess.Status.TermSig), + }); + + } + #endif + private void LoadRange_Instance(Ruby.Builtins.RubyModule/*!*/ module) { module.DefineLibraryMethod("==", 0x29, new System.Delegate[] { =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Dir.cs;C468100 File: Dir.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Dir.cs;C468100 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Dir.cs;fixes-2 @@ -105,16 +105,10 @@ [RubyMethod("chdir", RubyMethodAttributes.PublicSingleton)] public static object ChangeDirectory(object self) { #if !SILVERLIGHT - string defaultDirectory = Environment.GetEnvironmentVariable("HOME"); + string defaultDirectory = RubyFileOps.GetHomeDirectory(); + if (defaultDirectory == null) + throw RubyExceptions.CreateArgumentError("HOME / USERPROFILE not set"); - if (defaultDirectory == null) { - defaultDirectory = Environment.GetEnvironmentVariable("LOGDIR"); - } - - if (defaultDirectory == null) { - throw new ArgumentException("HOME/LOGDIR not set"); - } - return ChangeDirectory(self, MutableString.Create(defaultDirectory)); #else throw new InvalidOperationException(); @@ -177,393 +171,9 @@ #region glob - private class GlobUngrouper { - internal abstract class GlobNode { - internal readonly GlobNode/*!*/ _parent; - protected GlobNode(GlobNode parentNode) { - _parent = parentNode ?? this; - } - abstract internal GlobNode/*!*/ AddChar(char c); - abstract internal GlobNode/*!*/ StartLevel(); - abstract internal GlobNode/*!*/ AddGroup(); - abstract internal GlobNode/*!*/ FinishLevel(); - abstract internal List/*!*/ Flatten(); - } - - internal class TextNode : GlobNode { - private readonly StringBuilder/*!*/ _builder; - - internal TextNode(GlobNode/*!*/ parentNode) - : base(parentNode) { - _builder = new StringBuilder(); - } - internal override GlobNode/*!*/ AddChar(char c) { - if (c != 0) { - _builder.Append(c); - } - return this; - } - internal override GlobNode/*!*/ StartLevel() { - return _parent.StartLevel(); - } - internal override GlobNode/*!*/ AddGroup() { - return _parent.AddGroup(); - } - internal override GlobNode/*!*/ FinishLevel() { - return _parent.FinishLevel(); - } - internal override List/*!*/ Flatten() { - List result = new List(1); - result.Add(_builder); - return result; - } - } - - internal class ChoiceNode : GlobNode { - private readonly List/*!*/ _nodes; - - internal ChoiceNode(GlobNode/*!*/ parentNode) - : base(parentNode) { - _nodes = new List(); - } - internal override GlobNode/*!*/ AddChar(char c) { - SequenceNode node = new SequenceNode(this); - _nodes.Add(node); - return node.AddChar(c); - } - internal override GlobNode/*!*/ StartLevel() { - SequenceNode node = new SequenceNode(this); - _nodes.Add(node); - return node.StartLevel(); - } - internal override GlobNode/*!*/ AddGroup() { - AddChar((char)0); - return this; - } - internal override GlobNode/*!*/ FinishLevel() { - AddChar((char)0); - return _parent; - } - internal override List/*!*/ Flatten() { - List result = new List(); - foreach (GlobNode node in _nodes) { - foreach (StringBuilder builder in node.Flatten()) { - result.Add(builder); - } - } - return result; - } - } - - internal class SequenceNode : GlobNode { - private readonly List/*!*/ _nodes; - - internal SequenceNode(GlobNode parentNode) - : base(parentNode) { - _nodes = new List(); - } - internal override GlobNode/*!*/ AddChar(char c) { - TextNode/*!*/ node = new TextNode(this); - _nodes.Add(node); - return node.AddChar(c); - } - internal override GlobNode/*!*/ StartLevel() { - ChoiceNode node = new ChoiceNode(this); - _nodes.Add(node); - return node; - } - internal override GlobNode/*!*/ AddGroup() { - return _parent; - } - internal override GlobNode/*!*/ FinishLevel() { - return _parent._parent; - } - internal override List/*!*/ Flatten() { - List result = new List(); - result.Add(new StringBuilder()); - foreach (GlobNode node in _nodes) { - List tmp = new List(); - foreach (StringBuilder builder in node.Flatten()) { - foreach (StringBuilder sb in result) { - StringBuilder newsb = new StringBuilder(sb.ToString()); - newsb.Append(builder.ToString()); - tmp.Add(newsb); - } - } - result = tmp; - } - return result; - } - } - - private readonly SequenceNode/*!*/ _rootNode; - private GlobNode/*!*/ _currentNode; - private int _level; - - internal GlobUngrouper(int patternLength) { - _rootNode = new SequenceNode(null); - _currentNode = _rootNode; - _level = 0; - } - - internal void AddChar(char c) { - _currentNode = _currentNode.AddChar(c); - } - - internal void StartLevel() { - _currentNode = _currentNode.StartLevel(); - _level++; - } - - internal void AddGroup() { - _currentNode = _currentNode.AddGroup(); - } - - internal void FinishLevel() { - _currentNode = _currentNode.FinishLevel(); - _level--; - } - internal int Level { - get { return _level; } - } - internal string[]/*!*/ Flatten() { - if (_level != 0) { - return ArrayUtils.EmptyStrings; - } - List list = _rootNode.Flatten(); - string[] result = new string[list.Count]; - for (int i = 0; i < list.Count; i++) { - result[i] = list[i].ToString(); - } - return result; - } - } - - private static string[] UngroupGlobs(string/*!*/ pattern, bool noEscape) { - if (pattern.IndexOf('{') < 0) { - if (pattern.IndexOf('}') < 0) { - return new string[1] { pattern }; - } else { - return ArrayUtils.EmptyStrings; - } - } - - GlobUngrouper ungrouper = new GlobUngrouper(pattern.Length); - - bool inEscape = false; - foreach (char c in pattern) { - if (c == '\\' && !inEscape && !noEscape) { - inEscape = true; - continue; - } - if (inEscape) { - if (c != ',' && c != '{' && c != '{') { - ungrouper.AddChar('\\'); - } - ungrouper.AddChar(c); - inEscape = false; - continue; - } - switch (c) { - case '{': - ungrouper.StartLevel(); - break; - - case ',': - if (ungrouper.Level < 1) { - ungrouper.AddChar(c); - } else { - ungrouper.AddGroup(); - } - break; - - case '}': - if (ungrouper.Level < 1) { - // Unbalanced closing bracket matches nothing - return ArrayUtils.EmptyStrings; - } - ungrouper.FinishLevel(); - break; - - default: - ungrouper.AddChar(c); - break; - } - } - return ungrouper.Flatten(); - } - - class GlobMatcher { - PlatformAdaptationLayer/*!*/ _pal; - string/*!*/ _pattern; - int _flags; - bool _dirOnly; - bool _stripTwo; - List/*!*/ _result; - - internal GlobMatcher(CodeContext/*!*/ context, string/*!*/ pattern, int flags) { - _pal = context.LanguageContext.DomainManager.Platform; - _pattern = (pattern == "**") ? "*" : pattern; - _flags = flags | RubyFileOps.Constants.FNM_CASEFOLD; - _result = new List(); - _dirOnly = (_pattern.Length > 0) && (_pattern[_pattern.Length - 1] == '/'); - _stripTwo = false; - } - - internal int FindNextSeparator(int position, bool allowWildcard, out bool containsWildcard) { - int lastSlash = -1; - bool inEscape = false; - containsWildcard = false; - for (int i = position; i < _pattern.Length; i++) { - if (inEscape) { - inEscape = false; - continue; - } - char c = _pattern[i]; - if (c == '\\') { - inEscape = true; - continue; - } else if (c == '*' || c == '?' || c == '[') { - if (!allowWildcard) { - return lastSlash + 1; - } else if (lastSlash >= 0) { - return lastSlash; - } - containsWildcard = true; - } else if (c == '/' || c == ':') { - if (containsWildcard) { - return i; - } - lastSlash = i; - } - } - return _pattern.Length; - } - - private void TestPath(string path, int patternEnd, bool isLastPathSegment) { - if (!isLastPathSegment) { - DoGlob(path, patternEnd); - return; - } - string pathName = path.Replace('\\', '/'); - if (_stripTwo) { - pathName = pathName.Substring(2); - } - if (_pal.DirectoryExists(pathName)) { - _result.Add(pathName); - } else if (!_dirOnly && _pal.FileExists(pathName)) { - _result.Add(pathName); - } - } - - internal IList/*!*/ DoGlob() { - if (_pattern.Length == 0) { - return ArrayUtils.EmptyStrings; - } - - int pos = 0; - string baseDirectory = "."; - if (_pattern[0] == '/' || _pattern.IndexOf(':') >= 0) { - bool containsWildcard; - pos = FindNextSeparator(0, false, out containsWildcard); - if (pos == _pattern.Length) { - TestPath(_pattern, pos, true); - return _result; - } - if (pos > 0 || _pattern[0] == '/') { - baseDirectory = _pattern.Substring(0, pos); - } - } - - _stripTwo = (baseDirectory == "."); - - DoGlob(baseDirectory, pos); - return _result; - } - - internal void DoGlob(string/*!*/ baseDirectory, int position) { - if (!_pal.DirectoryExists(baseDirectory)) { - return; - } - - bool containsWildcard; - int patternEnd = FindNextSeparator(position, true, out containsWildcard); - bool isLastPathSegment = (patternEnd == _pattern.Length); - string dirSegment = _pattern.Substring(position, patternEnd - position); - - if (!isLastPathSegment) { - patternEnd++; - } - - if (!containsWildcard) { - string path = baseDirectory + "/" + dirSegment; - TestPath(path, patternEnd, isLastPathSegment); - return; - } - - MutableString mPattern = MutableString.Create(dirSegment); - bool doubleStar = dirSegment.Equals("**"); - if (doubleStar) { - DoGlob(baseDirectory, patternEnd); - } - - string[] files = Directory.GetFileSystemEntries(baseDirectory); - foreach (string file in files) { - string objectName = Path.GetFileName(file); - if (RubyFileOps.FnMatch(null, mPattern, MutableString.Create(objectName), _flags)) { - TestPath(file, patternEnd, isLastPathSegment); - if (doubleStar) { - DoGlob(file, position); - } - } - } - if (isLastPathSegment && (_flags & RubyFileOps.Constants.FNM_DOTMATCH) != 0 || mPattern.GetChar(0) == '.') { - if (RubyFileOps.FnMatch(null, mPattern, MutableString.Create("."), _flags)) { - string directory = baseDirectory + "/."; - if (_dirOnly) { - directory += '/'; - } - TestPath(directory, patternEnd, true); - } - if (RubyFileOps.FnMatch(null, mPattern, MutableString.Create(".."), _flags)) { - string directory = baseDirectory + "/.."; - if (_dirOnly) { - directory += '/'; - } - TestPath(directory, patternEnd, true); - } - } - } - } - - private static IList/*!*/ DoGlob(CodeContext/*!*/ context, string/*!*/ pattern, int flags) { - GlobMatcher matcher = new GlobMatcher(context, pattern, flags); - return matcher.DoGlob(); - } - - private static IEnumerable/*!*/ GlobResults(CodeContext/*!*/ context, MutableString/*!*/ pattern, int flags) { - if (pattern.Length == 0) { - yield break; - } - bool noEscape = ((flags & RubyFileOps.Constants.FNM_NOESCAPE) != 0); - string sPattern = pattern.ConvertToString(); - string[] groups = UngroupGlobs(sPattern, noEscape); - if (groups.Length == 0) { - yield break; - } - - foreach (string group in groups) { - foreach (string filename in DoGlob(context, group, flags)) { - MutableString result = MutableString.Create(filename); - RubyUtils.FlowTaint(context, pattern, result); - yield return result; - } - } - } - [RubyMethod("glob", RubyMethodAttributes.PublicSingleton)] public static object Glob(CodeContext/*!*/ context, object self, BlockParam block, [NotNull]MutableString/*!*/ pattern, [Optional]int flags) { - foreach (MutableString fileName in GlobResults(context, pattern, flags)) { + foreach (MutableString fileName in Ruby.Builtins.Glob.GlobResults(context, pattern.ToString(), flags)) { object result = _GlobSite.Invoke(context, block, fileName); if (block.BlockJumped(result)) { return result; @@ -586,7 +196,7 @@ [RubyMethod("[]", RubyMethodAttributes.PublicSingleton)] public static RubyArray/*!*/ Glob(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ pattern, [Optional]int flags) { RubyArray ret = new RubyArray(); - foreach (MutableString fileName in GlobResults(context, pattern, flags)) { + foreach (MutableString fileName in Ruby.Builtins.Glob.GlobResults(context, pattern.ToString(), flags)) { ret.Add(fileName); } return ret; =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FileOps.cs;C479187 File: FileOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FileOps.cs;C479187 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FileOps.cs;fixes-2 @@ -18,9 +18,6 @@ using System.Runtime.InteropServices; using System.Scripting; using System.Scripting.Runtime; -using System.Text; -using System.Text.RegularExpressions; -using Microsoft.Scripting.Actions; using Ruby.Runtime; namespace Ruby.Builtins { @@ -53,14 +50,6 @@ return new RubyFile(RubyUtils.GetExecutionContext(context), path.ConvertToString(), (RubyFileMode)fileMode); } - private static MutableString/*!*/ CanonicalizePath(MutableString/*!*/ path) { - for (int i = 0; i < path.Length; i++) { - if (path.GetChar(i) == '\\') - path.SetChar(i, '/'); - } - return path; - } - #region Private Singleton Methods #endregion @@ -126,7 +115,7 @@ string basename = System.IO.Path.GetFileNameWithoutExtension(filename); string result = WildcardExtensionMatch(fileExtension, extensionFilter.ConvertToString()) ? basename : filename; - return CanonicalizePath(RubyUtils.FlowTaint(context, self, (result.Equals(root) ? MutableString.Create(root) : MutableString.Create(result)))); + return Glob.CanonicalizePath(RubyUtils.FlowTaint(context, self, (result.Equals(root) ? MutableString.Create(root) : MutableString.Create(result)))); } [RubyMethod("basename", RubyMethodAttributes.PublicSingleton)] @@ -231,7 +220,7 @@ [RubyMethod("dirname", RubyMethodAttributes.PublicSingleton)] public static MutableString/*!*/ DirName(CodeContext/*!*/ context, object/*!*/ self, MutableString/*!*/ path) { string directoryName = System.IO.Path.GetDirectoryName(path.ConvertToString()); - return CanonicalizePath(MutableString.Create(String.IsNullOrEmpty(directoryName) ? "." : directoryName)); + return Glob.CanonicalizePath(MutableString.Create(String.IsNullOrEmpty(directoryName) ? "." : directoryName)); } [RubyMethod("executable?", RubyMethodAttributes.PublicSingleton)] @@ -281,124 +270,10 @@ #region fnmatch - private class CharClass { - private readonly StringBuilder/*!*/ _chars = new StringBuilder(); - - internal void Add(char c) { - if (c == ']' || c == '\\') { - _chars.Append('\\'); - } - _chars.Append(c); - } - - internal string MakeString() { - if (_chars.Length == 0) { - return null; - } - if (_chars.Length == 1 && _chars[0] == '^') { - _chars.Insert(0, "\\"); - } - _chars.Insert(0, "["); - _chars.Append(']'); - return _chars.ToString(); - } - } - - private static void AppendExplicitRegexChar(StringBuilder/*!*/ builder, char c) { - builder.Append('['); - if (c == '^' || c == '\\') { - builder.Append('\\'); - } - builder.Append(c); - builder.Append(']'); - } - - internal static string/*!*/ PatternToRegex(string/*!*/ pattern, bool pathName, bool noEscape) { - StringBuilder result = new StringBuilder(pattern.Length); - result.Append("\\G"); - - bool inEscape = false; - CharClass charClass = null; - - foreach (char c in pattern) { - if (c == '\\' && !inEscape && !noEscape) { - inEscape = true; - continue; - } - if (inEscape) { - if (charClass != null) { - charClass.Add(c); - } else { - AppendExplicitRegexChar(result, c); - } - inEscape = false; - continue; - } - if (charClass != null) { - if (c == ']') { - string set = charClass.MakeString(); - if (set == null) { - // Ruby regex "[]" matches nothing - // CLR regex "[]" throws exception - return String.Empty; - } - result.Append(set); - charClass = null; - } else { - charClass.Add(c); - } - continue; - } - switch (c) { - case '*': - result.Append(pathName ? "[^/]*" : ".*"); - break; - - case '?': - result.Append('.'); - break; - - case '[': - charClass = new CharClass(); - break; - - default: - AppendExplicitRegexChar(result, c); - break; - } - } - - return (charClass == null) ? result.ToString() : String.Empty; - } - [RubyMethod("fnmatch", RubyMethodAttributes.PublicSingleton)] [RubyMethod("fnmatch?", RubyMethodAttributes.PublicSingleton)] public static bool FnMatch(object self/*!*/, [NotNull]MutableString/*!*/ pattern, [NotNull]MutableString/*!*/ path, [Optional]int flags) { - if (pattern.Length == 0) { - return path.Length == 0; - } - - bool pathName = ((flags & Constants.FNM_PATHNAME) != 0); - bool noEscape = ((flags & Constants.FNM_NOESCAPE) != 0); - string sPath = path.ConvertToString(); - string regexPattern = PatternToRegex(pattern.ConvertToString(), pathName, noEscape); - if (regexPattern.Length == 0) { - return false; - } - - if (((flags & Constants.FNM_DOTMATCH) == 0) && sPath.Length > 0 && sPath[0] == '.') { - // Starting dot requires an explicit dot in the pattern - if (regexPattern.Length < 4 || regexPattern[2] != '[' || regexPattern[3] != '.') { - return false; - } - } - - RegexOptions options = RegexOptions.None; - if ((flags & Constants.FNM_CASEFOLD) != 0) { - options |= RegexOptions.IgnoreCase; - } - Match match = Regex.Match(sPath, regexPattern, options); - return match != null && match.Success && (match.Length == path.Length); + return Glob.FnMatch(pattern, path, flags); } #endregion @@ -454,54 +329,100 @@ #region expand_path - private static MutableString ParsePathForProfileDir(MutableString path) { -#if SILVERLIGHT - throw new NotImplementedException(); -#else +#if !SILVERLIGHT + // Algorithm to find HOME equivalents under Windows. This is equivalent to Ruby 1.9 behavior: + // + // 1. Try get HOME + // 2. Try to generate HOME equivalent using HOMEDRIVE + HOMEPATH + // 3. Try to generate HOME equivalent from USERPROFILE + // 4. Try to generate HOME equivalent from Personal special folder + + internal static string/*!*/ GetHomeDirectory() { + string result = Environment.GetEnvironmentVariable("HOME"); + + if (result == null) { + string homeDrive = Environment.GetEnvironmentVariable("HOMEDRIVE"); + string homePath = Environment.GetEnvironmentVariable("HOMEPATH"); + if (homeDrive == null && homePath == null) { + string userEnvironment = Environment.GetEnvironmentVariable("USERPROFILE"); + if (userEnvironment == null) { + // This will always succeed with a non-null string, but it can fail + // if the Personal folder was renamed or deleted. In this case it returns + // an empty string. + result = Environment.GetFolderPath(Environment.SpecialFolder.Personal); + } else { + result = userEnvironment; + } + } else if (homeDrive == null) { + result = homePath; + } else if (homePath == null) { + result = homeDrive; + } else { + result = System.IO.Path.Combine(homeDrive, homePath); + } + } + return result; + } + + // Expand directory path - these cases exist: + // + // 1. Empty string or nil means return current directory + // 2. ~ with non-existent HOME directory throws exception + // 3. ~, ~/ or ~\ which expands to HOME + // 4. ~foo is left unexpanded + // 5. Expand to full path if path is a relative path + // + // No attempt is made to determine whether the path is valid or not + // Returned path is always canonicalized to forward slashes + + private static MutableString/*!*/ ExpandPath(MutableString/*!*/ path) { try { if (path == null || path.Length == 0) - return CanonicalizePath(MutableString.Create(Directory.GetCurrentDirectory())); + return Glob.CanonicalizePath(MutableString.Create(Directory.GetCurrentDirectory())); if (path.Length == 1 && path.GetChar(0) == '~') - return CanonicalizePath(MutableString.Create(System.IO.Path.GetFullPath(Environment.GetEnvironmentVariable("HOME")))); + return Glob.CanonicalizePath(MutableString.Create(System.IO.Path.GetFullPath(Environment.GetEnvironmentVariable("HOME")))); if (path.GetChar(0) == '~' && (path.GetChar(1) == System.IO.Path.DirectorySeparatorChar || path.GetChar(1) == System.IO.Path.AltDirectorySeparatorChar)) { string homeDirectory = Environment.GetEnvironmentVariable("HOME"); - return CanonicalizePath(path.Length < 3 ? MutableString.Create(homeDirectory) : MutableString.Create(System.IO.Path.Combine(homeDirectory, path.GetSlice(2).ConvertToString()))); + return Glob.CanonicalizePath(path.Length < 3 ? MutableString.Create(homeDirectory) : MutableString.Create(System.IO.Path.Combine(homeDirectory, path.GetSlice(2).ConvertToString()))); } else { - return CanonicalizePath(MutableString.Create(System.IO.Path.GetFullPath(path.ConvertToString()))); + return Glob.CanonicalizePath(MutableString.Create(System.IO.Path.GetFullPath(path.ConvertToString()))); } } catch (Exception e) { // Re-throw exception as a reasonable Ruby exception throw new Errno.InvalidError(path.ConvertToString(), e); } -#endif } - [RubyMethod("expand_path", RubyMethodAttributes.PublicSingleton)] - public static MutableString ExpandPath(object/*!*/ self, [NotNull]MutableString/*!*/ path) { - return ParsePathForProfileDir(path); + [RubyMethod("expand_path", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static MutableString/*!*/ ExpandPath(object/*!*/ self, [NotNull]MutableString/*!*/ path) { + return ExpandPath(path); } - [RubyMethod("expand_path", RubyMethodAttributes.PublicSingleton)] - public static MutableString ExpandPath(CodeContext/*!*/ context, object/*!*/ self, object path) { - return ParsePathForProfileDir(Protocols.CastToString(context, path)); + [RubyMethod("expand_path", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static MutableString/*!*/ ExpandPath(CodeContext/*!*/ context, object/*!*/ self, object path) { + return ExpandPath(Protocols.CastToString(context, path)); } - [RubyMethod("expand_path", RubyMethodAttributes.PublicSingleton)] - public static MutableString ExpandPath(object/*!*/ self, [NotNull]MutableString/*!*/ path, [NotNull]MutableString/*!*/ basePath) { + [RubyMethod("expand_path", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static MutableString/*!*/ ExpandPath(object/*!*/ self, [NotNull]MutableString/*!*/ path, [NotNull]MutableString/*!*/ basePath) { // We ignore basePath parameter if first string starts with a ~ if (path.Length > 0 && path.GetChar(0) == '~') { - return ParsePathForProfileDir(path); + return ExpandPath(path); } else { - return MutableString.Create(System.IO.Path.GetFullPath(System.IO.Path.Combine(ParsePathForProfileDir(basePath).ConvertToString(), path.ConvertToString()))); + return Glob.CanonicalizePath(MutableString.Create(System.IO.Path.GetFullPath(System.IO.Path.Combine(ExpandPath(basePath).ConvertToString(), path.ConvertToString())))); } } - [RubyMethod("expand_path", RubyMethodAttributes.PublicSingleton)] - public static MutableString ExpandPath(CodeContext/*!*/ context, object/*!*/ self, object path, object basePath) { - return ExpandPath(self, Protocols.CastToString(context, path), Protocols.CastToString(context, basePath)); + [RubyMethod("expand_path", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static MutableString/*!*/ ExpandPath(CodeContext/*!*/ context, object/*!*/ self, object path, object basePath) { + if (basePath == null) + return ExpandPath(self, Protocols.CastToString(context, path)); + else + return ExpandPath(self, Protocols.CastToString(context, path), Protocols.CastToString(context, basePath)); } +#endif #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/KernelOps.cs;C479187 File: KernelOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/KernelOps.cs;C479187 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/KernelOps.cs;fixes-2 @@ -17,17 +17,17 @@ using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Linq.Expressions; using System.Reflection; using System.Runtime.InteropServices; using System.Scripting; -using System.Linq.Expressions; using System.Scripting.Runtime; using System.Scripting.Utils; using System.Threading; using Microsoft.Scripting.Actions; using Microsoft.Scripting.Math; using Ruby.Runtime; -using Ruby.Runtime.Calls; +using Ruby.Runtime.Calls; namespace Ruby.Builtins { @@ -100,13 +100,122 @@ return Protocols.ConvertToString(context, obj); } - [RubyMethod("`", RubyMethodAttributes.PrivateInstance)] - [RubyMethod("`", RubyMethodAttributes.PublicSingleton)] - public static MutableString ExecuteCommand(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ command) { - // TODO: - throw new NotImplementedException(); + #region `, exec, system + +#if !SILVERLIGHT + // Looks for RUBYSHELL and then COMSPEC under Windows + // It appears that COMSPEC is a special environment variable that cannot be undefined + private static ProcessStartInfo/*!*/ GetShell(MutableString/*!*/ command) { + string shell = Environment.GetEnvironmentVariable("RUBYSHELL"); + if (shell == null) { + // Always succeeds + shell = Environment.GetEnvironmentVariable("COMSPEC"); + } + return new ProcessStartInfo(shell, String.Format("/C \"{0}\"", command.ConvertToString())); } - + + private static MutableString/*!*/ JoinArguments(CodeContext/*!*/ context, object[] args) { + MutableString result = MutableString.CreateEmpty(); + + for (int i = 0; i < args.Length; i++) { + result.Append(Protocols.CastToString(context, args[i])); + if (args.Length > 1 && i < args.Length - 1) + result.Append(" "); + } + + return result; + } + + private static Process/*!*/ ExecuteProcess(ProcessStartInfo/*!*/ psi) { + psi.UseShellExecute = false; + psi.RedirectStandardError = true; + try { + Process p = Process.Start(psi); + p.WaitForExit(); + return p; + } catch (System.ComponentModel.Win32Exception e) { + throw new Errno.NoEntryError(psi.FileName, e); + } + } + + // Executes a command in a shell child process + private static Process/*!*/ ExecuteCommandInShell(MutableString/*!*/ command) { + return ExecuteProcess(GetShell(command)); + } + + // Executes a command directly in a child process - command is the name of the executable + private static Process/*!*/ ExecuteCommand(CodeContext/*!*/ context, MutableString/*!*/ command, object/*!*/[] args) { + return ExecuteProcess(new ProcessStartInfo(command.ToString(), JoinArguments(context, args).ToString())); + } + + // Backtick always executes the command in a shell child process + + [RubyMethod("`", RubyMethodAttributes.PrivateInstance, BuildConfig = "!SILVERLIGHT")] + [RubyMethod("`", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static MutableString/*!*/ ExecuteCommand(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ command) { + ProcessStartInfo psi = GetShell(command); + psi.RedirectStandardOutput = true; + + Process p = ExecuteProcess(psi); + MutableString result = MutableString.Create(p.StandardOutput.ReadToEnd()); + RubyUtils.GetExecutionContext(context).ChildProcessExitStatus = new RubyProcess.Status(p); + return result; + } + + [RubyMethod("`", RubyMethodAttributes.PrivateInstance, BuildConfig = "!SILVERLIGHT")] + [RubyMethod("`", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static MutableString/*!*/ ExecuteCommand(CodeContext/*!*/ context, object self, object command) { + return ExecuteCommand(context, self, Protocols.CastToString(context, command)); + } + + // Overloads of exec and system will always execute using the Windows shell if there is only the command parameter + // If args parameter is passed, it will execute the command directly without going to the shell. + + [RubyMethod("exec", RubyMethodAttributes.PrivateInstance, BuildConfig = "!SILVERLIGHT")] + [RubyMethod("exec", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static void Execute(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ command) { + Process p = ExecuteCommandInShell(command); + Exit(context, self, p.ExitCode); + } + + [RubyMethod("exec", RubyMethodAttributes.PrivateInstance, BuildConfig = "!SILVERLIGHT")] + [RubyMethod("exec", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static void Execute(CodeContext/*!*/ context, object self, object command) { + Execute(context, self, Protocols.CastToString(context, command)); + } + + [RubyMethod("exec", RubyMethodAttributes.PrivateInstance, BuildConfig = "!SILVERLIGHT")] + [RubyMethod("exec", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static void Execute(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ command, [NotNull]params object/*!*/[] args) { + Process p = ExecuteCommand(context, command, args); + RubyUtils.GetExecutionContext(context).ChildProcessExitStatus = p.ExitCode; + Exit(context, self, p.ExitCode); + } + + [RubyMethod("system", RubyMethodAttributes.PrivateInstance, BuildConfig = "!SILVERLIGHT")] + [RubyMethod("system", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static bool System(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ command) { + Process p = ExecuteCommandInShell(command); + RubyUtils.GetExecutionContext(context).ChildProcessExitStatus = p.ExitCode; + return p.ExitCode == 0; + } + + [RubyMethod("system", RubyMethodAttributes.PrivateInstance, BuildConfig = "!SILVERLIGHT")] + [RubyMethod("system", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static bool System(CodeContext/*!*/ context, object self, object command) { + return System(context, self, Protocols.CastToString(context, command)); + } + + [RubyMethod("system", RubyMethodAttributes.PrivateInstance, BuildConfig = "!SILVERLIGHT")] + [RubyMethod("system", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] + public static bool System(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ command, [NotNull]params object/*!*/[] args) { + Process p = ExecuteCommand(context, command, args); + RubyUtils.GetExecutionContext(context).ChildProcessExitStatus = p.ExitCode; + return p.ExitCode == 0; + } +#endif + #endregion + //abort [RubyMethod("at_exit", RubyMethodAttributes.PrivateInstance)] @@ -170,16 +279,6 @@ return RubyUtils.Evaluate(code, procBinding.LocalScope, procBinding.LocalScope.SelfObject, null, file, line); } -#if !SILVERLIGHT - [RubyMethod("exec", RubyMethodAttributes.PrivateInstance, BuildConfig = "!SILVERLIGHT")] - [RubyMethod("exec", RubyMethodAttributes.PublicSingleton, BuildConfig = "!SILVERLIGHT")] - public static object Execute(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ command, [NotNull]MutableString/*!*/ arguments) { - Process result = Process.Start(command.ToString(), arguments.ToString()); - result.WaitForExit(); - return MutableString.Create(result.StandardOutput.ReadToEnd()); - } -#endif - [RubyMethod("exit", RubyMethodAttributes.PrivateInstance)] [RubyMethod("exit", RubyMethodAttributes.PublicSingleton)] public static void Exit(CodeContext/*!*/ context, object self) { @@ -682,7 +781,6 @@ //sub //sub! //syscall - //system //test //trace_var @@ -1212,5 +1310,4 @@ #endregion } -} - +} \ No newline at end of file =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RubyProcess.cs;C479187 File: RubyProcess.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RubyProcess.cs;C479187 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RubyProcess.cs;fixes-2 @@ -27,6 +27,59 @@ [RubyModule("Process", BuildConfig = "!SILVERLIGHT")] public static class RubyProcess { + [RubyClass("Status", BuildConfig = "!SILVERLIGHT")] + public class Status { + private Process/*!*/ _process; + + public Status(Process/*!*/ process) { + _process = process; + } + + [RubyMethod("coredump?")] + public static bool CoreDump(Status/*!*/ self) { + // Always false on Windows + return false; + } + + [RubyMethod("exitstatus")] + public static int ExitStatus(Status/*!*/ self) { + return self._process.ExitCode; + } + + [RubyMethod("exited?")] + public static bool Exited(Status/*!*/ self) { + return self._process.HasExited; + } + + [RubyMethod("pid")] + public static int Pid(Status/*!*/ self) { + return self._process.Id; + } + + [RubyMethod("stopped?")] + public static bool Stopped(Status/*!*/ self) { + // Always false on Windows + return false; + } + + [RubyMethod("stopsig")] + public static object StopSig(Status/*!*/ self) { + // Always nil on Windows + return null; + } + + [RubyMethod("success?")] + public static bool Success(Status/*!*/ self) { + return self._process.ExitCode == 0; + } + + [RubyMethod("termsig")] + public static object TermSig(Status/*!*/ self) { + // Always nil on Windows + return null; + } + } + // abort // detach // egid =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libs/rbconfig.rb;C446709 File: rbconfig.rb =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libs/rbconfig.rb;C446709 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libs/rbconfig.rb;fixes-2 @@ -16,8 +16,8 @@ CONFIG["PATCHLEVEL"] = "0" CONFIG["prefix"] = (TOPDIR || DESTDIR + "") CONFIG["EXEEXT"] = ".exe" - CONFIG["ruby_install_name"] = "ruby" - CONFIG["RUBY_INSTALL_NAME"] = "ruby" + CONFIG["ruby_install_name"] = "ironruby" + CONFIG["RUBY_INSTALL_NAME"] = "ironruby" CONFIG["RUBY_SO_NAME"] = "msvcrt-ruby18" CONFIG["SHELL"] = "$(COMSPEC)" CONFIG["BUILD_FILE_SEPARATOR"] = "\\" =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C474221 File: Ruby.csproj =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C474221 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;fixes-2 @@ -92,6 +92,7 @@ + =================================================================== add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/Glob.cs File: Glob.cs =================================================================== --- [no source file] +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/Glob.cs;fixes-2 @@ -1,0 +1,532 @@ +?using System; +using System.Collections.Generic; +using System.IO; +using System.Scripting; +using System.Scripting.Runtime; +using System.Scripting.Utils; +using System.Text; +using System.Text.RegularExpressions; +using Ruby.Runtime; + +namespace Ruby.Builtins { + public class Glob { + // Duplicated constants from File.Constants + private static class Constants { + public readonly static int FNM_CASEFOLD = 0x08; + public readonly static int FNM_DOTMATCH = 0x04; + public readonly static int FNM_NOESCAPE = 0x01; + public readonly static int FNM_PATHNAME = 0x02; + public readonly static int FNM_SYSCASE = 0x08; + } + + private class CharClass { + private readonly StringBuilder/*!*/ _chars = new StringBuilder(); + + internal void Add(char c) { + if (c == ']' || c == '\\') { + _chars.Append('\\'); + } + _chars.Append(c); + } + + internal string MakeString() { + if (_chars.Length == 0) { + return null; + } + if (_chars.Length == 1 && _chars[0] == '^') { + _chars.Insert(0, "\\"); + } + _chars.Insert(0, "["); + _chars.Append(']'); + return _chars.ToString(); + } + } + + private static void AppendExplicitRegexChar(StringBuilder/*!*/ builder, char c) { + builder.Append('['); + if (c == '^' || c == '\\') { + builder.Append('\\'); + } + builder.Append(c); + builder.Append(']'); + } + + internal static string/*!*/ PatternToRegex(string/*!*/ pattern, bool pathName, bool noEscape) { + StringBuilder result = new StringBuilder(pattern.Length); + result.Append("\\G"); + + bool inEscape = false; + CharClass charClass = null; + + foreach (char c in pattern) { + if (c == '\\' && !inEscape && !noEscape) { + inEscape = true; + continue; + } + if (inEscape) { + if (charClass != null) { + charClass.Add(c); + } else { + AppendExplicitRegexChar(result, c); + } + inEscape = false; + continue; + } + if (charClass != null) { + if (c == ']') { + string set = charClass.MakeString(); + if (set == null) { + // Ruby regex "[]" matches nothing + // CLR regex "[]" throws exception + return String.Empty; + } + result.Append(set); + charClass = null; + } else { + charClass.Add(c); + } + continue; + } + switch (c) { + case '*': + result.Append(pathName ? "[^/]*" : ".*"); + break; + + case '?': + result.Append('.'); + break; + + case '[': + charClass = new CharClass(); + break; + + default: + AppendExplicitRegexChar(result, c); + break; + } + } + + return (charClass == null) ? result.ToString() : String.Empty; + } + + public static bool FnMatch(MutableString/*!*/ pattern, MutableString/*!*/ path, int flags) { + if (pattern.Length == 0) { + return path.Length == 0; + } + + bool pathName = ((flags & Constants.FNM_PATHNAME) != 0); + bool noEscape = ((flags & Constants.FNM_NOESCAPE) != 0); + string sPath = path.ConvertToString(); + string regexPattern = PatternToRegex(pattern.ConvertToString(), pathName, noEscape); + if (regexPattern.Length == 0) { + return false; + } + + if (((flags & Constants.FNM_DOTMATCH) == 0) && sPath.Length > 0 && sPath[0] == '.') { + // Starting dot requires an explicit dot in the pattern + if (regexPattern.Length < 4 || regexPattern[2] != '[' || regexPattern[3] != '.') { + return false; + } + } + + RegexOptions options = RegexOptions.None; + if ((flags & Constants.FNM_CASEFOLD) != 0) { + options |= RegexOptions.IgnoreCase; + } + Match match = Regex.Match(sPath, regexPattern, options); + return match != null && match.Success && (match.Length == path.Length); + } + + private class GlobUngrouper { + internal abstract class GlobNode { + internal readonly GlobNode/*!*/ _parent; + protected GlobNode(GlobNode parentNode) { + _parent = parentNode ?? this; + } + abstract internal GlobNode/*!*/ AddChar(char c); + abstract internal GlobNode/*!*/ StartLevel(); + abstract internal GlobNode/*!*/ AddGroup(); + abstract internal GlobNode/*!*/ FinishLevel(); + abstract internal List/*!*/ Flatten(); + } + + internal class TextNode : GlobNode { + private readonly StringBuilder/*!*/ _builder; + + internal TextNode(GlobNode/*!*/ parentNode) + : base(parentNode) { + _builder = new StringBuilder(); + } + internal override GlobNode/*!*/ AddChar(char c) { + if (c != 0) { + _builder.Append(c); + } + return this; + } + internal override GlobNode/*!*/ StartLevel() { + return _parent.StartLevel(); + } + internal override GlobNode/*!*/ AddGroup() { + return _parent.AddGroup(); + } + internal override GlobNode/*!*/ FinishLevel() { + return _parent.FinishLevel(); + } + internal override List/*!*/ Flatten() { + List result = new List(1); + result.Add(_builder); + return result; + } + } + + internal class ChoiceNode : GlobNode { + private readonly List/*!*/ _nodes; + + internal ChoiceNode(GlobNode/*!*/ parentNode) + : base(parentNode) { + _nodes = new List(); + } + internal override GlobNode/*!*/ AddChar(char c) { + SequenceNode node = new SequenceNode(this); + _nodes.Add(node); + return node.AddChar(c); + } + internal override GlobNode/*!*/ StartLevel() { + SequenceNode node = new SequenceNode(this); + _nodes.Add(node); + return node.StartLevel(); + } + internal override GlobNode/*!*/ AddGroup() { + AddChar((char)0); + return this; + } + internal override GlobNode/*!*/ FinishLevel() { + AddChar((char)0); + return _parent; + } + internal override List/*!*/ Flatten() { + List result = new List(); + foreach (GlobNode node in _nodes) { + foreach (StringBuilder builder in node.Flatten()) { + result.Add(builder); + } + } + return result; + } + } + + internal class SequenceNode : GlobNode { + private readonly List/*!*/ _nodes; + + internal SequenceNode(GlobNode parentNode) + : base(parentNode) { + _nodes = new List(); + } + internal override GlobNode/*!*/ AddChar(char c) { + TextNode/*!*/ node = new TextNode(this); + _nodes.Add(node); + return node.AddChar(c); + } + internal override GlobNode/*!*/ StartLevel() { + ChoiceNode node = new ChoiceNode(this); + _nodes.Add(node); + return node; + } + internal override GlobNode/*!*/ AddGroup() { + return _parent; + } + internal override GlobNode/*!*/ FinishLevel() { + return _parent._parent; + } + internal override List/*!*/ Flatten() { + List result = new List(); + result.Add(new StringBuilder()); + foreach (GlobNode node in _nodes) { + List tmp = new List(); + foreach (StringBuilder builder in node.Flatten()) { + foreach (StringBuilder sb in result) { + StringBuilder newsb = new StringBuilder(sb.ToString()); + newsb.Append(builder.ToString()); + tmp.Add(newsb); + } + } + result = tmp; + } + return result; + } + } + + private readonly SequenceNode/*!*/ _rootNode; + private GlobNode/*!*/ _currentNode; + private int _level; + + internal GlobUngrouper(int patternLength) { + _rootNode = new SequenceNode(null); + _currentNode = _rootNode; + _level = 0; + } + + internal void AddChar(char c) { + _currentNode = _currentNode.AddChar(c); + } + + internal void StartLevel() { + _currentNode = _currentNode.StartLevel(); + _level++; + } + + internal void AddGroup() { + _currentNode = _currentNode.AddGroup(); + } + + internal void FinishLevel() { + _currentNode = _currentNode.FinishLevel(); + _level--; + } + internal int Level { + get { return _level; } + } + internal string[]/*!*/ Flatten() { + if (_level != 0) { + return ArrayUtils.EmptyStrings; + } + List list = _rootNode.Flatten(); + string[] result = new string[list.Count]; + for (int i = 0; i < list.Count; i++) { + result[i] = list[i].ToString(); + } + return result; + } + } + + private static string[] UngroupGlobs(string/*!*/ pattern, bool noEscape) { + if (pattern.IndexOf('{') < 0) { + if (pattern.IndexOf('}') < 0) { + return new string[1] { pattern }; + } else { + return ArrayUtils.EmptyStrings; + } + } + + GlobUngrouper ungrouper = new GlobUngrouper(pattern.Length); + + bool inEscape = false; + foreach (char c in pattern) { + if (c == '\\' && !inEscape && !noEscape) { + inEscape = true; + continue; + } + if (inEscape) { + if (c != ',' && c != '{' && c != '{') { + ungrouper.AddChar('\\'); + } + ungrouper.AddChar(c); + inEscape = false; + continue; + } + switch (c) { + case '{': + ungrouper.StartLevel(); + break; + + case ',': + if (ungrouper.Level < 1) { + ungrouper.AddChar(c); + } else { + ungrouper.AddGroup(); + } + break; + + case '}': + if (ungrouper.Level < 1) { + // Unbalanced closing bracket matches nothing + return ArrayUtils.EmptyStrings; + } + ungrouper.FinishLevel(); + break; + + default: + ungrouper.AddChar(c); + break; + } + } + return ungrouper.Flatten(); + } + + class GlobMatcher { + PlatformAdaptationLayer/*!*/ _pal; + string/*!*/ _pattern; + int _flags; + bool _dirOnly; + bool _stripTwo; + List/*!*/ _result; + + internal GlobMatcher(CodeContext/*!*/ context, string/*!*/ pattern, int flags) { + _pal = context.LanguageContext.DomainManager.Platform; + _pattern = (pattern == "**") ? "*" : pattern; + _flags = flags | Constants.FNM_CASEFOLD; + _result = new List(); + _dirOnly = (_pattern.Length > 0) && (_pattern[_pattern.Length - 1] == '/'); + _stripTwo = false; + } + + internal int FindNextSeparator(int position, bool allowWildcard, out bool containsWildcard) { + int lastSlash = -1; + bool inEscape = false; + containsWildcard = false; + for (int i = position; i < _pattern.Length; i++) { + if (inEscape) { + inEscape = false; + continue; + } + char c = _pattern[i]; + if (c == '\\') { + inEscape = true; + continue; + } else if (c == '*' || c == '?' || c == '[') { + if (!allowWildcard) { + return lastSlash + 1; + } else if (lastSlash >= 0) { + return lastSlash; + } + containsWildcard = true; + } else if (c == '/' || c == ':') { + if (containsWildcard) { + return i; + } + lastSlash = i; + } + } + return _pattern.Length; + } + + private void TestPath(string path, int patternEnd, bool isLastPathSegment) { + if (!isLastPathSegment) { + DoGlob(path, patternEnd); + return; + } + string pathName = path.Replace('\\', '/'); + if (_stripTwo) { + pathName = pathName.Substring(2); + } + if (_pal.DirectoryExists(pathName)) { + _result.Add(pathName); + } else if (!_dirOnly && _pal.FileExists(pathName)) { + _result.Add(pathName); + } + } + + internal IList/*!*/ DoGlob() { + if (_pattern.Length == 0) { + return ArrayUtils.EmptyStrings; + } + + int pos = 0; + string baseDirectory = "."; + if (_pattern[0] == '/' || _pattern.IndexOf(':') >= 0) { + bool containsWildcard; + pos = FindNextSeparator(0, false, out containsWildcard); + if (pos == _pattern.Length) { + TestPath(_pattern, pos, true); + return _result; + } + if (pos > 0 || _pattern[0] == '/') { + baseDirectory = _pattern.Substring(0, pos); + } + } + + _stripTwo = (baseDirectory == "."); + + DoGlob(baseDirectory, pos); + return _result; + } + + internal void DoGlob(string/*!*/ baseDirectory, int position) { + if (!_pal.DirectoryExists(baseDirectory)) { + return; + } + + bool containsWildcard; + int patternEnd = FindNextSeparator(position, true, out containsWildcard); + bool isLastPathSegment = (patternEnd == _pattern.Length); + string dirSegment = _pattern.Substring(position, patternEnd - position); + + if (!isLastPathSegment) { + patternEnd++; + } + + if (!containsWildcard) { + string path = baseDirectory + "/" + dirSegment; + TestPath(path, patternEnd, isLastPathSegment); + return; + } + + MutableString mPattern = MutableString.Create(dirSegment); + bool doubleStar = dirSegment.Equals("**"); + if (doubleStar) { + DoGlob(baseDirectory, patternEnd); + } + + string[] files = Directory.GetFileSystemEntries(baseDirectory); + foreach (string file in files) { + string objectName = Path.GetFileName(file); + if (FnMatch(mPattern, MutableString.Create(objectName), _flags)) { + TestPath(file, patternEnd, isLastPathSegment); + if (doubleStar) { + DoGlob(file, position); + } + } + } + if (isLastPathSegment && (_flags & Constants.FNM_DOTMATCH) != 0 || mPattern.GetChar(0) == '.') { + if (FnMatch(mPattern, MutableString.Create("."), _flags)) { + string directory = baseDirectory + "/."; + if (_dirOnly) { + directory += '/'; + } + TestPath(directory, patternEnd, true); + } + if (FnMatch(mPattern, MutableString.Create(".."), _flags)) { + string directory = baseDirectory + "/.."; + if (_dirOnly) { + directory += '/'; + } + TestPath(directory, patternEnd, true); + } + } + } + } + + private static IList/*!*/ DoGlob(CodeContext/*!*/ context, string/*!*/ pattern, int flags) { + GlobMatcher matcher = new GlobMatcher(context, pattern, flags); + return matcher.DoGlob(); + } + + public static MutableString/*!*/ CanonicalizePath(MutableString/*!*/ path) { + for (int i = 0; i < path.Length; i++) { + if (path.GetChar(i) == '\\') + path.SetChar(i, '/'); + } + return path; + } + + public static IEnumerable/*!*/ GlobResults(CodeContext/*!*/ context, string/*!*/ pattern, int flags) { + if (pattern.Length == 0) { + yield break; + } + bool noEscape = ((flags & Constants.FNM_NOESCAPE) != 0); + string sPattern = pattern; + string[] groups = UngroupGlobs(sPattern, noEscape); + if (groups.Length == 0) { + yield break; + } + + foreach (string group in groups) { + foreach (string filename in DoGlob(context, group, flags)) { + MutableString result = MutableString.Create(filename); + RubyUtils.FlowTaint(context, pattern, result); + yield return result; + } + } + } + } +} \ No newline at end of file =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Symbols.cs;C468100 File: Symbols.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Symbols.cs;C468100 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Symbols.cs;fixes-2 @@ -86,7 +86,7 @@ public static readonly SymbolId CommandLineArguments = Multiply; public static readonly SymbolId CommandLineProgramPath = SymbolTable.StringToId("0"); public static readonly SymbolId CurrentProcessId = SymbolTable.StringToId("$"); - public static readonly SymbolId ChildProcessExitCode = SymbolTable.StringToId("?"); + public static readonly SymbolId ChildProcessExitStatus = SymbolTable.StringToId("?"); public static readonly SymbolId IgnoreCaseComparator = SymbolTable.StringToId("="); public static readonly SymbolId LoadPath = SymbolTable.StringToId(":"); public static readonly SymbolId LoadedFiles = SymbolTable.StringToId("\""); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Tokenizer.cs;C474221 File: Tokenizer.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Tokenizer.cs;C474221 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/Tokenizer.cs;fixes-2 @@ -1386,7 +1386,7 @@ case '\\': return GlobalVariableToken(Symbols.OutputSeparator); case '*': return GlobalVariableToken(Symbols.CommandLineArguments); case '$': return GlobalVariableToken(Symbols.CurrentProcessId); - case '?': return GlobalVariableToken(Symbols.ChildProcessExitCode); + case '?': return GlobalVariableToken(Symbols.ChildProcessExitStatus); case '=': return GlobalVariableToken(Symbols.IgnoreCaseComparator); case ':': return GlobalVariableToken(Symbols.LoadPath); case '"': return GlobalVariableToken(Symbols.LoadedFiles); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyOptionsParser.cs;C468100 File: RubyOptionsParser.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyOptionsParser.cs;C468100 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyOptionsParser.cs;fixes-2 @@ -17,6 +17,7 @@ using System.Diagnostics; using System.IO; using System.Reflection; +using System.Scripting.Runtime; using System.Scripting.Utils; using Microsoft.Scripting; using Microsoft.Scripting.Hosting; @@ -46,6 +47,22 @@ return new RubyEngineOptions(); } + // TODO: tomat - move this code + private void ExpandArgument(CodeContext/*!*/ context, RubyArray/*!*/ args, string/*!*/ arg) { + if (arg.IndexOf('*') != -1 || arg.IndexOf('?') != -1) { + bool added = false; + foreach (MutableString path in Glob.GlobResults(context, arg, 0)) { + args.Add(MutableString.Create(path)); + added = true; + } + + if (!added) + args.Add(MutableString.Create(arg)); + } else { + args.Add(MutableString.Create(arg)); + } + } + // TODO: remove private void InitializeContext() { RubyContext context = (RubyContext)HostingHelpers.GetLanguageContext(Engine); @@ -57,7 +74,8 @@ RubyArray args = new RubyArray(); if (options.Arguments != null) { for (int i = 0; i < options.Arguments.Length; i++) { - args.Add(MutableString.Create(options.Arguments[i])); + // TODO: tomat - move this code + ExpandArgument(context.EmptyContext, args, options.Arguments[i].Replace('\\', '/')); } } objectClass.SetConstant("ARGV", args); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;C479187 File: RubyExecutionContext.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;C479187 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;fixes-2 @@ -16,9 +16,9 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq.Expressions; using System.Scripting; using System.Scripting.Actions; -using System.Linq.Expressions; using System.Scripting.Runtime; using System.Scripting.Utils; using System.Security; @@ -42,6 +42,12 @@ private static Exception _currentException; /// + /// $? of type Process::Status + /// + [ThreadStatic] + private static object _childProcessExitStatus; + + /// /// $SAFE /// [ThreadStatic] @@ -204,6 +210,11 @@ get { return _runtimeErrorSink; } } + public object ChildProcessExitStatus { + get { return _childProcessExitStatus; } + set { _childProcessExitStatus = value; } + } + public Scope/*!*/ TopGlobalScope { get { return _globalScope; } } @@ -213,9 +224,7 @@ } public Loader/*!*/ Loader { - get { - return _loader; - } + get { return _loader; } } public bool ShowCls { @@ -262,6 +271,7 @@ _currentException = null; _currentSafeLevel = 0; + _childProcessExitStatus = null; _inputSeparator = MutableString.Create("\n"); _outputSeparator = null; _stringSeparator = null; @@ -306,8 +316,7 @@ // $-p // $0 - // $? - + DefineGlobalVariableNoLock(SymbolTable.StringToId("stdin"), new GlobalVariableInfo(StandardInput)); DefineGlobalVariableNoLock(SymbolTable.StringToId("stdout"), Runtime.GlobalVariables.OutputStream); DefineGlobalVariableNoLock(SymbolTable.StringToId("stderr"), new GlobalVariableInfo(StandardErrorOutput)); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Globals/GlobalVariable.cs;C468100 File: GlobalVariable.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Globals/GlobalVariable.cs;C468100 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Globals/GlobalVariable.cs;fixes-2 @@ -37,7 +37,7 @@ public abstract void SetValue(RubyExecutionContext/*!*/ context, RubyScope scope, SymbolId name, object value); internal Exception/*!*/ ReadOnlyError(SymbolId name) { - return RubyExceptions.CreateNameError(String.Format("{0} is a read-only variable", SymbolTable.IdToString(name))); + return RubyExceptions.CreateNameError(String.Format("${0} is a read-only variable", SymbolTable.IdToString(name))); } internal T RequireType(object value, SymbolId variableName, string/*!*/ typeName) { =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Globals/GlobalVariables.cs;C468100 File: GlobalVariables.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Globals/GlobalVariables.cs;C468100 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Globals/GlobalVariables.cs;fixes-2 @@ -41,6 +41,7 @@ SafeLevel, KCode, + ChildProcessExitStatus } public static class GlobalVariables { @@ -73,6 +74,7 @@ public static readonly GlobalVariable SafeLevel = new SpecialGlobalVariableInfo(GlobalVariableId.SafeLevel); public static readonly GlobalVariable KCode = new SpecialGlobalVariableInfo(GlobalVariableId.KCode); + public static readonly GlobalVariable ChildProcessExitStatus = new SpecialGlobalVariableInfo(GlobalVariableId.ChildProcessExitStatus); // // Defines variables backed by a field on ExecutionContext or Scope and variables that derived from them. @@ -103,6 +105,7 @@ context.DefineGlobalVariableNoLock(Symbols.LoadedFiles, LoadedFiles); context.DefineGlobalVariableNoLock(Symbols.LoadPath, LoadPath); context.DefineGlobalVariableNoLock(Symbols.LastInputLineNumber, LastInputLineNumber); - } + context.DefineGlobalVariableNoLock(Symbols.ChildProcessExitStatus, ChildProcessExitStatus); + } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Globals/SpecialGlobalVariableInfo.cs;C468100 File: SpecialGlobalVariableInfo.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Globals/SpecialGlobalVariableInfo.cs;C468100 (server) 7/8/2008 7:53 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Globals/SpecialGlobalVariableInfo.cs;fixes-2 @@ -109,6 +109,9 @@ string name = context.GetKCodeName(); return (name != null) ? MutableString.Create(name) : null; + case GlobalVariableId.ChildProcessExitStatus: + return context.ChildProcessExitStatus; + default: throw Assert.Unreachable; } @@ -203,6 +206,9 @@ context.SetKCode((value != null) ? RequireType(value, name, "String") : null); return; + case GlobalVariableId.ChildProcessExitStatus: + throw ReadOnlyError(name); + default: throw Assert.Unreachable; } ===================================================================