diff options
| -rw-r--r-- | .travis.yml | 7 | ||||
| -rw-r--r-- | CONTRIBUTING.md | 2 | ||||
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | README.md | 6 | ||||
| -rw-r--r-- | doc/guides/compile.md | 8 | ||||
| -rw-r--r-- | doc/guides/mrbgems.md | 6 | ||||
| -rw-r--r-- | include/mruby/class.h | 6 | ||||
| -rw-r--r-- | lib/mruby/build.rb | 2 | ||||
| -rw-r--r-- | lib/mruby/build/command.rb | 26 | ||||
| -rw-r--r-- | lib/mruby/build/load_gems.rb | 13 | ||||
| -rwxr-xr-x | minirake | 623 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-debugger/bintest/print.rb | 26 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c | 4 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/parse.y | 56 | ||||
| -rw-r--r-- | mrbgems/mruby-io/mrblib/file.rb | 66 | ||||
| -rw-r--r-- | mrbgems/mruby-io/src/file.c | 5 | ||||
| -rw-r--r-- | mrbgems/mruby-io/src/file_test.c | 5 | ||||
| -rw-r--r-- | mrbgems/mruby-io/src/io.c | 13 | ||||
| -rw-r--r-- | mrbgems/mruby-metaprog/src/metaprog.c | 33 | ||||
| -rw-r--r-- | src/class.c | 10 | ||||
| -rw-r--r-- | src/error.c | 4 | ||||
| -rw-r--r-- | src/gc.c | 2 | ||||
| -rw-r--r-- | tasks/gitlab.rake | 2 | ||||
| -rw-r--r-- | tasks/toolchains/android.rake | 4 | ||||
| -rw-r--r-- | tasks/toolchains/gcc.rake | 2 | ||||
| -rw-r--r-- | test/t/syntax.rb | 9 |
26 files changed, 159 insertions, 785 deletions
diff --git a/.travis.yml b/.travis.yml index 9ef7009a6..fde7f7525 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,11 +9,6 @@ matrix: - os: osx osx_image: xcode7.1 -addons: - apt: - packages: - - gperf - env: - MRUBY_CONFIG=travis_config.rb -script: "./minirake -j4 all test" +script: "rake -m && rake test" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3a7428a88..0b632f51c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ things in mind before submitting your pull request: * Work on the latest possible state of **mruby/master** * Create a branch which is dedicated to your change -* Test your changes before creating a pull request (```./minirake test```) +* Test your changes before creating a pull request (```rake test```) * If possible write a test case which confirms your change * Don't mix several features or bug-fixes in one pull request * Create a meaningful commit message @@ -1,8 +1,6 @@ # mruby is using Rake (http://rake.rubyforge.org) as a build tool. -# We provide a minimalistic version called minirake inside of our -# codebase. -RAKE = ruby ./minirake +RAKE = rake all : $(RAKE) @@ -44,11 +44,7 @@ See the [compile.md](https://github.com/mruby/mruby/blob/master/doc/guides/compi To run the tests, execute the following from the project's root directory. - $ make test - -Or - - $ ruby ./minirake test + $ rake test ## Building documentation diff --git a/doc/guides/compile.md b/doc/guides/compile.md index 6a093310a..ba23fcfb4 100644 --- a/doc/guides/compile.md +++ b/doc/guides/compile.md @@ -32,10 +32,10 @@ All tools necessary to compile mruby can be set or modified here. In case you want to maintain an additional *build_config.rb* you can define a customized path using the *$MRUBY_CONFIG* environment variable. -To compile just call `./minirake` inside of the mruby source root. To -generate and execute the test tools call `./minirake test`. To clean -all build files call `./minirake clean`. To see full command line on -build, call `./minirake -v`. +To compile just call `rake` inside of the mruby source root. To +generate and execute the test tools call `rake test`. To clean +all build files call `rake clean`. To see full command line on +build, call `rake -v`. ## Build Configuration diff --git a/doc/guides/mrbgems.md b/doc/guides/mrbgems.md index 184f62954..ffbf17f26 100644 --- a/doc/guides/mrbgems.md +++ b/doc/guides/mrbgems.md @@ -45,8 +45,8 @@ conf.gem mgem: 'mruby-redis', checksum_hash: '3446d19fc4a3f9697b5ddbf2a904f301c4 If there is missing dependencies, mrbgem dependencies solver will reference mrbgem from core or mgem-list. -To pull all gems from remote GIT repository on build, call ```./minirake -p```, -or ```./minirake --pull-gems```. +To pull all gems from remote GIT repository on build, call ```rake -p```, +or ```rake --pull-gems```. NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version. @@ -235,7 +235,7 @@ So it is recommended not to put GEM's local header files on include/. These exports are retroactive. For example: when B depends to C and A depends to B, A will get include paths exported by C. -Exported include_paths are automatically appended to GEM local include_paths by Minirake. +Exported include_paths are automatically appended to GEM local include_paths by rake. You can use `spec.export_include_paths` accessor if you want more complex build. diff --git a/include/mruby/class.h b/include/mruby/class.h index c15633e83..cbf96fef2 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -95,6 +95,12 @@ void mrb_gc_mark_mt(mrb_state*, struct RClass*); size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*); void mrb_gc_free_mt(mrb_state*, struct RClass*); +#ifdef MRB_METHOD_CACHE +void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c); +#else +#define mrb_mc_clear_by_class(mrb,c) +#endif + MRB_END_DECL #endif /* MRUBY_CLASS_H */ diff --git a/lib/mruby/build.rb b/lib/mruby/build.rb index 55b82cd2b..c080857a0 100644 --- a/lib/mruby/build.rb +++ b/lib/mruby/build.rb @@ -280,7 +280,7 @@ EOS if name.is_a?(Array) name.flatten.map { |n| cygwin_filename(n) } else - `cygpath -w "#{filename(name)}"`.strip + '"%s"' % `cygpath -w "#{filename(name)}"`.strip end end diff --git a/lib/mruby/build/command.rb b/lib/mruby/build/command.rb index 0a6d6b818..6eb4b6628 100644 --- a/lib/mruby/build/command.rb +++ b/lib/mruby/build/command.rb @@ -279,36 +279,42 @@ module MRuby class Command::Git < Command attr_accessor :flags - attr_accessor :clone_options, :pull_options, :checkout_options, :reset_options + attr_accessor :clone_options, :pull_options, :checkout_options, :checkout_detach_options, :reset_options def initialize(build) super @command = 'git' @flags = %w[] @clone_options = "clone %{flags} %{url} %{dir}" - @pull_options = "--git-dir #{shellquote("%{repo_dir}/.git")} --work-tree #{shellquote("%{repo_dir}")} pull" - @checkout_options = "--git-dir #{shellquote("%{repo_dir}/.git")} --work-tree #{shellquote("%{repo_dir}")} checkout %{checksum_hash}" - @reset_options = "--git-dir #{shellquote("%{repo_dir}/.git")} --work-tree #{shellquote("%{repo_dir}")} reset %{checksum_hash}" + @pull_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} pull" + @checkout_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} checkout %{checksum_hash}" + @checkout_detach_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} checkout --detach %{checksum_hash}" + @reset_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} reset %{checksum_hash}" end def run_clone(dir, url, _flags = []) _pp "GIT", url, dir.relative_path - _run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => url, :dir => filename(dir) } + _run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => shellquote(url), :dir => shellquote(filename(dir)) } end def run_pull(dir, url) _pp "GIT PULL", url, dir.relative_path - _run pull_options, { :repo_dir => dir } + _run pull_options, { :repo_dir => shellquote(dir) } end def run_checkout(dir, checksum_hash) - _pp "GIT CHECKOUT", checksum_hash - _run checkout_options, { :checksum_hash => checksum_hash, :repo_dir => dir } + _pp "GIT CHECKOUT", dir, checksum_hash + _run checkout_options, { :checksum_hash => checksum_hash, :repo_dir => shellquote(dir) } + end + + def run_checkout_detach(dir, checksum_hash) + _pp "GIT CHECKOUT DETACH", dir, checksum_hash + _run checkout_detach_options, { :checksum_hash => checksum_hash, :repo_dir => shellquote(dir) } end def run_reset_hard(dir, checksum_hash) - _pp "GIT RESET", checksum_hash - _run reset_options, { :checksum_hash => checksum_hash, :repo_dir => dir } + _pp "GIT RESET", dir, checksum_hash + _run reset_options, { :checksum_hash => checksum_hash, :repo_dir => shellquote(dir) } end def commit_hash(dir) diff --git a/lib/mruby/build/load_gems.rb b/lib/mruby/build/load_gems.rb index f6deb5168..17035c459 100644 --- a/lib/mruby/build/load_gems.rb +++ b/lib/mruby/build/load_gems.rb @@ -86,14 +86,13 @@ module MRuby if File.exist?(gemdir) if $pull_gems - git.run_pull gemdir, url # Jump to the top of the branch - git.run_checkout(gemdir, branch) - git.run_reset_hard gemdir, "origin/#{branch}" + git.run_checkout gemdir, branch + git.run_pull gemdir, url elsif params[:checksum_hash] - git.run_reset_hard(gemdir, params[:checksum_hash]) + git.run_checkout_detach gemdir, params[:checksum_hash] elsif lock - git.run_reset_hard(gemdir, lock['commit']) + git.run_checkout_detach gemdir, lock['commit'] end else options = [params[:options]] || [] @@ -105,9 +104,9 @@ module MRuby # Jump to the specified commit if params[:checksum_hash] - git.run_reset_hard gemdir, params[:checksum_hash] + git.run_checkout_detach gemdir, params[:checksum_hash] elsif lock - git.run_reset_hard gemdir, lock['commit'] + git.run_checkout_detach gemdir, lock['commit'] end end @@ -1,621 +1,2 @@ -#!/usr/bin/env ruby - -# Original is https://github.com/jimweirich/rake/ -# Copyright (c) 2003 Jim Weirich -# License: MIT-LICENSE - -require 'getoptlong' -require 'fileutils' - -$rake_fiber_table = {} -$rake_jobs = 1 -$rake_failed = [] - -class String - def ext(newext='') - return self.dup if ['.', '..'].include? self - if newext != '' - newext = (newext =~ /^\./) ? newext : ("." + newext) - end - self.chomp(File.extname(self)) << newext - end - - def pathmap(spec=nil, &block) - return self if spec.nil? - result = '' - spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag| - case frag - when '%f' - result << File.basename(self) - when '%n' - result << File.basename(self).ext - when '%d' - result << File.dirname(self) - when '%x' - result << File.extname(self) - when '%X' - result << self.ext - when '%p' - result << self - when '%s' - result << (File::ALT_SEPARATOR || File::SEPARATOR) - when '%-' - # do nothing - when '%%' - result << "%" - when /%(-?\d+)d/ - result << pathmap_partial($1.to_i) - when /^%\{([^}]*)\}(\d*[dpfnxX])/ - patterns, operator = $1, $2 - result << pathmap('%' + operator).pathmap_replace(patterns, &block) - when /^%/ - fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'" - else - result << frag - end - end - result - end -end - -module MiniRake - class Task - TASKS = Hash.new - RULES = Array.new - - # List of prerequisites for a task. - attr_reader :prerequisites - - # Source dependency for rule synthesized tasks. Nil if task was not - # sythesized from a rule. - attr_accessor :source - - # Create a task named +task_name+ with no actions or prerequisites.. - # use +enhance+ to add actions and prerequisites. - def initialize(task_name) - @name = task_name - @prerequisites = [] - @actions = [] - end - - # Enhance a task with prerequisites or actions. Returns self. - def enhance(deps=nil, &block) - @prerequisites |= deps if deps - @actions << block if block_given? - self - end - - # Name of the task. - def name - @name.to_s - end - - def done?; @done end - def running?; @running end - - # Invoke the task if it is needed. Prerequisites are invoked first. - def invoke - puts "Invoke #{name} (already=[#{@already_invoked}], needed=[#{needed?}])" if $trace - return if @already_invoked - prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten - prerequisites.each do |n| - t = Task[n] - unless t.done? - return prerequisites.select{|v| v = Task[v]; v && (!v.done? || !v.running?) } - end - end - - @already_invoked = true - - if needed? - @running = true - if $rake_root_fiber - return Fiber.new do - self.execute - $rake_root_fiber.transfer - end - else - self.execute - end - end - - @done = true - end - - # Execute the actions associated with this task. - def execute - puts "Execute #{name}" if $trace - self.class.enhance_with_matching_rule(name) if @actions.empty? - unless $dryrun - @actions.each { |act| act.call(self) } - end - @done = true - @running = false - end - - # Is this task needed? - def needed? - true - end - - # Timestamp for this task. Basic tasks return the current time for - # their time stamp. Other tasks can be more sophisticated. - def timestamp - Time.now - end - - # Class Methods ---------------------------------------------------- - - class << self - - # Clear the task list. This cause rake to immediately forget all - # the tasks that have been assigned. (Normally used in the unit - # tests.) - def clear - TASKS.clear - RULES.clear - end - - # List of all defined tasks. - def tasks - TASKS.keys.sort.collect { |tn| Task[tn] } - end - - # Return a task with the given name. If the task is not currently - # known, try to synthesize one from the defined rules. If no - # rules are found, but an existing file matches the task name, - # assume it is a file task with no dependencies or actions. - def [](task_name) - task_name = task_name.to_s - if task = TASKS[task_name] - return task - end - if task = enhance_with_matching_rule(task_name) - return task - end - if File.exist?(task_name) - return FileTask.define_task(task_name) - end - fail "Don't know how to rake #{task_name}" - end - - # Define a task given +args+ and an option block. If a rule with - # the given name already exists, the prerequisites and actions are - # added to the existing task. - def define_task(args, &block) - task_name, deps = resolve_args(args) - lookup(task_name).enhance([deps].flatten, &block) - end - - # Define a rule for synthesizing tasks. - def create_rule(args, &block) - pattern, deps = resolve_args(args) - pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern - RULES << [pattern, deps, block] - end - - - # Lookup a task. Return an existing task if found, otherwise - # create a task of the current type. - def lookup(task_name) - name = task_name.to_s - TASKS[name] ||= self.new(name) - end - - # If a rule can be found that matches the task name, enhance the - # task with the prerequisites and actions from the rule. Set the - # source attribute of the task appropriately for the rule. Return - # the enhanced task or nil of no rule was found. - def enhance_with_matching_rule(task_name, level=0) - fail "Rule Recursion Too Deep: #{task_name}" if level >= 16 - RULES.each do |pattern, extensions, block| - next unless pattern && pattern.match(task_name) - sources = extensions.flat_map do |ext| - case ext - when /%/ - task_name.pathmap(ext) - when %r{/} - ext - when /^\./ - source = task_name.sub(pattern, ext) - source == ext ? task_name.ext(ext) : source - when String - ext - when Proc, Method - ext.arity == 1 ? ext.call(task_name) : ext.call - else - fail "Don't know how to handle rule dependent: #{ext.inspect}" - end - end - prereqs = sources.map do |source| - if File.exist?(source) || TASKS[source] - source - elsif parent = enhance_with_matching_rule(source, level + 1) - parent.name - else - break nil - end - end - if prereqs - task = FileTask.define_task(task_name => prereqs, &block) - task.source = prereqs.first - return task - end - end - nil - end - - private - - # Resolve the arguments for a task/rule. - def resolve_args(args) - case args - when Hash - fail "Too Many Task Names: #{args.keys.join(' ')}" if args.size > 1 - fail "No Task Name Given" if args.size < 1 - task_name = args.keys[0] - deps = args[task_name] - deps = [deps] if (String===deps) || (Regexp===deps) || (Proc===deps) - else - task_name = args - deps = [] - end - [task_name, deps] - end - end - end - - - ###################################################################### - class FileTask < Task - # Is this file task needed? Yes if it doesn't exist, or if its time - # stamp is out of date. - def needed? - return true unless File.exist?(name) - prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten - latest_prereq = prerequisites.collect{|n| Task[n].timestamp}.max - return false if latest_prereq.nil? - timestamp < latest_prereq - end - - # Time stamp for file task. - def timestamp - return Time.at(0) unless File.exist?(name) - stat = File::stat(name.to_s) - stat.directory? ? Time.at(0) : stat.mtime - end - end - - module DSL - # Declare a basic task. - def task(args, &block) - MiniRake::Task.define_task(args, &block) - end - - # Declare a file task. - def file(args, &block) - MiniRake::FileTask.define_task(args, &block) - end - - # Declare a set of files tasks to create the given directories on - # demand. - def directory(args, &block) - MiniRake::FileTask.define_task(args) do |t| - block.call(t) unless block.nil? - dir = args.is_a?(Hash) ? args.keys.first : args - (dir.split(File::SEPARATOR) + ['']).inject do |acc, part| - (acc + File::SEPARATOR).tap do |d| - Dir.mkdir(d) unless File.exists? d - end + part - end - end - end - - # Declare a rule for auto-tasks. - def rule(args, &block) - MiniRake::Task.create_rule(args, &block) - end - - # Write a message to standard out if $verbose is enabled. - def log(msg) - print " " if $trace && $verbose - puts msg if $verbose - end - - # Run the system command +cmd+. - def sh(cmd) - puts cmd if $verbose - - if !$rake_root_fiber || Fiber.current == $rake_root_fiber - system(cmd) or fail "Command Failed: [#{cmd}]" - return - end - - pid = Process.spawn(cmd) - $rake_fiber_table[pid] = { - fiber: Fiber.current, - command: cmd, - process_waiter: Process.detach(pid) - } - $rake_root_fiber.transfer - end - - def desc(text) - end - end -end - -Rake = MiniRake -extend MiniRake::DSL - - -###################################################################### -# Task Definition Functions ... - -###################################################################### -# Rake main application object. When invoking +rake+ from the command -# line, a RakeApp object is created and run. -# -class RakeApp - RAKEFILES = ['rakefile', 'Rakefile'] - - OPTIONS = [ - ['--dry-run', '-n', GetoptLong::NO_ARGUMENT, - "Do a dry run without executing actions."], - ['--help', '-H', GetoptLong::NO_ARGUMENT, - "Display this help message."], - ['--libdir', '-I', GetoptLong::REQUIRED_ARGUMENT, - "Include LIBDIR in the search path for required modules."], - ['--nosearch', '-N', GetoptLong::NO_ARGUMENT, - "Do not search parent directories for the Rakefile."], - ['--quiet', '-q', GetoptLong::NO_ARGUMENT, - "Do not log messages to standard output (default)."], - ['--rakefile', '-f', GetoptLong::REQUIRED_ARGUMENT, - "Use FILE as the rakefile."], - ['--require', '-r', GetoptLong::REQUIRED_ARGUMENT, - "Require MODULE before executing rakefile."], - ['--tasks', '-T', GetoptLong::NO_ARGUMENT, - "Display the tasks and dependencies, then exit."], - ['--pull-gems','-p', GetoptLong::NO_ARGUMENT, - "Pull all git mrbgems."], - ['--trace', '-t', GetoptLong::NO_ARGUMENT, - "Turn on invoke/execute tracing."], - ['--usage', '-h', GetoptLong::NO_ARGUMENT, - "Display usage."], - ['--verbose', '-v', GetoptLong::NO_ARGUMENT, - "Log message to standard output."], - ['--directory', '-C', GetoptLong::REQUIRED_ARGUMENT, - "Change executing directory of rakefiles."], - ['--jobs', '-j', GetoptLong::REQUIRED_ARGUMENT, - 'Execute rake with parallel jobs.'] - ] - - # Create a RakeApp object. - def initialize - @rakefile = nil - @nosearch = false - end - - # True if one of the files in RAKEFILES is in the current directory. - # If a match is found, it is copied into @rakefile. - def have_rakefile - RAKEFILES.each do |fn| - if File.exist?(fn) - @rakefile = fn - return true - end - end - return false - end - - # Display the program usage line. - def usage - puts "rake [-f rakefile] {options} targets..." - end - - # Display the rake command line help. - def help - usage - puts - puts "Options are ..." - puts - OPTIONS.sort.each do |long, short, mode, desc| - if mode == GetoptLong::REQUIRED_ARGUMENT - if desc =~ /\b([A-Z]{2,})\b/ - long = long + "=#{$1}" - end - end - printf " %-20s (%s)\n", long, short - printf " %s\n", desc - end - end - - # Display the tasks and dependencies. - def display_tasks - MiniRake::Task.tasks.each do |t| - puts "#{t.class} #{t.name}" - t.prerequisites.each { |pre| puts " #{pre}" } - end - end - - # Return a list of the command line options supported by the - # program. - def command_line_options - OPTIONS.collect { |lst| lst[0..-2] } - end - - # Do the option defined by +opt+ and +value+. - def do_option(opt, value) - case opt - when '--dry-run' - $dryrun = true - $trace = true - when '--help' - help - exit - when '--libdir' - $:.push(value) - when '--nosearch' - @nosearch = true - when '--quiet' - $verbose = false - when '--rakefile' - RAKEFILES.clear - RAKEFILES << value - when '--require' - require value - when '--tasks' - $show_tasks = true - when '--pull-gems' - $pull_gems = true - when '--trace' - $trace = true - when '--usage' - usage - exit - when '--verbose' - $verbose = true - when '--version' - puts "rake, version #{RAKEVERSION}" - exit - when '--directory' - Dir.chdir value - when '--jobs' - $rake_jobs = [value.to_i, 1].max - else - fail "Unknown option: #{opt}" - end - end - - # Read and handle the command line options. - def handle_options - $verbose = false - $pull_gems = false - opts = GetoptLong.new(*command_line_options) - opts.each { |opt, value| do_option(opt, value) } - end - - # Run the +rake+ application. - def run - handle_options - - unless $rake_root_fiber - require 'fiber' - $rake_root_fiber = Fiber.current - end - - begin - here = Dir.pwd - while ! have_rakefile - Dir.chdir("..") - if Dir.pwd == here || @nosearch - fail "No Rakefile found (looking for: #{RAKEFILES.join(', ')})" - end - here = Dir.pwd - end - root_tasks = [] - ARGV.each do |task_name| - if /^(\w+)=(.*)/.match(task_name) - ENV[$1] = $2 - else - root_tasks << task_name - end - end - puts "(in #{Dir.pwd})" - $rakefile = @rakefile - load @rakefile - if $show_tasks - display_tasks - else - root_tasks.push("default") if root_tasks.empty? - # revese tasks for popping - root_tasks.reverse! - - tasks = [] - until root_tasks.empty? - root_name = root_tasks.pop - tasks << root_name - until tasks.empty? - task_name = tasks.pop - t = MiniRake::Task[task_name] - f = t.invoke - - # append additional tasks to task queue - if f.kind_of?(Array) - tasks.push(*f) - tasks.uniq! - end - - unless f.kind_of? Fiber - tasks.insert 0, task_name unless t.done? - if root_name == task_name - wait_process - end - next - end - - wait_process while $rake_fiber_table.size >= $rake_jobs - - f.transfer - end - end - - wait_process until $rake_fiber_table.empty? - end - rescue Exception => e - begin - $rake_failed << e - wait_process until $rake_fiber_table.empty? - rescue Exception => next_e - e = next_e - retry - end - end - - return if $rake_failed.empty? - - puts "rake aborted!" - $rake_failed.each do |ex| - puts ex.message - if $trace || $verbose - puts ex.backtrace.join("\n") - else - puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || "" - end - end - exit 1 - end - - def wait_process(count = 0) - dur = [0.0001 * (10 ** count), 1].min - sleep dur - - exited = [] - $rake_fiber_table.each do |pid, v| - exited << pid unless v[:process_waiter].alive? - end - - exited.each do |pid| - ent = $rake_fiber_table.delete pid - st = ent[:process_waiter].value - - # ignore process that isn't created by `sh` method - return if ent.nil? - - if st.exitstatus != 0 - raise "Command Failed: [#{ent[:command]}]" - end - - fail 'task scheduling bug!' if $rake_fiber_table.size >= $rake_jobs - - ent[:fiber].transfer - end - - wait_process(count + 1) if !$rake_fiber_table.empty? && exited.empty? - end - -end - -if __FILE__ == $0 then - RakeApp.new.run -end +#! /usr/bin/env ruby +exec "rake", *ARGV diff --git a/mrbgems/mruby-bin-debugger/bintest/print.rb b/mrbgems/mruby-bin-debugger/bintest/print.rb index 314c7041a..a8401963f 100644 --- a/mrbgems/mruby-bin-debugger/bintest/print.rb +++ b/mrbgems/mruby-bin-debugger/bintest/print.rb @@ -1,9 +1,10 @@ require 'open3' require 'tempfile' +require 'strscan' class BinTest_MrubyBinDebugger - @debug1=false - @debug2=true +# @debug1=false +# @debug2=true def self.test(rubysource, testcase) script, bin = Tempfile.new(['test', '.rb']), Tempfile.new(['test', '.mrb']) @@ -19,10 +20,20 @@ class BinTest_MrubyBinDebugger stdin_data = testcase.map{|t| t[:cmd]}.join("\n") << "\n" + prompt = /^\(#{Regexp.escape(script.path)}:\d+\) / ["bin/mrdb #{script.path}","bin/mrdb -b #{bin.path}"].each do |cmd| o, s = Open3.capture2(cmd, :stdin_data => stdin_data) + scanner = StringScanner.new(o) + scanner.skip_until(prompt) + testcase.each do |tc| + exp = tc[:exp] + if exp + act = scanner.scan_until(/\n/) + break unless assert_operator act, :start_with?, exp + end + scanner.skip_until(prompt) + end - exp_vals = testcase.map{|t| t.fetch(:exp, nil)} =begin if @debug1 o.split("\n").each_with_index do |i,actual| @@ -41,14 +52,6 @@ end assert_true actual.include?(exp) unless exp.nil? end =end - idx = 0 - exp_vals.each do |exp| - next if exp.nil? - idx = o.index(exp, idx) - assert_false idx.nil? - break unless idx - idx += 1 - end end end end @@ -698,4 +701,3 @@ SRC BinTest_MrubyBinDebugger.test(src, tc) end - diff --git a/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c index 4c8c680cb..716b79c88 100644 --- a/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +++ b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c @@ -183,7 +183,7 @@ partial_hook(struct mrb_parser_state *p) return -1; } fn = args->argv[args->idx++]; - p->f = fopen(fn, "r"); + p->f = fopen(fn, "rb"); if (p->f == NULL) { fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, fn); return -1; @@ -210,7 +210,7 @@ load_file(mrb_state *mrb, struct mrbc_args *args) } else { need_close = TRUE; - if ((infile = fopen(input, "r")) == NULL) { + if ((infile = fopen(input, "rb")) == NULL) { fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, input); return mrb_nil_value(); } diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index cf5f5230f..de875a1ae 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -74,8 +74,6 @@ typedef unsigned int stack_type; #define NUM_SUFFIX_R (1<<0) #define NUM_SUFFIX_I (1<<1) -#define NUMPARAM_MAX 9 - static inline mrb_sym intern_cstr_gen(parser_state *p, const char *s) { @@ -840,7 +838,7 @@ new_block_arg(parser_state *p, node *a) } static node* -setup_args(parser_state *p, node *a) +setup_numparams(parser_state *p, node *a) { int nvars = intn(p->nvars->cdr); if (nvars > 0) { @@ -849,7 +847,8 @@ setup_args(parser_state *p, node *a) // m || opt || rest || tail if (a && (a->car || (a->cdr && a->cdr->car) || (a->cdr->cdr && a->cdr->cdr->car) || (a->cdr->cdr->cdr->cdr && a->cdr->cdr->cdr->cdr->car))) { yyerror(p, "ordinary parameter is defined"); - } else { + } + else { node* args = 0; for (i = nvars; i > 0; i--) { char buf[3]; @@ -871,7 +870,7 @@ setup_args(parser_state *p, node *a) static node* new_block(parser_state *p, node *a, node *b) { - a = setup_args(p, a); + a = setup_numparams(p, a); return list4((node*)NODE_BLOCK, locals_node(p), a, b); } @@ -879,7 +878,6 @@ new_block(parser_state *p, node *a, node *b) static node* new_lambda(parser_state *p, node *a, node *b) { - a = setup_args(p, a); return list4((node*)NODE_LAMBDA, locals_node(p), a, b); } @@ -2482,7 +2480,6 @@ primary : literal | tLAMBDA { local_nest(p); - nvars_nest(p); $<num>$ = p->lpar_beg; p->lpar_beg = ++p->paren_nest; } @@ -2496,7 +2493,6 @@ primary : literal p->lpar_beg = $<num>2; $$ = new_lambda(p, $3, $5); local_unnest(p); - nvars_unnest(p); p->cmdarg_stack = $<stack>4; CMDARG_LEXPOP(); } @@ -3988,6 +3984,13 @@ nextc(parser_state *p) if (c >= 0) { p->column++; } + if (c == '\r') { + const int lf = nextc(p); + if (lf == '\n') { + return '\n'; + } + pushback(p, lf); + } return c; eof: @@ -5952,32 +5955,27 @@ parser_yylex(parser_state *p) break; case '_': - if (toklen(p) == 2 && ISDIGIT(tok(p)[1])) { + if (toklen(p) == 2 && ISDIGIT(tok(p)[1]) && p->nvars) { int n = tok(p)[1] - '0'; - node *nvars = p->nvars->car; - while (nvars) { - if (intn(nvars->cdr) > 0) { + if (n > 0) { + node *nvars = p->nvars->car; + + while (nvars) { + if (intn(nvars->cdr) > 0) { + yywarning(p, "numbered parameter in nested block"); + break; + } + nvars->cdr = nint(-1); + nvars = nvars->car; + } + if (intn(p->nvars->cdr) < 0) { yywarning(p, "numbered parameter in nested block"); - break; } - nvars->cdr = nint(-1); - nvars = nvars->car; - } - if (intn(p->nvars->cdr) < 0) { - yywarning(p, "numbered parameter in nested block"); - } - if (n == 0) { - yyerror(p, "_0 is not available"); - return 0; - } - if (n > NUMPARAM_MAX) { - yyerror(p, "too large numbered parameter"); - return 0; + pylval.num = n; + p->lstate = EXPR_END; + return tNUMPARAM; } - pylval.num = n; - p->lstate = EXPR_END; - return tNUMPARAM; } /* fall through */ default: diff --git a/mrbgems/mruby-io/mrblib/file.rb b/mrbgems/mruby-io/mrblib/file.rb index 710333d6f..d3a4b1ec7 100644 --- a/mrbgems/mruby-io/mrblib/file.rb +++ b/mrbgems/mruby-io/mrblib/file.rb @@ -55,46 +55,46 @@ class File < IO s end - def self.expand_path(path, default_dir = '.') - def concat_path(path, base_path) - if path[0] == "/" || path[1] == ':' # Windows root! - expanded_path = path - elsif path[0] == "~" - if (path[1] == "/" || path[1] == nil) - dir = path[1, path.size] - home_dir = _gethome - - unless home_dir - raise ArgumentError, "couldn't find HOME environment -- expanding '~'" - end - - expanded_path = home_dir - expanded_path += dir if dir - expanded_path += "/" - else - splitted_path = path.split("/") - user = splitted_path[0][1, splitted_path[0].size] - dir = "/" + splitted_path[1, splitted_path.size].join("/") + def self._concat_path(path, base_path) + if path[0] == "/" || path[1] == ':' # Windows root! + expanded_path = path + elsif path[0] == "~" + if (path[1] == "/" || path[1] == nil) + dir = path[1, path.size] + home_dir = _gethome + + unless home_dir + raise ArgumentError, "couldn't find HOME environment -- expanding '~'" + end - home_dir = _gethome(user) + expanded_path = home_dir + expanded_path += dir if dir + expanded_path += "/" + else + splitted_path = path.split("/") + user = splitted_path[0][1, splitted_path[0].size] + dir = "/" + splitted_path[1, splitted_path.size].join("/") - unless home_dir - raise ArgumentError, "user #{user} doesn't exist" - end + home_dir = _gethome(user) - expanded_path = home_dir - expanded_path += dir if dir - expanded_path += "/" + unless home_dir + raise ArgumentError, "user #{user} doesn't exist" end - else - expanded_path = concat_path(base_path, _getwd) - expanded_path += "/" + path - end - expanded_path + expanded_path = home_dir + expanded_path += dir if dir + expanded_path += "/" + end + else + expanded_path = _concat_path(base_path, _getwd) + expanded_path += "/" + path end - expanded_path = concat_path(path, default_dir) + expanded_path + end + + def self.expand_path(path, default_dir = '.') + expanded_path = _concat_path(path, default_dir) drive_prefix = "" if File::ALT_SEPARATOR && expanded_path.size > 2 && ("A".."Z").include?(expanded_path[0].upcase) && expanded_path[1] == ":" diff --git a/mrbgems/mruby-io/src/file.c b/mrbgems/mruby-io/src/file.c index f9ccb6148..673decc20 100644 --- a/mrbgems/mruby-io/src/file.c +++ b/mrbgems/mruby-io/src/file.c @@ -7,12 +7,7 @@ #include "mruby/data.h" #include "mruby/string.h" #include "mruby/ext/io.h" - -#if MRUBY_RELEASE_NO < 10000 -#include "error.h" -#else #include "mruby/error.h" -#endif #include <sys/types.h> #include <sys/stat.h> diff --git a/mrbgems/mruby-io/src/file_test.c b/mrbgems/mruby-io/src/file_test.c index 445bafde9..aadd1ac1c 100644 --- a/mrbgems/mruby-io/src/file_test.c +++ b/mrbgems/mruby-io/src/file_test.c @@ -7,12 +7,7 @@ #include "mruby/data.h" #include "mruby/string.h" #include "mruby/ext/io.h" - -#if MRUBY_RELEASE_NO < 10000 -#include "error.h" -#else #include "mruby/error.h" -#endif #include <sys/types.h> #include <sys/stat.h> diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c index 5bc88e047..32128fa07 100644 --- a/mrbgems/mruby-io/src/io.c +++ b/mrbgems/mruby-io/src/io.c @@ -10,12 +10,7 @@ #include "mruby/string.h" #include "mruby/variable.h" #include "mruby/ext/io.h" - -#if MRUBY_RELEASE_NO < 10000 -#include "error.h" -#else #include "mruby/error.h" -#endif #include <sys/types.h> #include <sys/stat.h> @@ -66,14 +61,6 @@ static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr); static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags); static void fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet); -#if MRUBY_RELEASE_NO < 10000 -static struct RClass * -mrb_module_get(mrb_state *mrb, const char *name) -{ - return mrb_class_get(mrb, name); -} -#endif - static struct mrb_io * io_get_open_fptr(mrb_state *mrb, mrb_value self) { diff --git a/mrbgems/mruby-metaprog/src/metaprog.c b/mrbgems/mruby-metaprog/src/metaprog.c index bca8ab34c..f00c4493b 100644 --- a/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mrbgems/mruby-metaprog/src/metaprog.c @@ -172,7 +172,7 @@ mrb_local_variables(mrb_state *mrb, mrb_value self) KHASH_DECLARE(st, mrb_sym, char, FALSE) static void -method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set) +method_entry_loop(mrb_state *mrb, struct RClass *klass, khash_t(st) *set, khash_t(st) *undef) { khint_t i; @@ -181,20 +181,28 @@ method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set) for (i=0;i<kh_end(h);i++) { if (kh_exist(h, i)) { mrb_method_t m = kh_value(h, i); - if (MRB_METHOD_UNDEF_P(m)) continue; - kh_put(st, mrb, set, kh_key(h, i)); + if (MRB_METHOD_UNDEF_P(m)) { + if (undef) { + kh_put(st, mrb, undef, kh_key(h, i)); + } + } + else if (undef == NULL || + kh_get(st, mrb, undef, kh_key(h, i)) == kh_end(undef)) { + kh_put(st, mrb, set, kh_key(h, i)); + } } } } static mrb_value -mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* klass, int obj) +mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass *klass, int obj) { khint_t i; mrb_value ary; mrb_bool prepended = FALSE; - struct RClass* oldklass; - khash_t(st)* set = kh_init(st, mrb); + struct RClass *oldklass; + khash_t(st) *set = kh_init(st, mrb); + khash_t(st) *undef = (recur ? kh_init(st, mrb) : NULL); if (!recur && (klass->flags & MRB_FL_CLASS_IS_PREPENDED)) { MRB_CLASS_ORIGIN(klass); @@ -203,7 +211,7 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl oldklass = 0; while (klass && (klass != oldklass)) { - method_entry_loop(mrb, klass, set); + method_entry_loop(mrb, klass, set, undef); if ((klass->tt == MRB_TT_ICLASS && !prepended) || (klass->tt == MRB_TT_SCLASS)) { } @@ -221,6 +229,7 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl } } kh_destroy(st, mrb, set); + if (undef) kh_destroy(st, mrb, undef); return ary; } @@ -313,18 +322,19 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj) { khint_t i; mrb_value ary; - struct RClass* klass; - khash_t(st)* set = kh_init(st, mrb); + struct RClass *klass; + khash_t(st) *set = kh_init(st, mrb); + khash_t(st) *undef = (recur ? kh_init(st, mrb) : NULL); klass = mrb_class(mrb, obj); if (klass && (klass->tt == MRB_TT_SCLASS)) { - method_entry_loop(mrb, klass, set); + method_entry_loop(mrb, klass, set, undef); klass = klass->super; } if (recur) { while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) { - method_entry_loop(mrb, klass, set); + method_entry_loop(mrb, klass, set, undef); klass = klass->super; } } @@ -336,6 +346,7 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj) } } kh_destroy(st, mrb, set); + if (undef) kh_destroy(st, mrb, undef); return ary; } diff --git a/src/class.c b/src/class.c index 0da572b0e..700bf5485 100644 --- a/src/class.c +++ b/src/class.c @@ -285,11 +285,9 @@ mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super) static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value); #ifdef MRB_METHOD_CACHE static void mc_clear_all(mrb_state *mrb); -static void mc_clear_by_class(mrb_state *mrb, struct RClass*); static void mc_clear_by_id(mrb_state *mrb, struct RClass*, mrb_sym); #else #define mc_clear_all(mrb) -#define mc_clear_by_class(mrb,c) #define mc_clear_by_id(mrb,c,s) #endif @@ -303,7 +301,7 @@ mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass) super = mrb->object_class; super->flags |= MRB_FL_CLASS_IS_INHERITED; s = mrb_obj_value(super); - mc_clear_by_class(mrb, klass); + mrb_mc_clear_by_class(mrb, klass); mid = mrb_intern_lit(mrb, "inherited"); if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) { mrb_value c = mrb_obj_value(klass); @@ -1109,7 +1107,7 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, stru m->flags |= MRB_FL_CLASS_IS_INHERITED; ins_pos->super = ic; mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic); - mc_clear_by_class(mrb, ins_pos); + mrb_mc_clear_by_class(mrb, ins_pos); ins_pos = ic; skip: m = m->super; @@ -1322,8 +1320,8 @@ mc_clear_all(mrb_state *mrb) } } -static void -mc_clear_by_class(mrb_state *mrb, struct RClass *c) +void +mrb_mc_clear_by_class(mrb_state *mrb, struct RClass *c) { struct mrb_cache_entry *mc = mrb->cache; int i; diff --git a/src/error.c b/src/error.c index 126cd23fb..8ce92cef4 100644 --- a/src/error.c +++ b/src/error.c @@ -302,7 +302,11 @@ mrb_vformat(mrb_state *mrb, const char *format, va_list ap) mrb_gc_arena_restore(mrb, ai); break; case 'n': +#if UINT32_MAX < INT_MAX + obj = mrb_symbol_value((mrb_sym)va_arg(ap, int)); +#else obj = mrb_symbol_value(va_arg(ap, mrb_sym)); +#endif goto L_cat_obj; case 's': chars = va_arg(ap, char*); @@ -807,10 +807,12 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) case MRB_TT_SCLASS: mrb_gc_free_mt(mrb, (struct RClass*)obj); mrb_gc_free_iv(mrb, (struct RObject*)obj); + mrb_mc_clear_by_class(mrb, (struct RClass*)obj); break; case MRB_TT_ICLASS: if (MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN)) mrb_gc_free_mt(mrb, (struct RClass*)obj); + mrb_mc_clear_by_class(mrb, (struct RClass*)obj); break; case MRB_TT_ENV: { diff --git a/tasks/gitlab.rake b/tasks/gitlab.rake index 471172377..97adb5835 100644 --- a/tasks/gitlab.rake +++ b/tasks/gitlab.rake @@ -110,7 +110,7 @@ task :gitlab_config do 'stage' => 'test', 'image' => ci_docker_tag(compiler), 'variables' => hash, - 'script' => 'env; ./minirake --verbose all test' + 'script' => 'env; rake --verbose all test' } end end diff --git a/tasks/toolchains/android.rake b/tasks/toolchains/android.rake index c7df9ef80..0ac4d000c 100644 --- a/tasks/toolchains/android.rake +++ b/tasks/toolchains/android.rake @@ -67,7 +67,7 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter end def home_path - @home_path ||= Pathname( + @home_path ||= Pathname.new( params[:ndk_home] || ENV['ANDROID_NDK_HOME'] || DEFAULT_NDK_HOMES.find { |path| @@ -124,7 +124,7 @@ Set ANDROID_PLATFORM environment variable or set :platform parameter path = home_path.join('toolchains', 'llvm' , 'prebuilt', 'windows*') Dir.glob(path.to_s){ |item| next if File.file?(item) - path = Pathname(item) + path = Pathname.new(item) break } path.basename diff --git a/tasks/toolchains/gcc.rake b/tasks/toolchains/gcc.rake index 1a28026bf..e9ea2550c 100644 --- a/tasks/toolchains/gcc.rake +++ b/tasks/toolchains/gcc.rake @@ -15,7 +15,7 @@ MRuby::Toolchain.new(:gcc) do |conf, params| compiler.option_include_path = '-I%s' compiler.option_define = '-D%s' compiler.compile_options = '%{flags} -MMD -o %{outfile} -c %{infile}' - compiler.cxx_compile_flag = '-x c++ -std=c++03' + compiler.cxx_compile_flag = '-x c++ -std=gnu++03' compiler.cxx_exception_flag = '-fexceptions' compiler.cxx_invalid_flags = c_mandatory_flags + cxx_invalid_flags end diff --git a/test/t/syntax.rb b/test/t/syntax.rb index af63fcef9..436c06601 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -672,11 +672,12 @@ assert 'keyword arguments' do assert_equal([:a, nil, :c], m(a: :a, c: :c)) end - assert('numbered parameters') do assert_equal(15, [1,2,3,4,5].reduce {_1+_2}) - assert_equal(3, ->{_1+_2}.call(1,2)) - assert_equal(4, ->(a=->{_1}){a}.call.call(4)) - assert_equal(5, -> a: ->{_1} {a}.call.call(5)) assert_equal(45, Proc.new do _1 + _2 + _3 + _4 + _5 + _6 + _7 + _8 + _9 end.call(*[1, 2, 3, 4, 5, 6, 7, 8, 9])) end + +assert('_0 is not numbered parameter') do + _0 = :l + assert_equal(:l, ->{_0}.call) +end |
