From b6aa4f8ce4f3a7d1fe33e2ca4df535f92d09480d Mon Sep 17 00:00:00 2001 From: Christine Oen Date: Thu, 31 Jul 2014 18:58:24 -0500 Subject: [PATCH 1/2] 4.25 seconds, 100% accuracy --- .DS_Store | Bin 0 -> 6148 bytes Gemfile | 4 + data/stopwords.txt | 2 +- gutenberg.rb | 1 + lib/complex_predictor.rb | 82 +- vendor/bundle/bin/byebug | 23 + vendor/bundle/bin/coderay | 23 + vendor/bundle/bin/pry | 23 + vendor/bundle/build_info/byebug-2.7.0.info | 1 + vendor/bundle/build_info/coderay-1.1.0.info | 1 + vendor/bundle/build_info/columnize-0.8.9.info | 1 + .../build_info/debugger-linecache-1.2.0.info | 1 + .../build_info/method_source-0.8.2.info | 1 + vendor/bundle/build_info/pry-0.10.0.info | 1 + .../bundle/build_info/pry-byebug-1.3.3.info | 1 + vendor/bundle/build_info/slop-3.6.0.info | 1 + vendor/bundle/gems/byebug-2.7.0/.gitignore | 18 + vendor/bundle/gems/byebug-2.7.0/.travis.yml | 8 + vendor/bundle/gems/byebug-2.7.0/CHANGELOG.md | 214 +++ .../bundle/gems/byebug-2.7.0/CONTRIBUTING.md | 21 + vendor/bundle/gems/byebug-2.7.0/GUIDE.md | 1368 +++++++++++++++++ vendor/bundle/gems/byebug-2.7.0/Gemfile | 3 + vendor/bundle/gems/byebug-2.7.0/LICENSE | 23 + vendor/bundle/gems/byebug-2.7.0/README.md | 167 ++ vendor/bundle/gems/byebug-2.7.0/Rakefile | 39 + vendor/bundle/gems/byebug-2.7.0/bin/byebug | 251 +++ .../bundle/gems/byebug-2.7.0/byebug.gemspec | 34 + .../byebug-2.7.0/ext/byebug/.RUBYARCHDIR.time | 0 .../gems/byebug-2.7.0/ext/byebug/Makefile | 237 +++ .../gems/byebug-2.7.0/ext/byebug/breakpoint.c | 504 ++++++ .../gems/byebug-2.7.0/ext/byebug/breakpoint.o | Bin 0 -> 113764 bytes .../gems/byebug-2.7.0/ext/byebug/byebug.c | 781 ++++++++++ .../gems/byebug-2.7.0/ext/byebug/byebug.h | 128 ++ .../gems/byebug-2.7.0/ext/byebug/byebug.o | Bin 0 -> 148460 bytes .../gems/byebug-2.7.0/ext/byebug/byebug.so | Bin 0 -> 531109 bytes .../gems/byebug-2.7.0/ext/byebug/context.c | 660 ++++++++ .../gems/byebug-2.7.0/ext/byebug/context.o | Bin 0 -> 128892 bytes .../gems/byebug-2.7.0/ext/byebug/extconf.rb | 17 + .../gems/byebug-2.7.0/ext/byebug/locker.c | 54 + .../gems/byebug-2.7.0/ext/byebug/locker.o | Bin 0 -> 91328 bytes .../gems/byebug-2.7.0/ext/byebug/threads.c | 113 ++ .../gems/byebug-2.7.0/ext/byebug/threads.o | Bin 0 -> 97632 bytes vendor/bundle/gems/byebug-2.7.0/lib/byebug.rb | 201 +++ .../gems/byebug-2.7.0/lib/byebug/command.rb | 229 +++ .../lib/byebug/command_processor.rb | 255 +++ .../lib/byebug/commands/breakpoints.rb | 137 ++ .../lib/byebug/commands/catchpoint.rb | 46 + .../lib/byebug/commands/condition.rb | 41 + .../lib/byebug/commands/continue.rb | 37 + .../lib/byebug/commands/control.rb | 90 ++ .../lib/byebug/commands/display.rb | 116 ++ .../byebug-2.7.0/lib/byebug/commands/edit.rb | 50 + .../lib/byebug/commands/enable.rb | 155 ++ .../byebug-2.7.0/lib/byebug/commands/eval.rb | 175 +++ .../lib/byebug/commands/finish.rb | 42 + .../byebug-2.7.0/lib/byebug/commands/frame.rb | 256 +++ .../byebug-2.7.0/lib/byebug/commands/help.rb | 50 + .../byebug-2.7.0/lib/byebug/commands/info.rb | 301 ++++ .../byebug-2.7.0/lib/byebug/commands/kill.rb | 44 + .../byebug-2.7.0/lib/byebug/commands/list.rb | 121 ++ .../lib/byebug/commands/method.rb | 77 + .../byebug-2.7.0/lib/byebug/commands/quit.rb | 32 + .../lib/byebug/commands/reload.rb | 50 + .../byebug-2.7.0/lib/byebug/commands/repl.rb | 138 ++ .../byebug-2.7.0/lib/byebug/commands/save.rb | 87 ++ .../byebug-2.7.0/lib/byebug/commands/set.rb | 159 ++ .../byebug-2.7.0/lib/byebug/commands/show.rb | 224 +++ .../byebug-2.7.0/lib/byebug/commands/skip.rb | 30 + .../lib/byebug/commands/source.rb | 36 + .../lib/byebug/commands/stepping.rb | 78 + .../lib/byebug/commands/threads.rb | 204 +++ .../byebug-2.7.0/lib/byebug/commands/trace.rb | 49 + .../lib/byebug/commands/variables.rb | 189 +++ .../gems/byebug-2.7.0/lib/byebug/context.rb | 89 ++ .../lib/byebug/control_command_processor.rb | 79 + .../gems/byebug-2.7.0/lib/byebug/helper.rb | 69 + .../gems/byebug-2.7.0/lib/byebug/interface.rb | 34 + .../lib/byebug/interfaces/local_interface.rb | 88 ++ .../lib/byebug/interfaces/remote_interface.rb | 55 + .../lib/byebug/interfaces/script_interface.rb | 45 + .../gems/byebug-2.7.0/lib/byebug/processor.rb | 18 + .../gems/byebug-2.7.0/lib/byebug/remote.rb | 99 ++ .../gems/byebug-2.7.0/lib/byebug/version.rb | 3 + .../byebug-2.7.0/test/breakpoints_test.rb | 453 ++++++ .../gems/byebug-2.7.0/test/conditions_test.rb | 69 + .../gems/byebug-2.7.0/test/continue_test.rb | 39 + .../byebug-2.7.0/test/debugger_alias_test.rb | 5 + .../gems/byebug-2.7.0/test/display_test.rb | 124 ++ .../gems/byebug-2.7.0/test/edit_test.rb | 47 + .../gems/byebug-2.7.0/test/eval_test.rb | 103 ++ .../byebug-2.7.0/test/examples/breakpoint.rb | 6 + .../test/examples/breakpoint_deep.rb | 4 + .../byebug-2.7.0/test/examples/conditions.rb | 4 + .../byebug-2.7.0/test/examples/continue.rb | 5 + .../byebug-2.7.0/test/examples/display.rb | 5 + .../gems/byebug-2.7.0/test/examples/edit.rb | 4 + .../gems/byebug-2.7.0/test/examples/eval.rb | 4 + .../gems/byebug-2.7.0/test/examples/finish.rb | 3 + .../gems/byebug-2.7.0/test/examples/frame.rb | 4 + .../byebug-2.7.0/test/examples/frame_deep.rb | 1 + .../gems/byebug-2.7.0/test/examples/gcd.rb | 15 + .../gems/byebug-2.7.0/test/examples/hanoi.rb | 34 + .../gems/byebug-2.7.0/test/examples/help.rb | 1 + .../gems/byebug-2.7.0/test/examples/info.rb | 6 + .../gems/byebug-2.7.0/test/examples/info2.rb | 3 + .../byebug-2.7.0/test/examples/interrupt.rb | 8 + .../gems/byebug-2.7.0/test/examples/kill.rb | 2 + .../gems/byebug-2.7.0/test/examples/list.rb | 23 + .../gems/byebug-2.7.0/test/examples/method.rb | 4 + .../byebug-2.7.0/test/examples/post_mortem.rb | 4 + .../gems/byebug-2.7.0/test/examples/primes.rb | 25 + .../gems/byebug-2.7.0/test/examples/quit.rb | 2 + .../gems/byebug-2.7.0/test/examples/reload.rb | 6 + .../gems/byebug-2.7.0/test/examples/repl.rb | 6 + .../byebug-2.7.0/test/examples/restart.rb | 6 + .../gems/byebug-2.7.0/test/examples/save.rb | 3 + .../gems/byebug-2.7.0/test/examples/set.rb | 3 + .../byebug-2.7.0/test/examples/settings.rb | 1 + .../gems/byebug-2.7.0/test/examples/show.rb | 1 + .../gems/byebug-2.7.0/test/examples/source.rb | 3 + .../byebug-2.7.0/test/examples/stepping.rb | 8 + .../examples/stepping_raise_from_c_method.rb | 3 + .../stepping_raise_from_ruby_method.rb | 3 + .../test/examples/test-triangle.rb | 14 + .../gems/byebug-2.7.0/test/examples/thread.rb | 5 + .../gems/byebug-2.7.0/test/examples/tmate.rb | 10 + .../gems/byebug-2.7.0/test/examples/trace.rb | 8 + .../gems/byebug-2.7.0/test/examples/tri3.rb | 6 + .../byebug-2.7.0/test/examples/triangle.rb | 13 + .../byebug-2.7.0/test/examples/variables.rb | 4 + .../gems/byebug-2.7.0/test/finish_test.rb | 53 + .../gems/byebug-2.7.0/test/frame_test.rb | 228 +++ .../gems/byebug-2.7.0/test/help_test.rb | 50 + .../gems/byebug-2.7.0/test/info_test.rb | 308 ++++ .../gems/byebug-2.7.0/test/interrupt_test.rb | 58 + .../gems/byebug-2.7.0/test/kill_test.rb | 41 + .../gems/byebug-2.7.0/test/list_test.rb | 171 +++ .../gems/byebug-2.7.0/test/method_test.rb | 78 + .../byebug-2.7.0/test/post_mortem_test.rb | 253 +++ .../gems/byebug-2.7.0/test/quit_test.rb | 42 + .../gems/byebug-2.7.0/test/reload_test.rb | 32 + .../gems/byebug-2.7.0/test/repl_test.rb | 65 + .../gems/byebug-2.7.0/test/restart_test.rb | 142 ++ .../gems/byebug-2.7.0/test/save_test.rb | 74 + .../bundle/gems/byebug-2.7.0/test/set_test.rb | 188 +++ .../gems/byebug-2.7.0/test/show_test.rb | 265 ++++ .../gems/byebug-2.7.0/test/source_test.rb | 39 + .../gems/byebug-2.7.0/test/stepping_test.rb | 184 +++ .../byebug-2.7.0/test/support/breakpoint.rb | 13 + .../byebug-2.7.0/test/support/matchers.rb | 68 + .../byebug-2.7.0/test/support/test_dsl.rb | 189 +++ .../test/support/test_interface.rb | 59 + .../gems/byebug-2.7.0/test/test_helper.rb | 46 + .../gems/byebug-2.7.0/test/thread_test.rb | 138 ++ .../gems/byebug-2.7.0/test/trace_test.rb | 105 ++ .../gems/byebug-2.7.0/test/variables_test.rb | 127 ++ .../gems/coderay-1.1.0/README_INDEX.rdoc | 123 ++ vendor/bundle/gems/coderay-1.1.0/Rakefile | 37 + vendor/bundle/gems/coderay-1.1.0/bin/coderay | 215 +++ .../bundle/gems/coderay-1.1.0/lib/coderay.rb | 284 ++++ .../gems/coderay-1.1.0/lib/coderay/duo.rb | 81 + .../gems/coderay-1.1.0/lib/coderay/encoder.rb | 201 +++ .../lib/coderay/encoders/_map.rb | 17 + .../lib/coderay/encoders/comment_filter.rb | 25 + .../lib/coderay/encoders/count.rb | 39 + .../lib/coderay/encoders/debug.rb | 49 + .../lib/coderay/encoders/debug_lint.rb | 63 + .../coderay-1.1.0/lib/coderay/encoders/div.rb | 23 + .../lib/coderay/encoders/filter.rb | 58 + .../lib/coderay/encoders/html.rb | 332 ++++ .../lib/coderay/encoders/html/css.rb | 65 + .../lib/coderay/encoders/html/numbering.rb | 108 ++ .../lib/coderay/encoders/html/output.rb | 166 ++ .../lib/coderay/encoders/json.rb | 83 + .../lib/coderay/encoders/lines_of_code.rb | 45 + .../lib/coderay/encoders/lint.rb | 59 + .../lib/coderay/encoders/null.rb | 18 + .../lib/coderay/encoders/page.rb | 24 + .../lib/coderay/encoders/span.rb | 23 + .../lib/coderay/encoders/statistic.rb | 95 ++ .../lib/coderay/encoders/terminal.rb | 195 +++ .../lib/coderay/encoders/text.rb | 46 + .../lib/coderay/encoders/token_kind_filter.rb | 111 ++ .../coderay-1.1.0/lib/coderay/encoders/xml.rb | 72 + .../lib/coderay/encoders/yaml.rb | 50 + .../coderay-1.1.0/lib/coderay/for_redcloth.rb | 95 ++ .../lib/coderay/helpers/file_type.rb | 151 ++ .../lib/coderay/helpers/plugin.rb | 274 ++++ .../lib/coderay/helpers/word_list.rb | 72 + .../gems/coderay-1.1.0/lib/coderay/scanner.rb | 355 +++++ .../lib/coderay/scanners/_map.rb | 24 + .../coderay-1.1.0/lib/coderay/scanners/c.rb | 189 +++ .../lib/coderay/scanners/clojure.rb | 217 +++ .../coderay-1.1.0/lib/coderay/scanners/cpp.rb | 215 +++ .../coderay-1.1.0/lib/coderay/scanners/css.rb | 196 +++ .../lib/coderay/scanners/debug.rb | 75 + .../lib/coderay/scanners/delphi.rb | 144 ++ .../lib/coderay/scanners/diff.rb | 221 +++ .../coderay-1.1.0/lib/coderay/scanners/erb.rb | 81 + .../coderay-1.1.0/lib/coderay/scanners/go.rb | 208 +++ .../lib/coderay/scanners/groovy.rb | 268 ++++ .../lib/coderay/scanners/haml.rb | 168 ++ .../lib/coderay/scanners/html.rb | 275 ++++ .../lib/coderay/scanners/java.rb | 174 +++ .../coderay/scanners/java/builtin_types.rb | 421 +++++ .../lib/coderay/scanners/java_script.rb | 237 +++ .../lib/coderay/scanners/json.rb | 98 ++ .../coderay-1.1.0/lib/coderay/scanners/lua.rb | 280 ++++ .../coderay-1.1.0/lib/coderay/scanners/php.rb | 527 +++++++ .../lib/coderay/scanners/python.rb | 287 ++++ .../lib/coderay/scanners/raydebug.rb | 75 + .../lib/coderay/scanners/ruby.rb | 470 ++++++ .../lib/coderay/scanners/ruby/patterns.rb | 178 +++ .../lib/coderay/scanners/ruby/string_state.rb | 71 + .../lib/coderay/scanners/sass.rb | 232 +++ .../coderay-1.1.0/lib/coderay/scanners/sql.rb | 177 +++ .../lib/coderay/scanners/taskpaper.rb | 36 + .../lib/coderay/scanners/text.rb | 26 + .../coderay-1.1.0/lib/coderay/scanners/xml.rb | 17 + .../lib/coderay/scanners/yaml.rb | 140 ++ .../gems/coderay-1.1.0/lib/coderay/style.rb | 23 + .../coderay-1.1.0/lib/coderay/styles/_map.rb | 7 + .../coderay-1.1.0/lib/coderay/styles/alpha.rb | 152 ++ .../coderay-1.1.0/lib/coderay/token_kinds.rb | 85 + .../gems/coderay-1.1.0/lib/coderay/tokens.rb | 161 ++ .../coderay-1.1.0/lib/coderay/tokens_proxy.rb | 55 + .../gems/coderay-1.1.0/lib/coderay/version.rb | 3 + .../coderay-1.1.0/test/functional/basic.rb | 318 ++++ .../coderay-1.1.0/test/functional/examples.rb | 129 ++ .../test/functional/for_redcloth.rb | 78 + .../coderay-1.1.0/test/functional/suite.rb | 15 + vendor/bundle/gems/columnize-0.8.9/.gitignore | 3 + .../bundle/gems/columnize-0.8.9/.travis.yml | 9 + vendor/bundle/gems/columnize-0.8.9/AUTHORS | 2 + vendor/bundle/gems/columnize-0.8.9/COPYING | 57 + vendor/bundle/gems/columnize-0.8.9/ChangeLog | 282 ++++ vendor/bundle/gems/columnize-0.8.9/Gemfile | 3 + vendor/bundle/gems/columnize-0.8.9/Makefile | 15 + vendor/bundle/gems/columnize-0.8.9/NEWS | 58 + vendor/bundle/gems/columnize-0.8.9/README.md | 108 ++ vendor/bundle/gems/columnize-0.8.9/Rakefile | 105 ++ vendor/bundle/gems/columnize-0.8.9/THANKS | 8 + .../gems/columnize-0.8.9/columnize.gemspec | 38 + .../bundle/gems/columnize-0.8.9/lib/Makefile | 10 + .../gems/columnize-0.8.9/lib/columnize.rb | 137 ++ .../columnize-0.8.9/lib/columnize/Makefile | 11 + .../lib/columnize/columnize.rb | 159 ++ .../columnize-0.8.9/lib/columnize/opts.rb | 35 + .../columnize-0.8.9/lib/columnize/version.rb | 7 + .../test/test-columnize-array.rb | 48 + .../columnize-0.8.9/test/test-columnize.rb | 74 + .../columnize-0.8.9/test/test-columnizer.rb | 112 ++ .../columnize-0.8.9/test/test-hashparm.rb | 43 + .../gems/columnize-0.8.9/test/test-issue3.rb | 24 + .../test/test-min_rows_and_colwidths.rb | 65 + .../gems/debugger-linecache-1.2.0/.travis.yml | 5 + .../debugger-linecache-1.2.0/CHANGELOG.md | 54 + .../debugger-linecache-1.2.0/CONTRIBUTING.md | 1 + .../gems/debugger-linecache-1.2.0/LICENSE.txt | 22 + .../debugger-linecache-1.2.0/OLD_CHANGELOG | 68 + .../gems/debugger-linecache-1.2.0/OLD_README | 50 + .../gems/debugger-linecache-1.2.0/README.md | 20 + .../gems/debugger-linecache-1.2.0/Rakefile | 28 + .../debugger-linecache.gemspec | 20 + .../lib/debugger/linecache.rb | 5 + .../lib/linecache19.rb | 407 +++++ .../lib/tracelines19.rb | 54 + .../test/data/begin1.rb | 3 + .../test/data/begin2.rb | 3 + .../test/data/begin3.rb | 6 + .../test/data/block1.rb | 7 + .../test/data/block2.rb | 4 + .../test/data/case1.rb | 6 + .../test/data/case2.rb | 5 + .../test/data/case3.rb | 5 + .../test/data/case4.rb | 4 + .../test/data/case5.rb | 10 + .../test/data/class1.rb | 5 + .../test/data/comments1.rb | 6 + .../test/data/def1.rb | 9 + .../test/data/each1.rb | 3 + .../debugger-linecache-1.2.0/test/data/end.rb | 3 + .../test/data/for1.rb | 4 + .../debugger-linecache-1.2.0/test/data/if1.rb | 4 + .../debugger-linecache-1.2.0/test/data/if2.rb | 4 + .../debugger-linecache-1.2.0/test/data/if3.rb | 9 + .../debugger-linecache-1.2.0/test/data/if4.rb | 14 + .../debugger-linecache-1.2.0/test/data/if5.rb | 7 + .../debugger-linecache-1.2.0/test/data/if6.rb | 4 + .../debugger-linecache-1.2.0/test/data/if7.rb | 8 + .../test/data/match.rb | 3 + .../test/data/match3.rb | 5 + .../test/data/match3a.rb | 6 + .../test/data/not-lit.rb | 6 + .../test/lnum-diag.rb | 127 ++ .../test/parse-show.rb | 13 + .../debugger-linecache-1.2.0/test/rcov-bug.rb | 10 + .../debugger-linecache-1.2.0/test/short-file | 2 + .../test/test-linecache.rb | 148 ++ .../test/test-lnum.rb | 33 + .../test/test-tracelines.rb | 38 + .../bundle/gems/method_source-0.8.2/.gemtest | 0 .../gems/method_source-0.8.2/.travis.yml | 13 + .../bundle/gems/method_source-0.8.2/.yardopts | 1 + .../bundle/gems/method_source-0.8.2/Gemfile | 2 + .../bundle/gems/method_source-0.8.2/LICENSE | 25 + .../gems/method_source-0.8.2/README.markdown | 91 ++ .../bundle/gems/method_source-0.8.2/Rakefile | 79 + .../method_source-0.8.2/lib/method_source.rb | 141 ++ .../lib/method_source/code_helpers.rb | 154 ++ .../lib/method_source/source_location.rb | 138 ++ .../lib/method_source/version.rb | 3 + .../method_source-0.8.2/method_source.gemspec | 33 + .../gems/method_source-0.8.2/test/test.rb | 138 ++ .../test/test_code_helpers.rb | 41 + .../method_source-0.8.2/test/test_helper.rb | 98 ++ vendor/bundle/gems/pry-0.10.0/CHANGELOG.md | 702 +++++++++ vendor/bundle/gems/pry-0.10.0/LICENSE | 25 + vendor/bundle/gems/pry-0.10.0/README.md | 406 +++++ vendor/bundle/gems/pry-0.10.0/bin/pry | 16 + vendor/bundle/gems/pry-0.10.0/lib/pry.rb | 161 ++ vendor/bundle/gems/pry-0.10.0/lib/pry/cli.rb | 220 +++ vendor/bundle/gems/pry-0.10.0/lib/pry/code.rb | 341 ++++ .../gems/pry-0.10.0/lib/pry/code/code_file.rb | 103 ++ .../pry-0.10.0/lib/pry/code/code_range.rb | 71 + .../gems/pry-0.10.0/lib/pry/code/loc.rb | 92 ++ .../gems/pry-0.10.0/lib/pry/code_object.rb | 172 +++ .../gems/pry-0.10.0/lib/pry/color_printer.rb | 55 + .../bundle/gems/pry-0.10.0/lib/pry/command.rb | 692 +++++++++ .../gems/pry-0.10.0/lib/pry/command_set.rb | 443 ++++++ .../gems/pry-0.10.0/lib/pry/commands.rb | 6 + .../pry-0.10.0/lib/pry/commands/amend_line.rb | 99 ++ .../gems/pry-0.10.0/lib/pry/commands/bang.rb | 20 + .../pry-0.10.0/lib/pry/commands/bang_pry.rb | 17 + .../gems/pry-0.10.0/lib/pry/commands/cat.rb | 62 + .../pry/commands/cat/abstract_formatter.rb | 27 + .../pry/commands/cat/exception_formatter.rb | 77 + .../lib/pry/commands/cat/file_formatter.rb | 67 + .../cat/input_expression_formatter.rb | 43 + .../gems/pry-0.10.0/lib/pry/commands/cd.rb | 41 + .../lib/pry/commands/change_inspector.rb | 27 + .../lib/pry/commands/change_prompt.rb | 26 + .../lib/pry/commands/code_collector.rb | 165 ++ .../lib/pry/commands/disable_pry.rb | 27 + .../lib/pry/commands/disabled_commands.rb | 2 + .../lib/pry/commands/easter_eggs.rb | 112 ++ .../gems/pry-0.10.0/lib/pry/commands/edit.rb | 195 +++ .../pry/commands/edit/exception_patcher.rb | 25 + .../commands/edit/file_and_line_locator.rb | 36 + .../gems/pry-0.10.0/lib/pry/commands/exit.rb | 42 + .../pry-0.10.0/lib/pry/commands/exit_all.rb | 29 + .../lib/pry/commands/exit_program.rb | 23 + .../lib/pry/commands/find_method.rb | 193 +++ .../pry-0.10.0/lib/pry/commands/fix_indent.rb | 19 + .../pry-0.10.0/lib/pry/commands/gem_cd.rb | 26 + .../lib/pry/commands/gem_install.rb | 32 + .../pry-0.10.0/lib/pry/commands/gem_list.rb | 33 + .../pry-0.10.0/lib/pry/commands/gem_open.rb | 29 + .../gems/pry-0.10.0/lib/pry/commands/gist.rb | 101 ++ .../gems/pry-0.10.0/lib/pry/commands/help.rb | 164 ++ .../gems/pry-0.10.0/lib/pry/commands/hist.rb | 180 +++ .../pry-0.10.0/lib/pry/commands/import_set.rb | 22 + .../lib/pry/commands/install_command.rb | 53 + .../pry-0.10.0/lib/pry/commands/jump_to.rb | 29 + .../lib/pry/commands/list_inspectors.rb | 35 + .../lib/pry/commands/list_prompts.rb | 35 + .../gems/pry-0.10.0/lib/pry/commands/ls.rb | 114 ++ .../lib/pry/commands/ls/constants.rb | 47 + .../lib/pry/commands/ls/formatter.rb | 49 + .../pry-0.10.0/lib/pry/commands/ls/globals.rb | 48 + .../pry-0.10.0/lib/pry/commands/ls/grep.rb | 21 + .../lib/pry/commands/ls/instance_vars.rb | 39 + .../lib/pry/commands/ls/interrogatable.rb | 18 + .../lib/pry/commands/ls/jruby_hacks.rb | 49 + .../lib/pry/commands/ls/local_names.rb | 35 + .../lib/pry/commands/ls/local_vars.rb | 39 + .../lib/pry/commands/ls/ls_entity.rb | 70 + .../pry-0.10.0/lib/pry/commands/ls/methods.rb | 57 + .../lib/pry/commands/ls/methods_helper.rb | 46 + .../lib/pry/commands/ls/self_methods.rb | 32 + .../pry-0.10.0/lib/pry/commands/nesting.rb | 25 + .../gems/pry-0.10.0/lib/pry/commands/play.rb | 103 ++ .../lib/pry/commands/pry_backtrace.rb | 25 + .../lib/pry/commands/pry_version.rb | 17 + .../pry-0.10.0/lib/pry/commands/raise_up.rb | 32 + .../lib/pry/commands/reload_code.rb | 62 + .../gems/pry-0.10.0/lib/pry/commands/reset.rb | 18 + .../gems/pry-0.10.0/lib/pry/commands/ri.rb | 60 + .../pry-0.10.0/lib/pry/commands/save_file.rb | 61 + .../lib/pry/commands/shell_command.rb | 48 + .../pry-0.10.0/lib/pry/commands/shell_mode.rb | 25 + .../pry-0.10.0/lib/pry/commands/show_doc.rb | 83 + .../pry-0.10.0/lib/pry/commands/show_info.rb | 195 +++ .../pry-0.10.0/lib/pry/commands/show_input.rb | 17 + .../lib/pry/commands/show_source.rb | 50 + .../lib/pry/commands/simple_prompt.rb | 22 + .../gems/pry-0.10.0/lib/pry/commands/stat.rb | 40 + .../pry-0.10.0/lib/pry/commands/switch_to.rb | 23 + .../lib/pry/commands/toggle_color.rb | 24 + .../lib/pry/commands/watch_expression.rb | 105 ++ .../commands/watch_expression/expression.rb | 38 + .../pry-0.10.0/lib/pry/commands/whereami.rb | 190 +++ .../gems/pry-0.10.0/lib/pry/commands/wtf.rb | 57 + .../bundle/gems/pry-0.10.0/lib/pry/config.rb | 24 + .../pry-0.10.0/lib/pry/config/behavior.rb | 139 ++ .../pry-0.10.0/lib/pry/config/convenience.rb | 26 + .../gems/pry-0.10.0/lib/pry/config/default.rb | 165 ++ .../pry-0.10.0/lib/pry/core_extensions.rb | 131 ++ .../bundle/gems/pry-0.10.0/lib/pry/editor.rb | 133 ++ .../gems/pry-0.10.0/lib/pry/exceptions.rb | 77 + .../bundle/gems/pry-0.10.0/lib/pry/helpers.rb | 5 + .../lib/pry/helpers/base_helpers.rb | 113 ++ .../lib/pry/helpers/command_helpers.rb | 156 ++ .../lib/pry/helpers/documentation_helpers.rb | 75 + .../lib/pry/helpers/options_helpers.rb | 27 + .../gems/pry-0.10.0/lib/pry/helpers/table.rb | 109 ++ .../gems/pry-0.10.0/lib/pry/helpers/text.rb | 107 ++ .../bundle/gems/pry-0.10.0/lib/pry/history.rb | 125 ++ .../gems/pry-0.10.0/lib/pry/history_array.rb | 121 ++ .../bundle/gems/pry-0.10.0/lib/pry/hooks.rb | 230 +++ .../bundle/gems/pry-0.10.0/lib/pry/indent.rb | 406 +++++ .../pry-0.10.0/lib/pry/input_completer.rb | 242 +++ .../gems/pry-0.10.0/lib/pry/input_lock.rb | 132 ++ .../gems/pry-0.10.0/lib/pry/inspector.rb | 27 + .../gems/pry-0.10.0/lib/pry/last_exception.rb | 61 + .../bundle/gems/pry-0.10.0/lib/pry/method.rb | 546 +++++++ .../pry-0.10.0/lib/pry/method/disowned.rb | 53 + .../gems/pry-0.10.0/lib/pry/method/patcher.rb | 125 ++ .../lib/pry/method/weird_method_locator.rb | 186 +++ .../pry-0.10.0/lib/pry/module_candidate.rb | 136 ++ .../gems/pry-0.10.0/lib/pry/object_path.rb | 82 + .../bundle/gems/pry-0.10.0/lib/pry/output.rb | 50 + .../bundle/gems/pry-0.10.0/lib/pry/pager.rb | 235 +++ .../bundle/gems/pry-0.10.0/lib/pry/plugins.rb | 103 ++ .../bundle/gems/pry-0.10.0/lib/pry/prompt.rb | 26 + .../gems/pry-0.10.0/lib/pry/pry_class.rb | 375 +++++ .../gems/pry-0.10.0/lib/pry/pry_instance.rb | 654 ++++++++ .../gems/pry-0.10.0/lib/pry/rbx_path.rb | 22 + vendor/bundle/gems/pry-0.10.0/lib/pry/repl.rb | 202 +++ .../pry-0.10.0/lib/pry/repl_file_loader.rb | 74 + .../bundle/gems/pry-0.10.0/lib/pry/rubygem.rb | 82 + .../gems/pry-0.10.0/lib/pry/terminal.rb | 79 + .../gems/pry-0.10.0/lib/pry/test/helper.rb | 170 ++ .../bundle/gems/pry-0.10.0/lib/pry/version.rb | 3 + .../gems/pry-0.10.0/lib/pry/wrapped_module.rb | 373 +++++ .../bundle/gems/pry-byebug-1.3.3/.gitignore | 18 + .../bundle/gems/pry-byebug-1.3.3/.travis.yml | 7 + .../bundle/gems/pry-byebug-1.3.3/CHANGELOG.md | 83 + vendor/bundle/gems/pry-byebug-1.3.3/Gemfile | 9 + vendor/bundle/gems/pry-byebug-1.3.3/LICENSE | 20 + vendor/bundle/gems/pry-byebug-1.3.3/README.md | 115 ++ vendor/bundle/gems/pry-byebug-1.3.3/Rakefile | 10 + .../gems/pry-byebug-1.3.3/lib/pry-byebug.rb | 3 + .../pry-byebug-1.3.3/lib/pry-byebug/base.rb | 13 + .../lib/pry-byebug/breakpoints.rb | 140 ++ .../pry-byebug-1.3.3/lib/pry-byebug/cli.rb | 1 + .../lib/pry-byebug/commands.rb | 260 ++++ .../lib/pry-byebug/processor.rb | 127 ++ .../lib/pry-byebug/pry_ext.rb | 23 + .../lib/pry-byebug/pry_remote_ext.rb | 41 + .../lib/pry-byebug/version.rb | 3 + .../gems/pry-byebug-1.3.3/pry-byebug.gemspec | 23 + .../gems/pry-byebug-1.3.3/test/base_test.rb | 14 + .../pry-byebug-1.3.3/test/breakpoints_test.rb | 34 + .../pry-byebug-1.3.3/test/commands_test.rb | 178 +++ .../pry-byebug-1.3.3/test/examples/break1.rb | 20 + .../pry-byebug-1.3.3/test/examples/break2.rb | 18 + .../test/examples/stepping.rb | 25 + .../pry-byebug-1.3.3/test/processor_test.rb | 6 + .../pry-byebug-1.3.3/test/pry_ext_test.rb | 6 + .../test/pry_remote_ext_test.rb | 6 + .../gems/pry-byebug-1.3.3/test/test_helper.rb | 34 + vendor/bundle/gems/slop-3.6.0/.gitignore | 7 + vendor/bundle/gems/slop-3.6.0/.travis.yml | 9 + vendor/bundle/gems/slop-3.6.0/CHANGES.md | 309 ++++ vendor/bundle/gems/slop-3.6.0/Gemfile | 3 + vendor/bundle/gems/slop-3.6.0/LICENSE | 20 + vendor/bundle/gems/slop-3.6.0/README.md | 202 +++ vendor/bundle/gems/slop-3.6.0/Rakefile | 29 + vendor/bundle/gems/slop-3.6.0/lib/slop.rb | 687 +++++++++ .../gems/slop-3.6.0/lib/slop/commands.rb | 196 +++ .../bundle/gems/slop-3.6.0/lib/slop/option.rb | 214 +++ vendor/bundle/gems/slop-3.6.0/slop.gemspec | 17 + .../gems/slop-3.6.0/test/commands_test.rb | 26 + vendor/bundle/gems/slop-3.6.0/test/helper.rb | 12 + .../gems/slop-3.6.0/test/option_test.rb | 145 ++ .../bundle/gems/slop-3.6.0/test/slop_test.rb | 518 +++++++ .../specifications/byebug-2.7.0.gemspec | 52 + .../specifications/coderay-1.1.0.gemspec | 23 + .../specifications/columnize-0.8.9.gemspec | 37 + .../debugger-linecache-1.2.0.gemspec | 31 + .../method_source-0.8.2.gemspec | 31 + .../bundle/specifications/pry-0.10.0.gemspec | 40 + .../specifications/pry-byebug-1.3.3.gemspec | 33 + .../bundle/specifications/slop-3.6.0.gemspec | 33 + 495 files changed, 44962 insertions(+), 3 deletions(-) create mode 100644 .DS_Store create mode 100644 Gemfile create mode 100755 vendor/bundle/bin/byebug create mode 100755 vendor/bundle/bin/coderay create mode 100755 vendor/bundle/bin/pry create mode 100644 vendor/bundle/build_info/byebug-2.7.0.info create mode 100644 vendor/bundle/build_info/coderay-1.1.0.info create mode 100644 vendor/bundle/build_info/columnize-0.8.9.info create mode 100644 vendor/bundle/build_info/debugger-linecache-1.2.0.info create mode 100644 vendor/bundle/build_info/method_source-0.8.2.info create mode 100644 vendor/bundle/build_info/pry-0.10.0.info create mode 100644 vendor/bundle/build_info/pry-byebug-1.3.3.info create mode 100644 vendor/bundle/build_info/slop-3.6.0.info create mode 100644 vendor/bundle/gems/byebug-2.7.0/.gitignore create mode 100644 vendor/bundle/gems/byebug-2.7.0/.travis.yml create mode 100644 vendor/bundle/gems/byebug-2.7.0/CHANGELOG.md create mode 100644 vendor/bundle/gems/byebug-2.7.0/CONTRIBUTING.md create mode 100644 vendor/bundle/gems/byebug-2.7.0/GUIDE.md create mode 100644 vendor/bundle/gems/byebug-2.7.0/Gemfile create mode 100644 vendor/bundle/gems/byebug-2.7.0/LICENSE create mode 100644 vendor/bundle/gems/byebug-2.7.0/README.md create mode 100644 vendor/bundle/gems/byebug-2.7.0/Rakefile create mode 100755 vendor/bundle/gems/byebug-2.7.0/bin/byebug create mode 100644 vendor/bundle/gems/byebug-2.7.0/byebug.gemspec create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/.RUBYARCHDIR.time create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/Makefile create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.c create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.o create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.c create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.h create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.o create mode 100755 vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.so create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.c create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.o create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/extconf.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.c create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.o create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.c create mode 100644 vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.o create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/command.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/command_processor.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/breakpoints.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/catchpoint.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/condition.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/continue.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/control.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/display.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/edit.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/enable.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/eval.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/finish.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/frame.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/help.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/info.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/kill.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/list.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/method.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/quit.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/reload.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/repl.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/save.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/set.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/show.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/skip.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/source.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/stepping.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/threads.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/trace.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/variables.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/context.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/control_command_processor.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/helper.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/interface.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/local_interface.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/remote_interface.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/script_interface.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/processor.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/remote.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/lib/byebug/version.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/breakpoints_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/conditions_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/continue_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/debugger_alias_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/display_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/edit_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/eval_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint_deep.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/conditions.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/continue.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/display.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/edit.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/eval.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/finish.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/frame.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/frame_deep.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/gcd.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/hanoi.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/help.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/info.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/info2.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/interrupt.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/kill.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/list.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/method.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/post_mortem.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/primes.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/quit.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/reload.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/repl.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/restart.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/save.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/set.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/settings.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/show.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/source.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/stepping.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_c_method.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_ruby_method.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/test-triangle.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/thread.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/tmate.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/trace.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/tri3.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/triangle.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/examples/variables.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/finish_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/frame_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/help_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/info_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/interrupt_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/kill_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/list_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/method_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/post_mortem_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/quit_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/reload_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/repl_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/restart_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/save_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/set_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/show_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/source_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/stepping_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/support/breakpoint.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/support/matchers.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/support/test_dsl.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/support/test_interface.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/test_helper.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/thread_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/trace_test.rb create mode 100644 vendor/bundle/gems/byebug-2.7.0/test/variables_test.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/README_INDEX.rdoc create mode 100644 vendor/bundle/gems/coderay-1.1.0/Rakefile create mode 100755 vendor/bundle/gems/coderay-1.1.0/bin/coderay create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/duo.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoder.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/_map.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/comment_filter.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/count.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug_lint.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/div.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/filter.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/css.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/numbering.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/output.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/json.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lines_of_code.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lint.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/null.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/page.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/span.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/statistic.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/terminal.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/text.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/token_kind_filter.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/xml.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/yaml.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/for_redcloth.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/file_type.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/plugin.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/word_list.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanner.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/_map.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/c.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/clojure.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/cpp.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/css.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/debug.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/delphi.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/diff.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/erb.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/go.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/groovy.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/haml.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/html.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java/builtin_types.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java_script.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/json.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/lua.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/php.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/python.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/raydebug.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/patterns.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/string_state.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sass.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sql.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/taskpaper.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/text.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/xml.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/yaml.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/style.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/styles/_map.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/styles/alpha.rb create mode 100755 vendor/bundle/gems/coderay-1.1.0/lib/coderay/token_kinds.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens_proxy.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/lib/coderay/version.rb create mode 100755 vendor/bundle/gems/coderay-1.1.0/test/functional/basic.rb create mode 100755 vendor/bundle/gems/coderay-1.1.0/test/functional/examples.rb create mode 100644 vendor/bundle/gems/coderay-1.1.0/test/functional/for_redcloth.rb create mode 100755 vendor/bundle/gems/coderay-1.1.0/test/functional/suite.rb create mode 100644 vendor/bundle/gems/columnize-0.8.9/.gitignore create mode 100644 vendor/bundle/gems/columnize-0.8.9/.travis.yml create mode 100644 vendor/bundle/gems/columnize-0.8.9/AUTHORS create mode 100644 vendor/bundle/gems/columnize-0.8.9/COPYING create mode 100644 vendor/bundle/gems/columnize-0.8.9/ChangeLog create mode 100644 vendor/bundle/gems/columnize-0.8.9/Gemfile create mode 100644 vendor/bundle/gems/columnize-0.8.9/Makefile create mode 100644 vendor/bundle/gems/columnize-0.8.9/NEWS create mode 100644 vendor/bundle/gems/columnize-0.8.9/README.md create mode 100644 vendor/bundle/gems/columnize-0.8.9/Rakefile create mode 100644 vendor/bundle/gems/columnize-0.8.9/THANKS create mode 100644 vendor/bundle/gems/columnize-0.8.9/columnize.gemspec create mode 100644 vendor/bundle/gems/columnize-0.8.9/lib/Makefile create mode 100644 vendor/bundle/gems/columnize-0.8.9/lib/columnize.rb create mode 100644 vendor/bundle/gems/columnize-0.8.9/lib/columnize/Makefile create mode 100644 vendor/bundle/gems/columnize-0.8.9/lib/columnize/columnize.rb create mode 100644 vendor/bundle/gems/columnize-0.8.9/lib/columnize/opts.rb create mode 100644 vendor/bundle/gems/columnize-0.8.9/lib/columnize/version.rb create mode 100755 vendor/bundle/gems/columnize-0.8.9/test/test-columnize-array.rb create mode 100755 vendor/bundle/gems/columnize-0.8.9/test/test-columnize.rb create mode 100755 vendor/bundle/gems/columnize-0.8.9/test/test-columnizer.rb create mode 100755 vendor/bundle/gems/columnize-0.8.9/test/test-hashparm.rb create mode 100755 vendor/bundle/gems/columnize-0.8.9/test/test-issue3.rb create mode 100755 vendor/bundle/gems/columnize-0.8.9/test/test-min_rows_and_colwidths.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/.travis.yml create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/CHANGELOG.md create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/CONTRIBUTING.md create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/LICENSE.txt create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/OLD_CHANGELOG create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/OLD_README create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/README.md create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/Rakefile create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/debugger-linecache.gemspec create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/lib/debugger/linecache.rb create mode 100755 vendor/bundle/gems/debugger-linecache-1.2.0/lib/linecache19.rb create mode 100755 vendor/bundle/gems/debugger-linecache-1.2.0/lib/tracelines19.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin1.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin2.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin3.rb create mode 100755 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block1.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block2.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case1.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case2.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case3.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case4.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case5.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/class1.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/comments1.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/def1.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/each1.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/end.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/for1.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if1.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if2.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if3.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if4.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if5.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if6.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if7.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3a.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/data/not-lit.rb create mode 100755 vendor/bundle/gems/debugger-linecache-1.2.0/test/lnum-diag.rb create mode 100755 vendor/bundle/gems/debugger-linecache-1.2.0/test/parse-show.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/rcov-bug.rb create mode 100644 vendor/bundle/gems/debugger-linecache-1.2.0/test/short-file create mode 100755 vendor/bundle/gems/debugger-linecache-1.2.0/test/test-linecache.rb create mode 100755 vendor/bundle/gems/debugger-linecache-1.2.0/test/test-lnum.rb create mode 100755 vendor/bundle/gems/debugger-linecache-1.2.0/test/test-tracelines.rb create mode 100644 vendor/bundle/gems/method_source-0.8.2/.gemtest create mode 100644 vendor/bundle/gems/method_source-0.8.2/.travis.yml create mode 100644 vendor/bundle/gems/method_source-0.8.2/.yardopts create mode 100644 vendor/bundle/gems/method_source-0.8.2/Gemfile create mode 100644 vendor/bundle/gems/method_source-0.8.2/LICENSE create mode 100644 vendor/bundle/gems/method_source-0.8.2/README.markdown create mode 100644 vendor/bundle/gems/method_source-0.8.2/Rakefile create mode 100644 vendor/bundle/gems/method_source-0.8.2/lib/method_source.rb create mode 100644 vendor/bundle/gems/method_source-0.8.2/lib/method_source/code_helpers.rb create mode 100644 vendor/bundle/gems/method_source-0.8.2/lib/method_source/source_location.rb create mode 100644 vendor/bundle/gems/method_source-0.8.2/lib/method_source/version.rb create mode 100644 vendor/bundle/gems/method_source-0.8.2/method_source.gemspec create mode 100644 vendor/bundle/gems/method_source-0.8.2/test/test.rb create mode 100644 vendor/bundle/gems/method_source-0.8.2/test/test_code_helpers.rb create mode 100644 vendor/bundle/gems/method_source-0.8.2/test/test_helper.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/CHANGELOG.md create mode 100644 vendor/bundle/gems/pry-0.10.0/LICENSE create mode 100644 vendor/bundle/gems/pry-0.10.0/README.md create mode 100755 vendor/bundle/gems/pry-0.10.0/bin/pry create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/cli.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/code.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_file.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_range.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/code/loc.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/code_object.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/color_printer.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/command.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/command_set.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/amend_line.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang_pry.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/abstract_formatter.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/exception_formatter.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/file_formatter.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/input_expression_formatter.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cd.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_inspector.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_prompt.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/code_collector.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disable_pry.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disabled_commands.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/easter_eggs.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/exception_patcher.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/file_and_line_locator.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_all.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_program.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/find_method.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/fix_indent.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_cd.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_install.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_list.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_open.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gist.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/help.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/hist.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/import_set.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/install_command.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/jump_to.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_inspectors.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_prompts.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/constants.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/formatter.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/globals.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/grep.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/instance_vars.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/interrogatable.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/jruby_hacks.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_names.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_vars.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/ls_entity.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods_helper.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/self_methods.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/nesting.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/play.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_backtrace.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_version.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/raise_up.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reload_code.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reset.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ri.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/save_file.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_command.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_mode.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_doc.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_info.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_input.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_source.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/simple_prompt.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/stat.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/switch_to.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/toggle_color.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression/expression.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/whereami.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/commands/wtf.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/config.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/config/behavior.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/config/convenience.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/config/default.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/core_extensions.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/editor.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/exceptions.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/helpers.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/base_helpers.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/command_helpers.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/documentation_helpers.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/options_helpers.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/table.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/text.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/history.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/history_array.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/hooks.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/indent.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/input_completer.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/input_lock.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/inspector.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/last_exception.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/method.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/method/disowned.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/method/patcher.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/method/weird_method_locator.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/module_candidate.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/object_path.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/output.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/pager.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/plugins.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/prompt.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/pry_class.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/pry_instance.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/rbx_path.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/repl.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/repl_file_loader.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/rubygem.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/terminal.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/test/helper.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/version.rb create mode 100644 vendor/bundle/gems/pry-0.10.0/lib/pry/wrapped_module.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/.gitignore create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/.travis.yml create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/CHANGELOG.md create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/Gemfile create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/LICENSE create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/README.md create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/Rakefile create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/base.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/breakpoints.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/cli.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/commands.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/processor.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_ext.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_remote_ext.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/version.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/pry-byebug.gemspec create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/test/base_test.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/test/breakpoints_test.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/test/commands_test.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break1.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break2.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/test/examples/stepping.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/test/processor_test.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/test/pry_ext_test.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/test/pry_remote_ext_test.rb create mode 100644 vendor/bundle/gems/pry-byebug-1.3.3/test/test_helper.rb create mode 100644 vendor/bundle/gems/slop-3.6.0/.gitignore create mode 100644 vendor/bundle/gems/slop-3.6.0/.travis.yml create mode 100644 vendor/bundle/gems/slop-3.6.0/CHANGES.md create mode 100644 vendor/bundle/gems/slop-3.6.0/Gemfile create mode 100644 vendor/bundle/gems/slop-3.6.0/LICENSE create mode 100644 vendor/bundle/gems/slop-3.6.0/README.md create mode 100644 vendor/bundle/gems/slop-3.6.0/Rakefile create mode 100644 vendor/bundle/gems/slop-3.6.0/lib/slop.rb create mode 100644 vendor/bundle/gems/slop-3.6.0/lib/slop/commands.rb create mode 100644 vendor/bundle/gems/slop-3.6.0/lib/slop/option.rb create mode 100644 vendor/bundle/gems/slop-3.6.0/slop.gemspec create mode 100644 vendor/bundle/gems/slop-3.6.0/test/commands_test.rb create mode 100644 vendor/bundle/gems/slop-3.6.0/test/helper.rb create mode 100644 vendor/bundle/gems/slop-3.6.0/test/option_test.rb create mode 100644 vendor/bundle/gems/slop-3.6.0/test/slop_test.rb create mode 100644 vendor/bundle/specifications/byebug-2.7.0.gemspec create mode 100644 vendor/bundle/specifications/coderay-1.1.0.gemspec create mode 100644 vendor/bundle/specifications/columnize-0.8.9.gemspec create mode 100644 vendor/bundle/specifications/debugger-linecache-1.2.0.gemspec create mode 100644 vendor/bundle/specifications/method_source-0.8.2.gemspec create mode 100644 vendor/bundle/specifications/pry-0.10.0.gemspec create mode 100644 vendor/bundle/specifications/pry-byebug-1.3.3.gemspec create mode 100644 vendor/bundle/specifications/slop-3.6.0.gemspec diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e2512c36294df2d1af0c548b9520d5a03b27b5b1 GIT binary patch literal 6148 zcmeHKyG{c^3>-s>NJuCp<^BSHu!_PL@Bu&wR6&OlrJ%ct@8Z)KKMJCQDx!(Tl0CaV z&#rEY^BI6G51U(H0bovd#HWX;`E&P)T~x-1be{2n2fSm40qaTi?+NE#BJt8*j%qQIvJf*L>a!$HbsBA9SLA23!}J6!>oiz5x)N7ghiO literal 0 HcmV?d00001 diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..962f370 --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' +ruby '2.0.0' + +gem 'pry-byebug' \ No newline at end of file diff --git a/data/stopwords.txt b/data/stopwords.txt index 7336c7c..effee63 100644 --- a/data/stopwords.txt +++ b/data/stopwords.txt @@ -1 +1 @@ -a,able,about,across,after,all,almost,also,am,among,an,and,any,are,as,at,be,because,been,but,by,can,cannot,could,dear,did,do,does,either,else,ever,every,for,from,get,got,had,has,have,he,her,hers,him,his,how,however,i,if,in,into,is,it,its,just,least,let,like,likely,may,me,might,most,must,my,neither,no,nor,not,of,off,often,on,only,or,other,our,own,rather,said,say,says,she,should,since,so,some,than,that,the,their,them,then,there,these,they,this,tis,to,too,twas,us,wants,was,we,were,what,when,where,which,while,who,whom,why,will,with,would,yet,you,your,one,out,more,now,first,two,very,such,same,shall,upon,before,therefore,great,made,even,same,work,make,being,through,here,way,true,see,time,those,place,much,without,body,whole,another,thus,set,new,given,both,above,well,part,between,end,order,each,form,gutenberg +a,able,about,across,after,all,almost,also,am,among,an,and,any,are,as,at,be,because,been,but,by,can,cannot,could,dear,did,do,does,either,else,ever,every,for,from,get,got,had,has,have,he,her,hers,him,his,how,however,i,if,in,into,is,it,its,just,least,let,like,likely,may,me,might,most,must,my,neither,no,nor,not,of,off,often,on,only,or,other,our,own,rather,said,say,says,she,should,since,so,some,than,that,the,their,them,then,there,these,they,this,tis,to,too,twas,us,wants,was,we,were,what,when,where,which,while,who,whom,why,will,with,would,yet,you,your,one,out,more,now,first,two,very,such,same,shall,upon,before,therefore,great,made,even,same,work,make,being,through,here,way,true,see,time,those,place,much,without,body,whole,another,thus,set,new,given,both,above,well,part,between,end,order,each,form,gutenberg, diff --git a/gutenberg.rb b/gutenberg.rb index 84d20f6..f064355 100644 --- a/gutenberg.rb +++ b/gutenberg.rb @@ -1,6 +1,7 @@ require_relative 'lib/simple_predictor' require_relative 'lib/complex_predictor' + def run!(predictor_klass, opts={}) puts "+----------------------------------------------------+" puts "| #{predictor_klass}#{" " * (51 - predictor_klass.to_s.size)}|" diff --git a/lib/complex_predictor.rb b/lib/complex_predictor.rb index b8921f3..2688710 100644 --- a/lib/complex_predictor.rb +++ b/lib/complex_predictor.rb @@ -1,12 +1,57 @@ require_relative 'predictor' +require 'pry-byebug' class ComplexPredictor < Predictor # Public: Trains the predictor on books in our dataset. This method is called # before the predict() method is called. # # Returns nothing. + + + def train! + + #iterates through all the words for each category, and creates a hash that has + #each word as a key, and the value is the number of times it appears. + # @data looks like: + # { + # philosophy: { + # word1: 10, + # word2: 50, + # ... + # }, + # archeology: { + # word1: 15, + # word2: 30, + # ... + # } + # } + @data = {} + @temp_data = {} + + @all_books.each do |category, books| + @data[category] = {} + @temp_data[category] = {} + books.each do |filename, tokens| + tokens.each do |token| + if good_token?(token) + @data[category][token] ||= 1 + @data[category][token] += 1 + end + end + @data_array = @data[category].sort_by {|k,v| v}.reverse + # @temp_data[category] = @data_array + # limit = @temp_data[category][100].last + limit = @data_array[100].last + @data[category].keep_if do |key, value| + value > limit + end + end + end + # binding.pry + + end # Public: Predicts category. @@ -15,8 +60,41 @@ def train! # # Returns a category. def predict(tokens) - # Always predict astronomy, for now. - :astronomy + + input_words = {} + match_words = {} + category_count = {} + +#put good tokens in an input words hash with their counts + tokens.each do |token| + if good_token?(token) + input_words[token] ||= 0 + input_words[token] += 1 + end + end + +#find words in the input words that match our data from the train method and store in match_words hash with their count + @data.each do |category, word_hash| + match_words[category] = {} + word_hash.each do |word, count| + if input_words.has_key?(word) + match_words[category][word] = input_words[word] + end + end + + end + # binding.pry + +#add up word count per category and put it in the category count hash + match_words.each do |category, words| + category_count[category] = match_words[category].values.inject(0) { |a, b| a + b } + end + + # binding.pry + +#return category with highest number of matches + return category_count.max_by{|k,v| v}.first + end end diff --git a/vendor/bundle/bin/byebug b/vendor/bundle/bin/byebug new file mode 100755 index 0000000..785cd12 --- /dev/null +++ b/vendor/bundle/bin/byebug @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'byebug' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ + version = $1 + ARGV.shift + end +end + +gem 'byebug', version +load Gem.bin_path('byebug', 'byebug', version) diff --git a/vendor/bundle/bin/coderay b/vendor/bundle/bin/coderay new file mode 100755 index 0000000..d6d76cb --- /dev/null +++ b/vendor/bundle/bin/coderay @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'coderay' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ + version = $1 + ARGV.shift + end +end + +gem 'coderay', version +load Gem.bin_path('coderay', 'coderay', version) diff --git a/vendor/bundle/bin/pry b/vendor/bundle/bin/pry new file mode 100755 index 0000000..d26856b --- /dev/null +++ b/vendor/bundle/bin/pry @@ -0,0 +1,23 @@ +#!/usr/bin/env ruby +# +# This file was generated by RubyGems. +# +# The application 'pry' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = ">= 0" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\A_(.*)_\z/ + version = $1 + ARGV.shift + end +end + +gem 'pry', version +load Gem.bin_path('pry', 'pry', version) diff --git a/vendor/bundle/build_info/byebug-2.7.0.info b/vendor/bundle/build_info/byebug-2.7.0.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/byebug-2.7.0.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/coderay-1.1.0.info b/vendor/bundle/build_info/coderay-1.1.0.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/coderay-1.1.0.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/columnize-0.8.9.info b/vendor/bundle/build_info/columnize-0.8.9.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/columnize-0.8.9.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/debugger-linecache-1.2.0.info b/vendor/bundle/build_info/debugger-linecache-1.2.0.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/debugger-linecache-1.2.0.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/method_source-0.8.2.info b/vendor/bundle/build_info/method_source-0.8.2.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/method_source-0.8.2.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/pry-0.10.0.info b/vendor/bundle/build_info/pry-0.10.0.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/pry-0.10.0.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/pry-byebug-1.3.3.info b/vendor/bundle/build_info/pry-byebug-1.3.3.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/pry-byebug-1.3.3.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/build_info/slop-3.6.0.info b/vendor/bundle/build_info/slop-3.6.0.info new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/vendor/bundle/build_info/slop-3.6.0.info @@ -0,0 +1 @@ + diff --git a/vendor/bundle/gems/byebug-2.7.0/.gitignore b/vendor/bundle/gems/byebug-2.7.0/.gitignore new file mode 100644 index 0000000..c7d47ea --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/.gitignore @@ -0,0 +1,18 @@ +tmp +pkg +doc + +.rvmrc +.ruby-version +.ruby-gemset +.gdbinit +.gdb_history +.bundle +.tags +.ackrc +.jrubyrc + +Gemfile.lock + +lib/byebug/byebug.so +lib/byebug/byebug.bundle diff --git a/vendor/bundle/gems/byebug-2.7.0/.travis.yml b/vendor/bundle/gems/byebug-2.7.0/.travis.yml new file mode 100644 index 0000000..23a32c8 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/.travis.yml @@ -0,0 +1,8 @@ +before_script: bundle exec rake compile +rvm: +- 2.0.0 +- 2.1.0 +- ruby-head +matrix: + allow_failures: + - rvm: ruby-head diff --git a/vendor/bundle/gems/byebug-2.7.0/CHANGELOG.md b/vendor/bundle/gems/byebug-2.7.0/CHANGELOG.md new file mode 100644 index 0000000..796689b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/CHANGELOG.md @@ -0,0 +1,214 @@ +# 2.7.0 +* Bugfix release (#52, #53 and #54) + + +# 2.6.0 + +* Fix circular dependency that was affecting `pry-byebug`, thanks @andreychernih + + +# 2.5.0 + +* Support for `sublime-debugger` + + +# 2.4.1 + +* Fix installation error in Mac OSX (#40), thanks @luislavena + + +# 2.4.0 + +* Use `require` instead of `require_relative` for loading byebug's extension +library (thanks @nobu) +* Adds back `debugger` as an alias to `byebug` (thanks @wallace) +* Adds -R option to byebug's binary to specify server's hostname:port for remote +debugging (thanks @mrkn) +* Fixes `thread list` showing too many threads +* Change in tracing global variables. Use `trace variable foo` instead of `trace +variable $foo` +* Fix setting post mortem mode with `set post_mortem`. Now this is the only +post mortem functionality available as specifying `Byebug.post_mortem` with a +block has been removed in this version. + + +# 2.3.1 + +* Fixes bug preventing users from deleting breakpoints +* Fix broken test suite + + +# 2.3.0 + +* Compatibility with Phusion Passenger Enterprise (thanks @FooBarWidget) +* More minimalist help system + + +# 2.2.2 + +* Fix another compilation issue in 64 bit systems + + +# 2.2.1 + +* Fix compilation issue introduced by 2.2.0 (#26) +* "show" and "set" option `stack_trace_on_error` is now called `stack_on_error` + + +# 2.2.0 + +* Small fixes in stack_size calculations +* Warning free byebug +* Add `verbose` setting for TracePoint API event inspection +* Fix setting `post_mortem` mode +* Allow `edit ` without a line number + + +# 2.1.1 + +* Fix bug when debugging code inside '-e' flag + + +# 2.1.0 + +* Fix bug in remote debugging display +* Fix bug where eval would crash when inspect raised an exception (reported by +@iblue) +* `enable breakpoints` now enables every breakpoint +* `disable breakpoints` now disables every breakpoint + + +# 2.0.0 + +* Various bug fixes +* "Official" definition of a command API +* Thread support + + +## 1.8.2 + +* More user friendly regexps for commands +* Better help for some commands +* `save` command now saves the list of "displays" +* Fixes bug in calculating stacksize + + +## 1.8.1 + +* Bugfix release + + +## 1.8.0 + +* Remote debugging support + + +## 1.7.0 + +* Callstack display: specifically mark c-frames +* Callstack navigation: skip c-frames +* Callstack navigation: autolist after navigation commands + + +## 1.6.1 + +* Windows compatibiliy: compilation and terminal width issues + + +## 1.6.0 + +* `byebug` placed at the end of a block or method call now works as expected +* Don't autolist when ruby '-e' option is used +* Fixes callstyles. From now on, use 'long' for detailed frames in callstack and +'short' for more concise frames + + +## 1.5.0 + +* No more Byebug.start to get correct callstack information! Dropping `byebug` +anywhere and inmediately printing the stack just works now. :) + + +## 1.4.2 + +* Fixes crash when using "help command subcommand" +* Byebug now works with Rails Console debugging flag +* Fix post-mortem mode when running byebug from the outset +* Fix --no-quit flag when running byebug from the outset + + +## 1.4.1 + +* Fixes crash when printing some filenames in backtraces +* Allows byebug developers to easily use compilers different from gcc (thanks +@GarthSnyder!) + + +## 1.4.0 + +* Byebug now uses the Debug Inspector API: faster and nicer! +* Fixes bug that prevents some random crashes + + +## 1.3.1 + +* Byebug now works with Rails debugging flag +* Fix bug which would make byebug crash when trying to print lines of code +containing the character '%' +* Fix bug which prevented basename and linetrace options from working together + + +## 1.3.0 + +* Support colon-delimited include paths in command-line front-end (@ender672) + + +## 1.2.0 + +* Added 'pry' command. +* Ctrl+C during command line editing is handled and works like pry/irb + + +## 1.1.1 + +* Better help system +* Code cleanup +* First version compatible with pry-byebug + + +## 1.1.0 + +* Post-mortem support + + +## 1.0.3 + +* "autoreload" is set by default now +* "list" command: no negative line numbers shown, and line range behaves as +expected at the begining/end of file +* In some weird cases, "backtrace" command segfaults when trying to show info on +some frame args. Don't know the reason yet, but the exception is handled now and +and the command doesn't segfault anymore. +* Try some thread support (not even close to usable) + + +## 1.0.2 + +* "autolist" and "autoeval" are default settings now +* Fixes bug which messed up the call-stack when manipulating backtrace +information and when nexting/stepping + + +## 1.0.1 + +* Corrected small bug preventing byebug from loading + + +## 1.0.0 + +* Green test suite + + +## 0.0.1 + +* Initial release diff --git a/vendor/bundle/gems/byebug-2.7.0/CONTRIBUTING.md b/vendor/bundle/gems/byebug-2.7.0/CONTRIBUTING.md new file mode 100644 index 0000000..e34290b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/CONTRIBUTING.md @@ -0,0 +1,21 @@ +Thanks for your interest in contributing to ByeBug! + +To make your changes, follow this steps: + +* [Fork the project](https://help.github.com/fork-a-repo) +* Create a topic branch - `git checkout -b my_branch` +* Insert awesome code - See below +* Push your branch to your forked repo - `git push origin my_branch` +* [Make a pull request](https://help.github.com/articles/using-pull-requests) + +How to insert awesome code: + +This gem uses `rake-compiler` to build native gems. You can use `rake compile` to build the native gem +and start the tests using `rake test` + +```bash +rake compile +rake test +``` + +It's appreciated if you add tests for new functionality. Thanks! \ No newline at end of file diff --git a/vendor/bundle/gems/byebug-2.7.0/GUIDE.md b/vendor/bundle/gems/byebug-2.7.0/GUIDE.md new file mode 100644 index 0000000..40f425b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/GUIDE.md @@ -0,0 +1,1368 @@ +### First Steps + +A handful of commands are enough to get started using `byebug`. The following +session illustrates these commands. + +``` +$ byebug triangle.rb +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 1: # Compute the n'th triangle number: triangle(n) == (n*(n+1))/2 +=> 2: def triangle(n) + 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: t = triangle(3) +(byebug) +``` + +We are currently stopped before the first executable line of the program: line 2 +of `triangle.rb`. If you are used to less dynamic languages and have used +debuggers for more statically compiled languages like C, C++, or Java, it may +seem odd to be stopped before a function definition but in Ruby line 2 is +executed. + +Byebug's prompt is `(byebug)`. If the program has died and you are in +post-mortem debugging, `(byebug:post-mortem)` is used instead. If the program +has terminated normally, the string this position will be `(byebug:ctrl)`. The +commands available change depending on the program's state. + +Byebug automatically lists 10 lines of code centered around the current line +everytime it is stopped. The current line is marked with `=>`, so the range +byebug would like to show is [-3..6]. However since there aren't 5 lines before +the current line, the range is moved _up_ so we can actually display 10 lines +of code. + +Now let us step through the program. + +``` +(byebug) step +[2, 11] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 2: def triangle(n) + 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: +=> 10: t = triangle(3) + 11: puts t +(byebug) # hit enter +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 1: # Compute the n'th triangle number: triangle(n) == (n*(n+1))/2 + 2: def triangle(n) +=> 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: t = triangle(3) +(byebug) p tri +nil +(byebug) step +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 1: # Compute the n'th triangle number: triangle(n) == (n*(n+1))/2 + 2: def triangle(n) + 3: tri = 0 +=> 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: t = triangle(3) +(byebug) p tri +0 +``` + +The first `step` command runs the script one executable unit. The second command +we entered was just hitting the return key; `byebug` remembers the last command +you entered was `step` and it runs it again. + +One way to print the values of variables is `p` (there are other ways). When we +look at the value of `tri` the first time, we see it is `nil`. Again we are +stopped _before_ the assignment on line 3, and this variable hasn't been set +previously. However after issuing another `step` command we see that the value +is 0 as expected. If every time we stop we want to see the value of `tri` to see +how things are going, there is a better way by setting a display expression: + +``` +(byebug) display tri +1: tri = 0 +``` + +Now let us run the program until we return from the function. We'll want to see +which lines get run, so we turn on _line tracing_. If we don't want whole paths +to be displayed when tracing, we can turn on _basename_. + +``` +(byebug) display i +2: i = +(byebug) set linetrace on +line tracing is on. +(byebug) set basename on +basename is on. +(byebug) finish +Tracing: triangle.rb:5 tri += i +1: tri = 0 +2: i = 0 +Tracing: triangle.rb:5 tri += i +1: tri = 0 +2: i = 1 +Tracing: triangle.rb:5 tri += i +1: tri = 1 +2: i = 2 +Tracing: triangle.rb:5 tri += i +1: tri = 3 +2: i = 3 +Tracing: triangle.rb:7 tri +1: tri = 6 +2: i = +Tracing: triangle.rb:11 puts t +1: tri = +2: i = +[2, 11] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 2: def triangle(n) + 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: t = triangle(3) +=> 11: puts t +1: tri = +2: i = +(byebug) quit +Really quit? (y/n) y +``` + +So far, so good. As you can see from the above to get out of `byebug`, one +can issue a `quit` command (`q` and `exit` are just as good). If you want to +quit without being prompted, suffix the command with an exclamation mark, e.g., +`q!`. + + +### Second Sample Session: Delving Deeper + +In this section we'll introduce breakpoints, the call stack and restarting. +Below we will debug a simple Ruby program to solve the classic Towers of Hanoi +puzzle. It is augmented by the bane of programming: some command-parameter +processing with error checking. + +```bash +$ byebug hanoi.rb +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. +=> 2: def hanoi(n,a,b,c) + 3: if n-1 > 0 + 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +(byebug) +``` + +Recall in the first section iwe said that before the `def` is run, the method it +names is undefined. Let's check that out. First let's see what private methods +we can call before running `def hanoi`. + +```bash +(byebug) private_methods +[:public, :private, :include, :using, :define_method, :default_src_encoding, ... +``` + +`private_methods` is not a byebug command but a Ruby feature. By default, when +byebug doesn't understand a command, it will evaluate it as if it was a Ruby +command. If you don't want this behaviour, you can use `set autoeval off` or +even drop it in your `.byebugrc` file if you want that behaviour permanently. +The output of `private_methods`, thought, is unwieldy for our porpuse: check +whether `hanoi` method is in the list. Fortunately, byebug has nice formatting +features: we can sort the output and put it into columns list using the print +command `ps`. + +```bash +(byebug) ps private_methods +Array debug_program open sprintf +Complex default_src_encoding p srand +DelegateClass define_method pp syscall +Digest eval print system +Float exec printf test +Hash exit private throw +Integer exit! proc trace_var +Pathname fail process_options trap +Rational fork public untrace_var +String format putc using +__callee__ gem puts warn +__dir__ gem_original_require raise whence_file +__method__ gets rand +` global_variables readline +abort include readlines +at_exit initialize require +autoload initialize_clone require_relative +autoload? initialize_copy respond_to_missing? +binding initialize_dup select +block_given? iterator? set_trace_func +caller lambda singleton_method_added +caller_locations load singleton_method_removed +catch local_variables singleton_method_undefined +dbg_print loop sleep +dbg_puts method_missing spawn +(byebug) +``` + +Now let's see what happens after stepping: + +```bash +(byebug) private_methods.member?(:hanoi) +false +(byebug:1) step +[7, 16] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end + 11: +=> 12: i_args=ARGV.length + 13: if i_args > 1 + 14: puts "*** Need number of disks or no parameter" + 15: exit 1 + 16: end +(byebug) private_methods.member?(:hanoi) +true +(byebug) +``` + +Okay, lets go on and talk about program arguments. + +```bash +(byebug) ARGV +[] +``` + +Ooops. We forgot to specify any parameters to this program. Let's try again. We +can use the `restart` command here. + +```bash +(byebug) restart 3 +Re exec'ing: + /home/davidr/.rvm/gems/ruby-2.0.0-p195@byebug/gems/byebug-1.1.1/bin/byebug /home/davidr/Proyectos/byebug/old_doc/hanoi.rb 3 +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. +=> 2: def hanoi(n,a,b,c) + 3: if n-1 > 0 + 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +(byebug) break 4 +Created breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3 +(byebug) continue +Stopped by breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3 +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. + 2: def hanoi(n,a,b,c) +=> 3: if n-1 > 0 + 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +(byebug) display n +1: n = 3 +(byebug) display a +2: a = a +(byebug) undisplay 2 +(byebug) display a.inspect +3: a.inspect = :a +(byebug) display b.inspect +4: b.inspect = :b +(byebug) continue +Stopped by breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3 +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. + 2: def hanoi(n,a,b,c) +=> 3: if n-1 > 0 + 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +1: n = 2 +3: a.inspect = :a +4: b.inspect = :c +(byebug) c +Stopped by breakpoint 1 at /home/davidr/Proyectos/byebug/old_doc/hanoi.rb:3 +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. + 2: def hanoi(n,a,b,c) +=> 3: if n-1 > 0 + 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +1: n = 1 +3: a.inspect = :a +4: b.inspect = :b +(byebug) set nofullpath +Displaying frame's full file names is off. +(byebug) where +--> #0 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol) at .../byebug/old_doc/hanoi.rb:4 + #1 Object.hanoi(n#Fixnum, a#Symbol, b#Symbol, c#Symbol) at .../byebug/old_doc/hanoi.rb:8 + #2 at .../byebug/old_doc/hanoi.rb:34 +(byebug) +``` + +In the above we added new commands: `break` (see [breakpoints]()), which +indicates to stop just before that line of code is run, and `continue`, which +resumes execution. Notice the difference between `display a` and +`display a.inspect`. An implied string conversion is performed on the expression +after it is evaluated. To remove a display expression `undisplay` is used. If we +give a display number, just that display expression is removed. + +We also used a new command `where`(see [backtrace]()) to show the callstack. In +the above situation, starting from the bottom line we see we called the `hanoi` +method from line 34 of the file `hanoi.rb` and the `hanoi` method called itself +two more times at line 4. + +In the callstack we show a _current frame_ mark, the frame number, the method +being called, the names of the parameters, the types those parameters +_currently_ have and the file-line position. Remember it's possible that when +the program was called the parameters had different types, since the types of +variables can change dynamically. You can alter the style of what to show in the +trace (see [callstyle]()). + +Now let's move around the callstack. + +```bash +(byebug) undisplay +Clear all expressions? (y/n) y +(byebug) i_args +NameError Exception: undefined local variable or method `i_args' for main:Object +(byebug) frame -1 +[25, 34] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 25: exit 2 + 26: end + 27: end + 28: + 29: if n < 1 or n > 100 + 30: puts "*** number of disks should be between 1 and 100" + 31: exit 2 + 32: end + 33: +=> 34: hanoi(n, :a, :b, :c) +(byebug) i_args +0 +(byebug) p n +3 +(byebug) down 2 +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/hanoi.rb + 1: # Solves the classic Towers of Hanoi puzzle. + 2: def hanoi(n,a,b,c) + 3: if n-1 > 0 +=> 4: hanoi(n-1, a, c, b) + 5: end + 6: puts "Move disk %s to %s" % [a, b] + 7: if n-1 > 0 + 8: hanoi(n-1, c, b, a) + 9: end + 10: end +(byebug:1) p n +2 +``` + +Notice in the above to get the value of variable `n` we had to use a print +command like `p n`. If we entered just `n`, that would be taken to mean byebug +command `next`. In the current scope, variable `i_args` is not defined. +However I can change to the top-most frame by using the `frame` command. Just as +with arrays, -1 means the last one. Alternatively using frame number 3 would +have been the same thing; so would issuing `up 3`. Note that in the outside +frame #3, the value of `i_args` can be shown. Also note that the value of +variable `n` is different. + + +### Attaching to a running program with `byebug` + +In the previous sessions we've been calling byebug right at the outset, but +there is another mode of operation you might use. If there's a lot of code that +needs to be run before the part you want to inspect, it might not be efficient +or convenient to run byebug from the outset. + +In this section we'll show how to enter the code in the middle of your program, +while delving more into byebug's operation. We will also use unit testing. Using +unit tests will greatly reduce the amount of debugging needed, while at the same +time, will increase the quality of your program. + +What we'll do is take the `triangle` code from the first session and write a +unit test for that. In a sense we did write a tiny test for the program which +was basically the last line where we printed the value of `triangle(3)`. This +test however wasn't automated: the expectation is that someone would look at the +output and verify that what was printed is what was expected. + +Before we can turn that into something that can be `required`, we probably want +to remove that output. However I like to keep in that line so that when I +look at the file, I have an example of how to run it. Therefore we will +conditionally run this line if that file is invoked directly, but skip it if it +is not. _NOTE: `byebug` resets `$0` to try to make things like this work._ + +```ruby +if __FILE__ == $0 + t = triangle(3) + puts t +end +``` + +Okay, we're now ready to write our unit test. We'll use `minitest` which comes +with the standard Ruby distribution. Here's the test code; it should be in the +same directory as `triangle.rb`. + +```ruby +require 'minitest/autorun' +require_relative 'triangle.rb' + +class TestTri < MiniTest::Unit::TestCase + def test_basic + solutions = [] + 0.upto(5) do |i| + solutions << triangle(i) + end + assert_equal([0, 1, 3, 6, 10, 15], solutions, + 'Testing the first 5 triangle numbers') + end +end +``` + +Let's say we want to stop before the first statement in our test method, we'll +add the following: + +```ruby +... +def test_basic + byebug + solutions = [] +... +``` + +Now we run the program, requiring `byebug` + +```bash +$ ruby -rbyebug test-triangle.rb +Run options: --seed 13073 + +# Running tests: + +[2, 11] in test-triangle.rb + 2: require_relative 'triangle.rb' + 3: + 4: class TestTri < MiniTest::Unit::TestCase + 5: def test_basic + 6: byebug +=> 7: solutions = [] + 8: 0.upto(5) do |i| + 9: solutions << triangle(i) + 10: end + 11: assert_equal([0, 1, 3, 6, 10, 15], solutions, +(byebug) +``` + +and we see that we are stopped at line 7 just before the initialization of the +list `solutions`. + +Now let's see where we are... + +```bash +(byebug) set nofullpath +Displaying frame's full file names is off. +(byebug) bt +--> #0 TestTri.test_basic at test-triangle.rb:7 + #1 MiniTest::Unit::TestCase.run(runner#MiniTest::Unit) at .../2.0.0/minitest/unit.rb:1301 + #2 MiniTest::Unit.block in _run_suite(suite#Class, type#Symbol) at .../2.0.0/minitest/unit.rb:919 + +-- #3 Array.map at .../2.0.0/minitest/unit.rb:912 + #4 MiniTest::Unit._run_suite(suite#Class, type#Symbol) at .../2.0.0/minitest/unit.rb:912 + #5 MiniTest::Unit.block in _run_suites(suites#Array, type#Symbol) at .../2.0.0/minitest/unit.rb:899 + +-- #6 Array.map at .../2.0.0/minitest/unit.rb:899 + #7 MiniTest::Unit._run_suites(suites#Array, type#Symbol) at .../2.0.0/minitest/unit.rb:899 + #8 MiniTest::Unit._run_anything(type#Symbol) at .../2.0.0/minitest/unit.rb:867 + #9 MiniTest::Unit.run_tests at .../2.0.0/minitest/unit.rb:1060 + #10 MiniTest::Unit.block in _run(args#Array) at .../2.0.0/minitest/unit.rb:1047 + +-- #11 Array.each at .../2.0.0/minitest/unit.rb:1046 + #12 MiniTest::Unit._run(args#Array) at .../2.0.0/minitest/unit.rb:1046 + #13 MiniTest::Unit.run(args#Array) at .../2.0.0/minitest/unit.rb:1035 + #14 #.block in autorun at .../2.0.0/minitest/unit.rb:789 +(byebug) +``` + +We get the same result as if we had run byebug from the outset, just faster! + +__NOTICE: In ruby-debug, debugger and older versions of byebug, this would not +work as expected. If you are having issues, please upgrade to byebug >= 1.5.0__ + + +### Byebug.start with a block + +We saw that `Byebug.start()` and `Byebug.stop()` allow fine-grain control over +where byebug tracking should occur. + +Rather than use an explicit `stop()`, you can also pass a block to the `start()` +method. This causes `start()` to run and then `yield` to that block. When the +block is finished, `stop()` is run. In other words, this wraps a +`Byebug.start()` and `Byebug.stop()` around the block of code. But it also has a +side benefit of ensuring that in the presence of an uncaught exception `stop` is +run, without having to explicitly use `begin ... ensure Byebug.stop() end`. + +For example, in Ruby on Rails you might want to debug code in one of the +controllers without causing any slowdown to any other code. And this can be done +by wrapping the controller in a `start()` with a block; when the method wrapped +this way finishes, byebug is turned off and the application proceeds at regular +speed. + +Of course, inside the block you will probably want to enter the byebug using +`Byebug.byebug()`, otherwise there would be little point in using the `start`. +For example, you can do this in `irb`: + +```bash +$ irb +2.0.0p195 :001 > require 'byebug' + => true +2.0.0p195 :002 > def foo +2.0.0p195 :003?> x=1 +2.0.0p195 :004?> puts 'foo' +2.0.0p195 :005?> end + => nil +2.0.0p195 :006 > Byebug.start{byebug; foo} +(irb) @ 6 +(byebug) s +(irb) @ 3 +(byebug) s +(irb) @ 4 +(byebug) p x +1 +(byebug) s +foo + => true +2.0.0p195 :007 > +``` + +There is a counter inside of `Byebug.start` method to make sure that this works +when another `Byebug.start` method is called inside of the outer one. However, +if you are stopped inside byebug, issuing another `byebug` call will not have +any effect even if it is nested inside another `Byebug.start`. + + +### Debugging Oddities: How debugging Ruby may be different from other languages + +If you are used to debugging in other languages like C, C++, Perl, Java or even +Bash (see [bashdb](http://bashdb.sf.net)), there may be a number of things that +seem or feel a little bit different and may confuse you. A number of these +things aren't oddities of the debugger per se but differences in how Ruby works +compared to those other languages. Because Ruby works a little differently from +those other languages, writing a debugger has to also be a little different as +well if it is to be useful. In this respect, using byebug may help you +understand Ruby better. + +We've already seen one such difference: the fact that we stop on method +definitions or `def`'s and that is because these are in fact executable +statements. In other compiled languages this would not happen because that's +already been done when you compile the program (or in Perl when it scans in the +program). In this section we'll consider some other things that might throw off +new users to Ruby who are familiar with other languages and debugging in them. + +* Bouncing Around in Blocks (iterators) +* No Parameter Values in a Call Stack +* Lines You Can Stop At + +#### Bouncing Around in Blocks (iterators) + +When debugging languages with coroutines like Python and Ruby, a method call may +not necessarily go to the first statement after the method header. It's possible +that the call will continue after a `yield` statement from a prior call. + +```ruby +# Enumerator for primes +class SievePrime + @@odd_primes = [] + def self.next_prime(&block) + candidate = 2 + yield candidate + not_prime = false + candidate += 1 + while true do + @@odd_primes.each do |p| + not_prime = (0 == (candidate % p)) + break if not_prime + end + unless not_prime + @@odd_primes << candidate + yield candidate + end + candidate += 2 + end + end +end +SievePrime.next_prime do |prime| + puts prime + break if prime > 10 +end +``` + +```bash +$ byebug primes.rb +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/primes.rb + 1: # Enumerator for primes +=> 2: class SievePrime + 3: @@odd_primes = [] + 4: def self.next_prime(&block) + 5: candidate = 2 + 6: yield candidate + 7: not_prime = false + 8: candidate += 1 + 9: while true do + 10: @@odd_primes.each do |p| +(byebug) set linetrace +line tracing is on. +(byebug) set basename +basename in on. +(byebug) step 9 +Tracing: primes.rb:3 @@odd_primes = [] +Tracing: primes.rb:4 def self.next_prime(&block) +Tracing: primes.rb:22 SievePrime.next_prime do |prime| +Tracing: primes.rb:5 candidate = 2 +Tracing: primes.rb:6 yield candidate +Tracing: primes.rb:23 puts prime +2 +Tracing: primes.rb:24 break if prime > 10 +Tracing: primes.rb:7 not_prime = false +Tracing: primes.rb:8 candidate += 1 +[3, 12] in /home/davidr/Proyectos/byebug/old_doc/primes.rb + 3: @@odd_primes = [] + 4: def self.next_prime(&block) + 5: candidate = 2 + 6: yield candidate + 7: not_prime = false +=> 8: candidate += 1 + 9: while true do + 10: @@odd_primes.each do |p| + 11: not_prime = (0 == (candidate % p)) + 12: break if not_prime +(byebug) +``` + +The loop between lines 23-26 gets interleaved between those of +`Sieve::next_prime`, lines 6-19 above. + + +#### No Parameter Values in a Call Stack + +In traditional debuggers, in a call stack you can generally see the names of the +parameters and the values that were passed in. + +Ruby is a very dynamic language and it tries to be efficient within the confines +of the language definition. Values generally aren't taken out of a variable or +expression and pushed onto a stack. Instead a new scope is created and the +parameters are given initial values. Parameter passing is by _reference_ not by +_value_ as it is say Algol, C, or Perl. During the execution of a method, +parameter values can change (and often do). In fact even the _class_ of the +object can change. + +So at present, the name of the parameter is shown. The call-style setting +([callstyle]()) can be used to set whether the name is shown or the name and the +_current_ class of the object. It has been contemplated that a style might be +added which saves on call shorter "scalar" types of values and the class name. + + +#### Lines You Can Stop At + +As with the duplicate stops per control (e.g. `if` statement), until tools like +debuggers get more traction among core ruby developers there are going to be +weirdness. Here we describe the stopping locations which effects the breakpoint +line numbers you can stop at. + +Consider the following little Ruby program. + +```ruby +'Yes it does' =~ / +(Yes) \s+ +it \s+ +does +/ix +puts $1 +``` + +The stopping points that Ruby records are the last two lines, lines 5 and 6. + +Inside `byebug` you can get a list of stoppable lines for a file using the `info +file` command with the attribute `breakpoints`. + +To be continued... +* more complex example with objects, pretty printing and irb. +* line tracing and non-interactive tracing. +* mixing in Byebug.debug with byebug +* post-mortem debugging and setting up for that + + +## Getting in & out + +### Starting byebug + +There is a wrapper script called `byebug` which basically `require`'s the gem +then loads `byebug` before its argument (the program to be debugged) is started. + +```bash +byebug [byebug-options] [--] ruby-script ruby-script-arguments +``` + +If you don't need to pass dash options to your program, which might be confused +with byebug options, then you don't need to add the `--`. To get a brief list of +options and descriptions, use the `--help` option. + +```bash +$ byebug --help +byebug 1.6.1 +Usage: byebug [options] -- + +Options: + -d, --debug Set $DEBUG=true + -I, --include PATH Add PATH (single or multiple:path:list) to $LOAD_PATH + --no-quit Do not quit when script finishes + --no-stop Do not stop when script is loaded + --nx Don't run any byebug initialization files + --post-mortem Enable post-mortem mode for uncaught exceptions + -r, --require SCRIPT Require library before script + --restart-script FILE Name of the script file to run. Erased after read + --script FILE Name of the script file to run + -x, --trace Turn on line tracing + +Common options: + --help Show this message + --version Print program version + -v Print version number, then turn on verbose mode +``` + +Many options appear as a long option name, such as `--help` and a short one +letter option name, such as `-h`. The list of options is detailed below: + +* **-h | --help**. It causes `byebug` to print some basic help and exit +* **-v | --version**. It causes `byebug` to print its version number and +exit. +* **-d | --debug**. Set `$DEBUG` to `true`. Compatible with Ruby's. +* **-I | --include **. Add `path` to load path. `path` can be a single +path ar a colon separated path list. +* **--post-mortem**. If your program raises an exception that isn't caught you +can enter byebug for inspection of what went wrong. You may also want to use +this option in conjunction with `--no-stop`. See also [Post-Mortem Debugging](). +* **--no-quit**. Restart `byebug` when your program terminates normally. +* **--no-stop**. Normally `byebug` stops before executing the first statement. +If instead you want it to start running initially and perhaps break it later in +the execution, use this option. +* **--require | -r**. Require the library before executing the script. However, +if the library happened to be `debug`, we'll just ignore the require since we're +already a debugger. This option is compatible with Ruby's. +* **--script **. Script to run before byebug's execution. +* **-x | --trace**. Turn on line tracing. Running `byebug --trace +.rb` is pretty much like running `ruby -rtracer +.rb`. If all you want to do however is get a linetrace, `tracer` is +most likely faster than `byebug` + +```bash +$ time ruby -rtracer old_doc/gcd.rb 24 31 >/dev/null + +real 0m0.066s +user 0m0.048s +sys 0m0.016s + +$ time byebug --trace old_doc/gcd.rb 24 31 >/dev/null + +real 0m0.660s +user 0m0.588s +sys 0m0.056s +``` + +### Byebug default options + +Byebug has many command-line options,; it seems that some people want to set +them differently from the defaults. For example, some people may want +`--no-quit` to be the default behavior. One could write a wrapper script or set +a shell alias to handle this. But `byebug` has another way to do it. Before +processing command options, if the file `$HOME/.byebugoptrc` is found, it is +loaded. If you want to set the defaults in some other way, you can put Ruby code +here and set variable `options` which is an OpenStruct. For example here's how +you'd set `-no-quit` and a personal message. + +```ruby +# This file contains how you want the default options to byebug to be set. Any +# Ruby code can be put here. +# +# byebug # Uncomment if you want to debug byebug! +options.control = false +puts "rocky's byebugrc run" +``` + +Here are the default values in `options` + +``` +# +``` + +### Command Files + +A command file is a file of lines that are `byebug` commands. Comments (lines +starting with `#`) may also be included. An empty line in a command file does +nothing; it does not mean to repeat the last command, as it would from the +terminal. + +When you start `byebug`, it automatically executes commands from its +_init file_, called `.byebugrc`. During startup, `byebug` does the following: + +* __Processes command line options and operands.__ Reads the init file in your +current directory, if any, and then checks your home directory. The home +directory is the directory named in the `$HOME` or `$HOMEPATH` environment +variable. Thus, you can have more than one init file, one generic in your home +directory, and another, specific to the program you are debugging, in the +directory where you invoke `byebug`. + +* __Reads command files specified by the `--script` option.__ + +You can also request the execution of a command file with the `source` command +(see [Source]()). + + +### Quitting byebug + +To exit `byebug`, use the `quit` command (abbreviated `q` and aliased `exit`). +Normally if you are in an interactive session, this command will prompt to ask +if you really want to quit. If you don't want any questions asked, enter +`quit unconditionally` (abbreviated `q!`). Another way to terminate byebug is to +use the `kill` command. This does the more forceful `kill -9`. It can be used in +cases where `quit` doesn't work (I haven't seen those yet). + + +### Calling byebug from inside your program + +Running a program from byebug adds a bit of overhead and slows it down a little. +Furthermore, by necessity, debuggers change the operation of the program they +are debugging. And this can lead to unexpected and unwanted differences. It has +happened so often that the term +[Heisenbugs](http://en.wikipedia.org/wiki/Heisenbug}) was coined to describe the +situation where using a debugger (among other possibilities) changes the +behavior of the program so that the bug doesn't manifest itself anymore. + +There is another way to get into byebug which adds no overhead or slowdown until +you reach the point at which you want to start debugging. However here you must +change the script and make an explicit call to byebug. Because byebug isn't +involved before the first call, there is no overhead and the script will run +at the same speed as if there were no byebug. + +To enter byebug this way, just drop `byebug` in whichever line you want to start +debugging at. You also have to require byebug somehow. If using bundler, it will +take care of that for you, otherwise you can use the ruby `-r` flag or add +`require 'byebug'` in the line previous to the `byebug` call. + +If speed is crucial, you may want to start and stop this around certain sections +of code, using `Byebug.start` and `Byebug.stop`. Alternatively, instead of +issuing an explicit `Byebug.stop` you can add a block to the `Byebug.start` and +debugging is turned on for that block. If the block of code raises an uncaught +exception that would cause the block to terminate, the `stop` will occur. See +[Byebug.start with a block](). + +When `byebug`is run, `.byebugrc` is read. + +You may want to enter byebug at several points in the program where there is a +problem you want to investigate. And since `byebug` is just a method call it's +possible to enclose it in a conditional expression, for example + +```ruby +byebug if 'bar' == foo and 20 == iter_count +``` + +### Restarting Byebug + +You can restart the program using `restart [program args]`. This is a re-exec - +all byebug state is lost. If command arguments are passed, those are used. +Otherwise program arguments from the last invocation are used. + +You won't be able to restart your program in all cases. First, the program +should have been invoked at the outset rather than having been called from +inside your program or invoked as a result of post-mortem handling. + +Also, since this relies on the OS `exec` call, this command is available only if +your OS supports `exec`. + + +## Byebug Command Reference + +### Command Syntax +Usually a command is put on a single line. There is no limit on how long it can be. +It starts with a command name, which is followed by arguments whose meaning depends +on the command name. For example, the command `step` accepts an argument which is the +number of times to step, as in `step 5`. You can also use the `step` command with no +arguments. Some commands do not allow any arguments. + +Multiple commands can be put on a line by separating each with a semicolon `;`. You +can disable the meaning of a semicolon to separate commands by escaping it with a +backslash. + +For example, if you have [autoeval]() set, which is the default, you might want to +enter the following code to compute the 5th Fibonacci number. + +```bash +(byebug) fib1=0; fib2=1; 5.times {|temp| temp=fib1; fib1=fib2; fib2 += temp } +0 +1 +SyntaxError Exception: /home/davidr/Proyectos/sample_app/trace.rb:1: syntax +error, unexpected end-of-input, expecting '}' + 5.times { |temp| temp=fib1 + ^ +nil +1 +SyntaxError Exception: /home/davidr/Proyectos/sample_app/trace.rb:1: syntax +error, unexpected tSTRING_DEND, expecting end-of-input + fib2 += temp } + ^ +nil +(byebug) fib1=0\; fib2=1\; 5.times {|temp| temp=fib1\; fib1=fib2\; fib2 += temp } +5 +(byebug) fib2 +8 +``` + +You might also consider using the [irb]() or [pry]() commands and then you won't have +to escape semicolons. + +A blank line as input (typing just ``) means to repeat the previous command. + +Byebug uses readline, which handles line editing and retrieval of previous commands. +Up arrow, for example, moves to the previous byebug command; down arrow moves to the +next more recent command (provided you are not already at the last command). Command +history is saved in file `.byebug_hist`. A limit is put on the history size. You +can see this with the `show history size` command. See [history]() for history +parameters. + +### Command Output +In the command-line interface, when `byebug` is waiting for input it presents a +prompt of the form `(byebug)`. If the program has terminated normally the prompt will +be `(byebug:ctrl)` and in post-mortem debugging it will be +`(byebug:post-mortem)`. + +Whenever `byebug` gives an error message such as for an invalid command or an invalid +location position, it will generally preface the message with `***`. + +### Command Help + +Once inside `byebug` you can always ask it for information on its commands using the +`help` command. You can use `help` (abbreviated `h`) with no arguments to display a +short list of named classes of commands + +```bash +(byebug) help +Type "help " for help on a specific command + +Available commands: +backtrace delete enable help method ps save step where +break disable eval info next putl set trace +catch display exit irb p quit show undisplay +condition down finish kill pp reload skip up +continue edit frame list pry restart source var +``` + +With a command name as `help` argument, `byebug` displays short information on how to +use that command. + +```bash +(byebug) help list +l[ist] list forward +l[ist] - list backward +l[ist] = list current line +l[ist] nn-mm list given lines +* NOTE - to turn on autolist, use 'set autolist' +(byebug) +``` + +A number of commands, namely `info`, `set`, `show`, `enable` and `disable`, have many +sub-parameters or _subcommands_. When you ask for help for one of these commands, you +will get help for all of the subcommands that command offers. Sometimes you may want +help only on a subcommand and to do this just follow the command with its subcommand +name. For example, `help info breakpoints`will just give help about the `info +breakpoints` command. Furthermore it will give longer help than the summary +information that appears when you ask for help. You don't need to list the full +subcommand name, just enough of the letters to make that subcommand distinct from +others will do. For example, `help info b` is the same as `help info breakpoints`. + +Some examples follow. + +```bash +(byebug) help info +info[ subcommand] + +Generic command for showing things about the program being debugged. + +-- +List of "info" subcommands: +-- +info args -- Argument variables of current stack frame +info breakpoints -- Status of user-settable breakpoints +info catch -- Exceptions that can be caught in the current stack +frame +info display -- Expressions to display when program stops +info file -- Info about a particular file read in +info files -- File names and timestamps of files read in +info global_variables -- Global variables +info instance_variables -- Instance variables of the current stack frame +info line -- Line number and file name of current position in +source file +info locals -- Local variables of the current stack frame +info program -- Execution status of the program +info stack -- Backtrace of the stack +info variables -- Local and instance variables of the current stack +frame +``` + +```bash +(byebug) help info breakpoints +Status of user-settable breakpoints. +Without argument, list info about all breakpoints. +With an integer argument, list info on that breakpoint. +``` + +```bash +(byebug) help info b +Status of user-settable breakpoints. +Without argument, list info about all breakpoints. +With an integer argument, list info on that breakpoint. +``` + +### Control Commands: quit, restart, source + +#### Quit + +To exit `byebug`, type `quit` (abbreviated `q` and aliased `exit`). Normally if +you are in an interactive session, this command will prompt you to confirm you +really want to quit. If you don't want any questions asked, enter +`quit unconditionally` (abbreviated `q!`). + +#### Restart + +To restart the program, use the `restart|r` command. This is a re-exec - all +`byebug` state is lost. If command arguments are passed, those are used. +Otherwise program arguments from the last invocation are used. + +You won't be able to restart your program in all cases. First, the program +should have been invoked at the outset rather than having been called from +inside your program or invoked as a result of post-mortem handling. + +#### Source + +You can run `byebug` commands inside a file, using the command `source `. +The lines in a command file are executed sequentially. They are not printed as +they are executed. If there is an error, execution proceeds to the next command +in the file. For information about command files that get run automatically on +startup see [Command Files](). + + +### Display Commands: display, undisplay + +#### Display + +If you find that you want to print the value of an expression frequently (to see +how it changes), you might want to add it to the *automatic display list** so +that `byebug` evaluates it each time your program stops or after a line is +printed if line tracing is enabled. Each expression added to the list is given a +number to identify it; to remove an expression from the list, you specify that +number. The automatic display looks like this: + +```bash +(byebug) display n +1: n = 3 +``` + +This display shows item numbers, expressions and their current values. If the +expression is undefined or illegal the expression will be printed but no value +will appear. + +```bash +(byebug) display undefined_variable +2: undefined_variable = +(byebug) display 1/0 +3: 1/0 = +``` + +If you use `display` with no argument, `byebug` will display the current values +of the expressions in the list, just as it is done when your program stops. +Using `info display` has the same effect. + +#### Undisplay + +To remove an item from the list, use `undisplay` followed by the number +identifying the expression you want to remove. `undisplay` does not repeat if +you press ``after using it (otherwise you would just get the error _No +display number n_) + +You can also temporarily disable or enable display expressions, so that the will +not be printed but they won't be forgotten either, so you can toggle them again +later. To do that, use `disable display` or `enable display` followed by the +expression number. + + +### Print Commands + +One way to examine and change data in your script is with the `eval` command +(abbreviated `p`). `byebug` by default evaluates any input that is not +recognized as a command, so in most situations `eval` is not necessary and +`byebug` will work like a REPL. One case where it's necessary could be when +trying to print a variable called `n`. In this case, you have no choice because +typing just `n` will execute `byebug`'s command `next`. + +A similar command to `eval|p` is `pp` which tries to pretty print the result. + +If the value you want to print is an array, sometimes a columnized list looks +nicer. Use `putl` for that. Notice however that entries are sorted to run down +first rather than across. If the value is not an array `putl` will just call +pretty-print. + +Sometimes you may want to print the array not only columnized, but sorted as +well. The list of byebug help commands appears this way, and so does the output +of the `method` commands. Use `ps` for that. If the value is not an array `ps` +will just call pretty-print. + +```bash +(byebug) Kernel.instance_methods +[:nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, +:dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, +:frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods, +:private_methods, :public_methods, :instance_variables, :instance_variable_get, +:instance_variable_set, :instance_variable_defined?, :remove_instance_variable, +:instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, +:extend, :display, :method, :public_method, :define_singleton_method, +:object_id, :to_enum, :enum_for, :gem, :pretty_inspect, :byebug] +(byebug) p Kernel.instance_methods +[:nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, +:dup, :taint, :tainted?, :untaint, :untrust, :untrusted?, :trust, :freeze, +:frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods, +:private_methods, :public_methods, :instance_variables, :instance_variable_get, +:instance_variable_set, :instance_variable_defined?, :remove_instance_variable, +:instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?, +:extend, :display, :method, :public_method, :define_singleton_method, +:object_id, :to_enum, :enum_for, :gem, :pretty_inspect, :byebug] +(byebug) pp Kernel.instance_methods +[:nil?, + :===, + :=~, + :!~, + :eql?, + :hash, + :<=>, + :class, + :singleton_class, + :clone, + :dup, + :taint, + :tainted?, + :untaint, + :untrust, + :untrusted?, + :trust, + :freeze, + :frozen?, + :to_s, + :inspect, + :methods, + :singleton_methods, + :protected_methods, + :private_methods, + :public_methods, + :instance_variables, + :instance_variable_get, + :instance_variable_set, + :instance_variable_defined?, + :remove_instance_variable, + :instance_of?, + :kind_of?, + :is_a?, + :tap, + :send, + :public_send, + :respond_to?, + :extend, + :display, + :method, + :public_method, + :define_singleton_method, + :object_id, + :to_enum, + :enum_for, + :gem, + :pretty_inspect, + :byebug] +(byebug) putl Kernel.instance_methods +nil? <=> tainted? frozen? private_methods remove_instance_variable public_send define_singleton_method byebug +=== class untaint to_s public_methods instance_of? respond_to? object_id +=~ singleton_class untrust inspect instance_variables kind_of? extend to_enum +!~ clone untrusted? methods instance_variable_get is_a? display enum_for +eql? dup trust singleton_methods instance_variable_set tap method gem +hash taint freeze protected_methods instance_variable_defined? send public_method pretty_inspect +(byebug) ps Kernel.instance_methods +!~ clone extend instance_of? kind_of? private_methods respond_to? tap untrusted? +<=> define_singleton_method freeze instance_variable_defined? method protected_methods send to_enum +=== display frozen? instance_variable_get methods public_method singleton_class to_s +=~ dup gem instance_variable_set nil? public_methods singleton_methods trust +byebug enum_for hash instance_variables object_id public_send taint untaint +class eql? inspect is_a? pretty_inspect remove_instance_variable tainted? untrust +``` + +Finally, if you need more advanced functionality from REPL's, you can enter +`irb` or `pry` using `irb` or `pry` commands. The bindings environment will be +set to the current state in the program. When you leave the repl and go back to +`byebug`'s command prompt we show the file, line and text position of the +program. If you issue a `list` without location information, the default +location used is the current line rather than the current position that may have +got updated via a prior `list` command. + +``` +$ byebug triangle.rb +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 1: # Compute the n'th triangle number, the hard way: triangle(n) == (n*(n+1))/2 +=> 2: def triangle(n) + 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: if __FILE__ == $0 +(byebug) irb +2.0.0-p247 :001 > (0..6).inject{|sum, i| sum +=i} + => 21 +2.0.0-p247 :002 > exit +/home/davidr/Proyectos/byebug/old_doc/triangle.rb @ 2 +def triangle(n) +(byebug) list # same line range as before going into irb +[1, 10] in /home/davidr/Proyectos/byebug/old_doc/triangle.rb + 1: # Compute the n'th triangle number, the hard way: triangle(n) == (n*(n+1))/2 +=> 2: def triangle(n) + 3: tri = 0 + 4: 0.upto(n) do |i| + 5: tri += i + 6: end + 7: tri + 8: end + 9: + 10: if __FILE__ == $0 +(byebug) +``` + +### Printing variables + +Byebug can print many different information about variables. Such as +* `var const `. Show the constants of ``. This is basically +listing variables and their values in `.constant`. +* `var instance `. Show the instance variables of ``. This is +basically listing `.instance_variables`. +* `info instance_variables`. Show instance_variables of `self`. +* `info locals`. Show local variables. +* `info globals`. Show global variables. +* `info variables`. Show local and instance variables of `self`. +* `method instance `. Show methods of ``. Basically this is the +same as running `ps .instance_methods(false)`. +* `method iv `. Show method instance variables of `object`. Basically +this is the same as running +``` + .instance_variables.each do |v| + puts "%s = %s\n" % [v, .instance_variable_get(v)] + end +``` +* `signature `. Show signature of method ``. _This command is +available only if the nodewrap gem is installed_. + +```ruby + def mymethod(a, b=5, &bock) + end + (byebug) method sig mymethod + Mine#mymethod(a, b=5, &bock) +``` + +* `method `. Show methods of the class or module +``. Basically this is the same as running +`ps .methods`. + +### Examining Program Source Files (`list`) + +`byebug` can print parts of your script's source. When your script stops, +`byebug` spontaneously lists the source code around the line where it stopped +that line. It does that when you change the current stack frame as well. +Implicitly there is a default line location. Each time a list command is run +that implicit location is updated, so that running several list commands in +succession shows a contiguous block of program text. + +If you don't need code context displayed every time, you can issue the `set +noautolist` command. Now whenever you want code listed, you can explicitly issue +the `list` command or its abbreviation `l`. Notice that when a second listing is +displayed, we continue listing from the place we last left off. When the +beginning or end of the file is reached, the line range to be shown is adjusted +so "it doesn't overflow". You can set the `noautolist` option by default by +dropping `set noautolist` in byebug's startup file `.byebugrc`. + +If you want to set how many lines to be printed by default rather than use the +initial number of lines, 10, use the `set listsize` command ([listsize()). To +see the entire program in one shot, give an explicit starting and ending line +number. You can print other portions of source files by giving explicit position +as a parameter to the list command. + +There are several ways to specify what part of the file you want to print. `list +nnn` prints lines centered around line number `nnn` in the current source file. +`l` prints more lines, following the last lines printed. `list -` prints lines +just before the lines last printed. `list nnn-mmm` prints lines between `nnn` +and `mmm` inclusive. `list =` prints lines centered around where the script is +stopped. Repeating a `list` command with `RET` discards the argument, so it is +equivalent to typing just `list`. This is more useful than listing the same +lines again. An exception is made for an argument of `-`: that argument is +preserved in repetition so that each repetition moves up in the source file. + +### Editing Source files (`edit`) + +To edit a source file, use the `edit` command. The editor of your choice is invoked +with the current line set to the active line in the program. Alternatively, you can +give a line specification to specify what part of the file you want to edit. + +You can customize `byebug` to use any editor you want by using the `EDITOR` +environment variable. The only restriction is that your editor (say `ex`) recognizes +the following command-line syntax: +``` +ex +nnn file +``` + +The optional numeric value `+nnn` specifies the line number in the file where +you want to start editing. For example, to configure `byebug` to use the `vi` editor, +you could use these commands with the `sh` shell: + +```bash +EDITOR=/usr/bin/vi +export EDITOR +byebug ... +``` + +or in the `csh` shell, +```bash +setenv EDITOR /usr/bin/vi +byebug ... +``` diff --git a/vendor/bundle/gems/byebug-2.7.0/Gemfile b/vendor/bundle/gems/byebug-2.7.0/Gemfile new file mode 100644 index 0000000..fa75df1 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gemspec diff --git a/vendor/bundle/gems/byebug-2.7.0/LICENSE b/vendor/bundle/gems/byebug-2.7.0/LICENSE new file mode 100644 index 0000000..84d0ba5 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/LICENSE @@ -0,0 +1,23 @@ +Copyright (C) 2013 David Rodríguez +All rights reserved. + * +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. diff --git a/vendor/bundle/gems/byebug-2.7.0/README.md b/vendor/bundle/gems/byebug-2.7.0/README.md new file mode 100644 index 0000000..e5ffed7 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/README.md @@ -0,0 +1,167 @@ +# Byebug +[![Version][VersionBadge]][VersionURL] +[![Build][TravisBadge]][TravisURL] +[![Climate][CodeClimateBadge]][CodeClimateURL] +[![Dependencies][GemnasiumBadge]][GemnasiumURL] +[![Coverage][CoverallsBadge]][CoverallsURL] +[![Gittip][GittipBadge]][GittipURL] + +_Debugging in Ruby 2_ + +Byebug is a simple to use, feature rich debugger for Ruby 2. It uses the new +TracePoint API for execution control and the new Debug Inspector API for call +stack navigation, so it doesn't depend on internal core sources. It's developed +as a C extension, so it's fast. And it has a full test suite so it's reliable. + +It allows you to see what is going on _inside_ a Ruby program while it executes +and can do four main kinds of things to help you catch bugs in the act: + +* Start your program or attach to it, specifying anything that might affect its +behavior. +* Make your program stop on specified conditions. +* Examine what has happened when your program has stopped. +* Change things in your program, so you can experiment with correcting the +effects of one bug and go on to learn about another. + + +## Install + + $ gem install byebug + + +## Usage + +Simply drop + + byebug + +wherever you want to start debugging and the execution will stop there. If you +are debugging rails, start the server and once the execution gets to your +`byebug` command you will get a debugging prompt. + +Former [debugger](https://github.com/cldwalker/debugger) or +[ruby-debug](https://github.com/mark-moseley/ruby-debug) users, notice: + +* Some gems (rails, rspec) implement debugging flags (-d, --debugger) that early +require and start the debugger. These flags are a performance penalty and Byebug +doesn't need them anymore so my recommendation is not to use them. +* The startup configuration file is now called `.byebugrc` instead of +`.rdebugrc`. + + +## What's different from debugger + +* Works on Ruby 2.x and it doesn't on 1.9.x. +* Has no MRI internal source code dependencies, just a clean API. +* Fixes all of debugger's open bugs in its issue tracker and provides some +enhancements, such as a markdown guide or the fact that `byebug` can now be +placed at the end of a block or method call. +* Actively mantained. +* Editor agnostic: no external editor built-in support. +* Pry command is built-in. No need of external gem like debugger-pry. + + +## Semantic Versioning + +Byebug tries to follow [semantic versioning](http://semver.org). Backwards +compatibility doesn't seem like a critic issue for a debugger because it's not +supposed to be used permanently by any program, let alone in production +environments. However, I still like the idea of giving some meaning to version +changes. + +Byebug's public API is determined by its set of commands + + Command | Aliases | Subcommands + ----------- |:------------ |:----------- + `backtrace` | `bt` `where` | + `break` | | + `catch` | | + `condition` | | + `continue` | | + `delete` | | + `disable` | | `breakpoints` `display` + `display` | | + `down` | | + `edit` | | + `enable` | | `breakpoints` `display` + `finish` | | + `frame` | | + `help` | | + `info` | | `args` `breakpoints` `catch` `display` `file` `files` `global_variables` `instance_variables` `line` `locals` `program` `stack` `variables` + `irb` | | + `kill` | | + `list` | | + `method` | | `instance` `iv` + `next` | | + `p` | `eval` | + `pp` | | + `pry` | | + `ps` | | + `putl` | | + `quit` | `exit` | + `reload` | | + `restart` | | + `save` | | + `set` | | `args` `autoeval` `autoirb` `autolist` `autoreload` `basename` `callstyle` `callstyle` `forcestep` `fullpath` `history` `linetrace` `linetrace_plus` `listsize` `post_mortem` `stack_on_error` `testing` `verbose` `width` + `show` | | `args` `autoeval` `autoirb` `autolist` `autoreload` `basename` `callstyle` `callstyle` `commands` `forcestep` `fullpath` `history` `linetrace` `linetrace_plus` `listsize` `post_mortem` `stack_on_error` `verbose` `width` + `skip` | | + `source` | | + `step` | | + `thread` | | `current` `list` `resume` `stop` `switch` + `trace` | | + `undisplay` | | + `up` | | + `var` | | `class` `constant` `global` `instance` `local` `ct` + + +## Getting Started + +Read [byebug's markdown +guide](https://github.com/deivid-rodriguez/byebug/blob/master/GUIDE.md) to get +started. Proper documentation will be eventually written. + + +## Related projects + +* [pry-byebug](https://github.com/deivid-rodriguez/pry-byebug) adds `next`, + `step`, `finish`, `continue` and `break` commands to pry using byebug. +* [ruby-debug-passenger](https://github.com/davejamesmiller/ruby-debug-passenger) +adds a rake task that restarts Passenger with byebug connected. +* [minitest-byebug](https://github.com/kaspth/minitest-byebug) starts a byebug +session on minitest failures. +* [sublime-debugger](https://github.com/shuky19/sublime_debugger) provides a plugin +for ruby debugging on Sublime Text. + + +## Future (possible) directions + +* JRuby support. +* Libify and test byebug's executable. +* Add printers support. + + +## Credits + +Everybody who has ever contributed to this forked and reforked piece of +software, specially: + +* Kent Sibilev and Mark Moseley, original authors of +[ruby-debug](https://github.com/mark-moseley/ruby-debug). +* Gabriel Horner, [debugger](https://github.com/cldwalker/debugger)'s mantainer. +* Koichi Sasada, author of the new C debugging API for Ruby. +* Dennis Ushakov, author of [debase](https://github.com/denofevil/debase), the +starting point of this. +* @kevjames3 for testing, bug reports and the interest in the project. + +[VersionBadge]: https://badge.fury.io/rb/byebug.png +[VersionURL]: http://badge.fury.io/rb/byebug +[TravisBadge]: https://travis-ci.org/deivid-rodriguez/byebug.png +[TravisURL]: http://travis-ci.org/deivid-rodriguez/byebug +[CodeClimateBadge]: https://codeclimate.com/github/deivid-rodriguez/byebug.png +[CodeClimateURL]: https://codeclimate.com/github/deivid-rodriguez/byebug +[GemnasiumBadge]: https://gemnasium.com/deivid-rodriguez/byebug.png +[GemnasiumURL]: https://gemnasium.com/deivid-rodriguez/byebug +[CoverallsBadge]: https://coveralls.io/repos/deivid-rodriguez/byebug/badge.png +[CoverallsURL]: https://coveralls.io/r/deivid-rodriguez/byebug +[GittipBadge]: http://img.shields.io/gittip/deivid-rodriguez.png +[GittipURL]: https://www.gittip.com/deivid-rodriguez diff --git a/vendor/bundle/gems/byebug-2.7.0/Rakefile b/vendor/bundle/gems/byebug-2.7.0/Rakefile new file mode 100644 index 0000000..b5b86c1 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/Rakefile @@ -0,0 +1,39 @@ +require 'rake/testtask' +require 'rake/extensiontask' +require 'bundler/gem_tasks' + +Rake::ExtensionTask.new('byebug') do |ext| + ext.lib_dir = 'lib/byebug' +end + +# Override default rake tests loader +class Rake::TestTask + def rake_loader + 'test/test_helper.rb' + end +end + +desc "Run MiniTest suite" +task :test do + Rake::TestTask.new do |t| + t.verbose = true + t.warning = true + t.pattern = 'test/*_test.rb' + end +end + +base_spec = eval(File.read('byebug.gemspec'), binding, 'byebug.gemspec') + +task :default => :test + +desc 'Run a test in looped mode so that you can look for memory leaks' +task 'test_loop' do + code = %Q[loop{ require '#{$*[1]}' }] + cmd = %Q[ruby -Itest -e "#{ code }"] + system cmd +end + +desc 'Watch memory use of a looping test' +task 'test_loop_mem' do + system "watch \"ps aux | grep -v 'sh -c r' | grep [I]test\"" +end diff --git a/vendor/bundle/gems/byebug-2.7.0/bin/byebug b/vendor/bundle/gems/byebug-2.7.0/bin/byebug new file mode 100755 index 0000000..829cffa --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/bin/byebug @@ -0,0 +1,251 @@ +#!/usr/bin/env ruby + +#=== Summary +# +#A command-line front-end to byebug +# +#Command invocation: +# +# byebug [options] [--] [script-options] ruby-script-to-debug +# byebug [options] [script-options] +# byebug [--version | --help] +# +#=== Options +# +#-d | --debug:: +# Set $DEBUG true. +# +#--help:: +# Show invocation help and exit. +# +#-I | --include path +# Add path to $LOAD_PATH. Like the ruby -I command, +# it supports multiple load paths separated by colons. +# +#--post-mortem:: +# Activate post-mortem mode. +# +#--no-quit:: +# Do not quit when script terminates. Instead rerun the program. +# +#--no-stop:: +# Do not stop when script is loaded. +# +#--nx:: +# Don’t execute commands found in any initialization files like +# .byebugrc. +# +#-r | --requirescript:: +# Require the library, before executing your script. +# +#--script=file:: +# Run script file file +# +#--v:: +# Print the version number, then turn on verbose mode if a script name is +# given. If no script name is given just exit after printing the version +# number. +# +#--verbose:: +# Turn on verbose mode. +# +#--version:: +# Show the version number and exit. +# +#-x | --trace:: +# Show lines before executing them. +# + +require 'optparse' +require 'ostruct' +require File.dirname(__FILE__) + "/../lib/byebug" + +def debug_program(options) + # Make sure Ruby script syntax checks okay. + output = `ruby -c "#{Byebug::PROG_SCRIPT}" 2>&1` + if $?.exitstatus != 0 + puts output + exit $?.exitstatus + end + if bt = Byebug.debug_load(Byebug::PROG_SCRIPT, options.stop) + p bt, bt.backtrace + end +end + +# Do a shell-like path lookup for prog_script and return the results. +# If we can't find anything return prog_script. +def whence_file(prog_script) + if prog_script.index(File::SEPARATOR) + # Don't search since this name has path separator components + return prog_script + end + for dirname in ENV['PATH'].split(File::PATH_SEPARATOR) do + prog_script_try = File.join(dirname, prog_script) + return prog_script_try if File.exist?(prog_script_try) + end + # Failure + return prog_script +end + +options = OpenStruct.new( + 'nx' => false, + 'post_mortem' => false, + 'quit' => true, + 'restart_script' => nil, + 'script' => nil, + 'server' => nil, + 'stop' => true, + 'tracing' => false, +) + +def process_options(options) + program = File.basename($0) + opts = OptionParser.new do |opts| + opts.banner = < -- +EOB + opts.separator "" + opts.separator "Options:" + + opts.on("-d", "--debug", "Set $DEBUG=true") { + $DEBUG = true } + opts.on('-I', '--include PATH', String, + 'Add PATH (single or multiple:path:list) to $LOAD_PATH.') { + |path| $LOAD_PATH.unshift(*path.split(':')) } + opts.on('--no-quit', 'Do not quit when script finishes') { + options.quit = false } + opts.on('--no-stop', 'Do not stop when script is loaded') { + options.stop = false } + opts.on('-nx', 'Don\'t run any byebug initialization files') { + options.nx = true } + opts.on('--post-mortem', 'Run byebug in post-mortem mode') { + options.post_mortem = true } + opts.on('-r', '--require SCRIPT', String, 'Require library before script') { + |name| if name == 'debug' + puts 'byebug not compatible with Ruby\'s \'debug\' lib, option ignored' + else + require name + end } + opts.on('-R', '--remote HOST[:PORT]', String, 'Specify byebug server spec') { + |server| host, port = server.split(':', 2) + host = 'localhost' if host.empty? + port = nil if port && port.empty? + port &&= port.to_i + options.server = [host, port].compact + } + opts.on('--restart-script FILE', String, + 'Name of the script file to run. Erased after read') do + |restart_script| + options.restart_script = restart_script + unless File.exist?(options.restart_script) + puts "Script file '#{options.restart_script}' is not found" + exit + end + end + opts.on('--script FILE', String, 'Name of the script file to run') do + |script| + options.script = script + unless File.exist?(options.script) + puts "Script file '#{options.script}' is not found" + exit + end + end + opts.on('-x', '--trace', 'Turn on line tracing') { + options.tracing = true } + + opts.separator '' + opts.separator 'Common options:' + opts.on_tail('--help', 'Show this message') do + puts opts + exit + end + opts.on_tail('--version', 'Print program version') do + puts "byebug #{Byebug::VERSION}" + exit + end + opts.on_tail('-v', 'Print version number, then turn on verbose mode') do + puts "byebug #{Byebug::VERSION}" + $VERBOSE = true + end + end + return opts +end + +# What file is used for byebug startup commands. +unless defined?(OPTS_INITFILE) + OPTS_INITFILE = '.byebugoptrc' + HOME_DIR = ENV['HOME'].to_s +end + +begin + initfile = File.join(HOME_DIR, OPTS_INITFILE) + eval(File.read(initfile)) if File.exist?(initfile) +rescue +end + +opts = process_options(options) + +begin + Byebug::ARGV = ARGV.clone if not defined? Byebug::ARGV + Byebug::BYEBUG_SCRIPT = File.expand_path(__FILE__) + Byebug::IGNORED_FILES << Byebug::BYEBUG_SCRIPT + Byebug::INITIAL_DIR = Dir.pwd + opts.parse! ARGV +rescue StandardError => e + puts opts + puts + puts e.message + exit(-1) +end + +if options.server + puts "Connecting to byebug server #{options.server.join(':')}" + Byebug.start_client(*options.server) + exit +end + +if ARGV.empty? + puts opts + puts + puts 'Must specify a script to run' + exit(-1) +end + +# save script name +prog_script = ARGV.shift +prog_script = whence_file(prog_script) unless File.exist?(prog_script) +Byebug::PROG_SCRIPT = File.expand_path prog_script + +# Set up trace hook for byebug +Byebug.start post_mortem: options.post_mortem + +# load initrc script (e.g. .byebugrc) +Byebug.run_init_script(StringIO.new) unless options.nx + +# run restore-settings startup script if specified +if options.restart_script + require 'fileutils' + Byebug.run_script(options.restart_script) + FileUtils.rm(options.restart_script) +end + +# run startup script if specified +if options.script + Byebug.run_script(options.script) +end + +options.stop = false if options.tracing +Byebug.tracing = options.tracing + +loop do + debug_program(options) + + break if options.quit + + interface = Byebug::LocalInterface.new + # Not sure if ControlCommandProcessor is really the right + # thing to use. CommandProcessor requires a state. + processor = Byebug::ControlCommandProcessor.new(interface) + processor.process_commands +end diff --git a/vendor/bundle/gems/byebug-2.7.0/byebug.gemspec b/vendor/bundle/gems/byebug-2.7.0/byebug.gemspec new file mode 100644 index 0000000..c0c5816 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/byebug.gemspec @@ -0,0 +1,34 @@ +require File.dirname(__FILE__) + '/lib/byebug/version' + +Gem::Specification.new do |s| + s.name = 'byebug' + s.version = Byebug::VERSION + s.authors = ['David Rodriguez', 'Kent Sibilev', 'Mark Moseley'] + s.email = 'deivid.rodriguez@mail.com' + s.license = 'BSD' + s.homepage = 'http://github.com/deivid-rodriguez/byebug' + s.summary = %q{Ruby 2.0 fast debugger - base + cli} + s.description = %q{Byebug is a Ruby 2 debugger. It's implemented using the + Ruby 2 TracePoint C API for execution control and the Debug Inspector C API + for call stack navigation. The core component provides support that + front-ends can build on. It provides breakpoint handling and bindings for + stack frames among other things and it comes with an easy to use command + line interface.} + + s.required_ruby_version = '>= 2.0.0' + + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- test/*`.split("\n") + s.executables = ['byebug'] + s.extra_rdoc_files = ['README.md'] + s.extensions = ['ext/byebug/extconf.rb'] + + s.add_dependency 'columnize', '~> 0.3' + s.add_dependency 'debugger-linecache', '~> 1.2' + + s.add_development_dependency 'rake', '~> 10.1' + s.add_development_dependency 'rake-compiler', '~> 0.9' + s.add_development_dependency 'mocha', '~> 1.0' + s.add_development_dependency 'minitest', '~> 5.2' + s.add_development_dependency 'coveralls', '~> 0.7' +end diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/.RUBYARCHDIR.time b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/.RUBYARCHDIR.time new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/Makefile b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/Makefile new file mode 100644 index 0000000..85cee7f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/Makefile @@ -0,0 +1,237 @@ + +SHELL = /bin/sh + +# V=0 quiet, V=1 verbose. other values don't work. +V = 0 +Q1 = $(V:1=) +Q = $(Q1:0=@) +ECHO1 = $(V:1=@:) +ECHO = $(ECHO1:0=@echo) + +#### Start of system configuration section. #### + +srcdir = . +topdir = /home/vagrant/.rbenv/versions/2.0.0-p481/include/ruby-2.0.0 +hdrdir = $(topdir) +arch_hdrdir = /home/vagrant/.rbenv/versions/2.0.0-p481/include/ruby-2.0.0/i686-linux +PATH_SEPARATOR = : +VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby +prefix = /home/vagrant/.rbenv/versions/2.0.0-p481 +rubysitearchprefix = $(rubylibprefix)/$(sitearch) +rubyarchprefix = $(rubylibprefix)/$(arch) +rubylibprefix = $(libdir)/$(RUBY_BASE_NAME) +exec_prefix = $(prefix) +vendorarchhdrdir = $(vendorhdrdir)/$(sitearch) +sitearchhdrdir = $(sitehdrdir)/$(sitearch) +rubyarchhdrdir = $(rubyhdrdir)/$(arch) +vendorhdrdir = $(rubyhdrdir)/vendor_ruby +sitehdrdir = $(rubyhdrdir)/site_ruby +rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME) +vendorarchdir = $(vendorlibdir)/$(sitearch) +vendorlibdir = $(vendordir)/$(ruby_version) +vendordir = $(rubylibprefix)/vendor_ruby +sitearchdir = ./.gem.20140731-3348-1hz26dy +sitelibdir = ./.gem.20140731-3348-1hz26dy +sitedir = $(rubylibprefix)/site_ruby +rubyarchdir = $(rubylibdir)/$(arch) +rubylibdir = $(rubylibprefix)/$(ruby_version) +sitearchincludedir = $(includedir)/$(sitearch) +archincludedir = $(includedir)/$(arch) +sitearchlibdir = $(libdir)/$(sitearch) +archlibdir = $(libdir)/$(arch) +ridir = $(datarootdir)/$(RI_BASE_NAME) +mandir = $(datarootdir)/man +localedir = $(datarootdir)/locale +libdir = $(exec_prefix)/lib +psdir = $(docdir) +pdfdir = $(docdir) +dvidir = $(docdir) +htmldir = $(docdir) +infodir = $(datarootdir)/info +docdir = $(datarootdir)/doc/$(PACKAGE) +oldincludedir = /usr/include +includedir = $(prefix)/include +localstatedir = $(prefix)/var +sharedstatedir = $(prefix)/com +sysconfdir = $(prefix)/etc +datadir = $(datarootdir) +datarootdir = $(prefix)/share +libexecdir = $(exec_prefix)/libexec +sbindir = $(exec_prefix)/sbin +bindir = $(exec_prefix)/bin +archdir = $(rubyarchdir) + + +CC = gcc +CXX = g++ +LIBRUBY = $(LIBRUBY_A) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir) +LIBRUBYARG_STATIC = -Wl,-R -Wl,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static +empty = +OUTFLAG = -o $(empty) +COUTFLAG = -o $(empty) + +RUBY_EXTCONF_H = +cflags = $(optflags) $(debugflags) $(warnflags) +optflags = -O3 -fno-fast-math +debugflags = -ggdb3 +warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration +CCDLFLAGS = -fPIC +CFLAGS = $(CCDLFLAGS) $(cflags) -Wall -Werror -Wno-unused-parameter $(ARCH_FLAG) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) +DEFS = -D_FILE_OFFSET_BITS=64 +CPPFLAGS = -I/home/vagrant/.rbenv/versions/2.0.0-p481/include $(DEFS) $(cppflags) +CXXFLAGS = $(CCDLFLAGS) $(cxxflags) $(ARCH_FLAG) +ldflags = -L. -L/home/vagrant/.rbenv/versions/2.0.0-p481/lib -fstack-protector -rdynamic -Wl,-export-dynamic +dldflags = +ARCH_FLAG = +DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG) +LDSHARED = $(CC) -shared +LDSHAREDXX = $(CXX) -shared +AR = ar +EXEEXT = + +RUBY_INSTALL_NAME = ruby +RUBY_SO_NAME = ruby +RUBYW_INSTALL_NAME = +RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version) +RUBYW_BASE_NAME = rubyw +RUBY_BASE_NAME = ruby + +arch = i686-linux +sitearch = $(arch) +ruby_version = 2.0.0 +ruby = $(bindir)/ruby +RUBY = $(ruby) +ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h + +RM = rm -f +RM_RF = $(RUBY) -run -e rm -- -rf +RMDIRS = rmdir --ignore-fail-on-non-empty -p +MAKEDIRS = /bin/mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp +TOUCH = exit > + +#### End of system configuration section. #### + +preload = + +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) -Wl,-R$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = +DISTCLEANDIRS = + +extout = +extout_prefix = +target_prefix = /byebug +LOCAL_LIBS = +LIBS = -lpthread -lrt -ldl -lcrypt -lm -lc +ORIG_SRCS = breakpoint.c byebug.c context.c locker.c threads.c +SRCS = $(ORIG_SRCS) +OBJS = breakpoint.o byebug.o context.o locker.o threads.o +HDRS = $(srcdir)/byebug.h +TARGET = byebug +TARGET_NAME = byebug +TARGET_ENTRY = Init_$(TARGET_NAME) +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +BINDIR = $(DESTDIR)$(bindir) +RUBYCOMMONDIR = $(DESTDIR)$(sitedir)$(target_prefix) +RUBYLIBDIR = $(DESTDIR)$(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(DESTDIR)$(sitearchdir)$(target_prefix) +HDRDIR = $(DESTDIR)$(rubyhdrdir)/ruby$(target_prefix) +ARCHHDRDIR = $(DESTDIR)$(rubyhdrdir)/$(arch)/ruby$(target_prefix) + +TARGET_SO = $(DLLIB) +CLEANLIBS = $(TARGET).so +CLEANOBJS = *.o *.bak + +all: $(DLLIB) +static: $(STATIC_LIB) +.PHONY: all install static install-so install-rb +.PHONY: clean clean-so clean-static clean-rb + +clean-static:: +clean-rb-default:: +clean-rb:: +clean-so:: +clean: clean-so clean-static clean-rb-default clean-rb + -$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time + +distclean-rb-default:: +distclean-rb:: +distclean-so:: +distclean-static:: +distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb + -$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + -$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + -$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true + +realclean: distclean +install: install-so install-rb + +install-so: $(DLLIB) ./.RUBYARCHDIR.time + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +clean-static:: + -$(Q)$(RM) $(STATIC_LIB) +install-rb: pre-install-rb install-rb-default +install-rb-default: pre-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +pre-install-rb-default: + $(ECHO) installing default byebug libraries +./.RUBYARCHDIR.time: + $(Q) $(MAKEDIRS) $(RUBYARCHDIR) + $(Q) $(TOUCH) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .mm .cxx .cpp .C .o + +.cc.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.mm.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.cxx.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.cpp.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.C.o: + $(ECHO) compiling $(<) + $(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $< + +.c.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $< + +.m.o: + $(ECHO) compiling $(<) + $(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $< + +$(DLLIB): $(OBJS) Makefile + $(ECHO) linking shared-object byebug/$(DLLIB) + -$(Q)$(RM) $(@) + $(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + + + +$(OBJS): $(HDRS) $(ruby_headers) diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.c b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.c new file mode 100644 index 0000000..055998e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.c @@ -0,0 +1,504 @@ +#include + +#ifdef _WIN32 +#include +#endif + +#if defined DOSISH +#define isdirsep(x) ((x) == '/' || (x) == '\\') +#else +#define isdirsep(x) ((x) == '/') +#endif + +static VALUE cBreakpoint; +static int breakpoint_max; + +static ID idEval; + +static VALUE +eval_expression(VALUE args) +{ + return rb_funcall2(rb_mKernel, idEval, 2, RARRAY_PTR(args)); +} + +/* + * call-seq: + * breakpoint.enabled? -> bool + * + * Returns +true+ if breakpoint is enabled, false otherwise. + */ +static VALUE +brkpt_enabled(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return breakpoint->enabled; +} + +/* + * call-seq: + * breakpoint.enabled = bool + * + * Enables or disables breakpoint. + */ +static VALUE +brkpt_set_enabled(VALUE self, VALUE bool) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return breakpoint->enabled = bool; +} + +/* + * call-seq: + * breakpoint.expr -> string + * + * Returns a conditional expression which indicates when this breakpoint should + * be activated. + */ +static VALUE +brkpt_expr(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return breakpoint->expr; +} + +/* + * call-seq: + * breakpoint.expr = string | nil + * + * Sets or unsets the conditional expression which indicates when this + * breakpoint should be activated. + */ +static VALUE +brkpt_set_expr(VALUE self, VALUE expr) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + breakpoint->expr = NIL_P(expr) ? expr: StringValue(expr); + return expr; +} + +/* + * call-seq: + * breakpoint.hit_condition -> symbol + * + * Returns the hit condition of the breakpoint: +nil+ if it is an + * unconditional breakpoint, or :greater_or_equal, :equal or :modulo otherwise + */ +static VALUE +brkpt_hit_condition(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + switch(breakpoint->hit_condition) + { + case HIT_COND_GE: + return ID2SYM(rb_intern("greater_or_equal")); + case HIT_COND_EQ: + return ID2SYM(rb_intern("equal")); + case HIT_COND_MOD: + return ID2SYM(rb_intern("modulo")); + case HIT_COND_NONE: + default: + return Qnil; + } +} + +/* + * call-seq: + * breakpoint.hit_condition = symbol + * + * Sets the hit condition of the breakpoint which must be one of the following + * values: + * + * +nil+ if it is an unconditional breakpoint, or + * :greater_or_equal(:ge), :equal(:eq), :modulo(:mod) + */ +static VALUE +brkpt_set_hit_condition(VALUE self, VALUE value) +{ + breakpoint_t *breakpoint; + ID id_value; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + id_value = rb_to_id(value); + + if(rb_intern("greater_or_equal") == id_value || rb_intern("ge") == id_value) + breakpoint->hit_condition = HIT_COND_GE; + else if(rb_intern("equal") == id_value || rb_intern("eq") == id_value) + breakpoint->hit_condition = HIT_COND_EQ; + else if(rb_intern("modulo") == id_value || rb_intern("mod") == id_value) + breakpoint->hit_condition = HIT_COND_MOD; + else + rb_raise(rb_eArgError, "Invalid condition parameter"); + return value; +} + +/* + * call-seq: + * breakpoint.hit_count -> int + * + * Returns the number of times this breakpoint has been hit. + */ +static VALUE +brkpt_hit_count(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return INT2FIX(breakpoint->hit_count); +} + +/* + * call-seq: + * breakpoint.hit_value -> int + * + * Returns the hit value of the breakpoint, namely, a value to build a + * condition on the number of hits of the breakpoint. + */ +static VALUE +brkpt_hit_value(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return INT2FIX(breakpoint->hit_value); +} + +/* + * call-seq: + * breakpoint.hit_value = int + * + * Sets the hit value of the breakpoint. This allows the user to set conditions + * on the number of hits to enable/disable the breakpoint. + */ +static VALUE +brkpt_set_hit_value(VALUE self, VALUE value) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + breakpoint->hit_value = FIX2INT(value); + return value; +} + +/* + * call-seq: + * breakpoint.id -> int + * + * Returns the id of the breakpoint. + */ +static VALUE +brkpt_id(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return INT2FIX(breakpoint->id); +} + +/* + * call-seq: + * breakpoint.pos -> string or int + * + * Returns the position of this breakpoint, either a method name or a line + * number. + */ +static VALUE +brkpt_pos(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + if (breakpoint->type == BP_METHOD_TYPE) + return rb_str_new2(rb_id2name(breakpoint->pos.mid)); + else + return INT2FIX(breakpoint->pos.line); +} + +/* + * call-seq: + * breakpoint.source -> string + * + * Returns the source file of the breakpoint. + */ +static VALUE +brkpt_source(VALUE self) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + return breakpoint->source; +} + +static void +mark_breakpoint(breakpoint_t *breakpoint) +{ + rb_gc_mark(breakpoint->source); + rb_gc_mark(breakpoint->expr); +} + +static VALUE +brkpt_create(VALUE klass) +{ + breakpoint_t *breakpoint = ALLOC(breakpoint_t); + + return Data_Wrap_Struct(klass, mark_breakpoint, xfree, breakpoint); +} + +static VALUE +brkpt_initialize(VALUE self, VALUE source, VALUE pos, VALUE expr) +{ + breakpoint_t *breakpoint; + + Data_Get_Struct(self, breakpoint_t, breakpoint); + + breakpoint->type = FIXNUM_P(pos) ? BP_POS_TYPE : BP_METHOD_TYPE; + if(breakpoint->type == BP_POS_TYPE) + breakpoint->pos.line = FIX2INT(pos); + else + breakpoint->pos.mid = SYM2ID(pos); + + breakpoint->id = ++breakpoint_max; + breakpoint->source = StringValue(source); + breakpoint->enabled = Qtrue; + breakpoint->expr = NIL_P(expr) ? expr : StringValue(expr); + breakpoint->hit_count = 0; + breakpoint->hit_value = 0; + breakpoint->hit_condition = HIT_COND_NONE; + + return Qnil; +} + +int +filename_cmp_impl(VALUE source, char *file) +{ + char *source_ptr, *file_ptr; + long s_len, f_len, min_len; + long s,f; + int dirsep_flag = 0; + + s_len = RSTRING_LEN(source); + f_len = strlen(file); + min_len = s_len < f_len ? s_len : f_len; + + source_ptr = RSTRING_PTR(source); + file_ptr = file; + + for( s = s_len - 1, f = f_len - 1; s >= s_len - min_len && f >= f_len - min_len; s--, f-- ) + { + if((source_ptr[s] == '.' || file_ptr[f] == '.') && dirsep_flag) + return 1; + if(isdirsep(source_ptr[s]) && isdirsep(file_ptr[f])) + dirsep_flag = 1; +#ifdef DOSISH_DRIVE_LETTER + else if (s == 0) + return(toupper(source_ptr[s]) == toupper(file_ptr[f])); +#endif + else if(source_ptr[s] != file_ptr[f]) + return 0; + } + return 1; +} + +int +filename_cmp(VALUE source, char *file) +{ +#ifdef _WIN32 + return filename_cmp_impl(source, file); +#else +#ifdef PATH_MAX + char path[PATH_MAX + 1]; + path[PATH_MAX] = 0; + return filename_cmp_impl(source, realpath(file, path) != NULL ? path : file); +#else + char *path; + int result; + path = realpath(file, NULL); + result = filename_cmp_impl(source, path == NULL ? file : path); + free(path); + return result; +#endif +#endif +} + +static int +check_breakpoint_by_hit_condition(VALUE breakpoint_object) +{ + breakpoint_t *breakpoint; + + if (breakpoint_object == Qnil) + return 0; + + Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint); + breakpoint->hit_count++; + + if (Qtrue != breakpoint->enabled) + return 0; + + switch (breakpoint->hit_condition) + { + case HIT_COND_NONE: + return 1; + case HIT_COND_GE: + { + if (breakpoint->hit_count >= breakpoint->hit_value) + return 1; + break; + } + case HIT_COND_EQ: + { + if (breakpoint->hit_count == breakpoint->hit_value) + return 1; + break; + } + case HIT_COND_MOD: + { + if (breakpoint->hit_count % breakpoint->hit_value == 0) + return 1; + break; + } + } + return 0; +} + +static int +check_breakpoint_by_pos(VALUE breakpoint_object, char *file, int line) +{ + breakpoint_t *breakpoint; + + if (breakpoint_object == Qnil) + return 0; + + Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint); + + if ( (Qtrue != breakpoint->enabled) || + (breakpoint->type != BP_POS_TYPE) || + (breakpoint->pos.line != line) ) + return 0; + + return filename_cmp(breakpoint->source, file); +} + +static int +check_breakpoint_by_method(VALUE breakpoint_object, VALUE klass, ID mid, + VALUE self) +{ + breakpoint_t *breakpoint; + + if (breakpoint_object == Qnil) + return 0; + + Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint); + + if ( (Qfalse == breakpoint->enabled) || + (breakpoint->type != BP_METHOD_TYPE) || + (breakpoint->pos.mid != mid) ) + return 0; + + if ( (classname_cmp(breakpoint->source, klass)) || + ((rb_type(self) == T_CLASS) && classname_cmp(breakpoint->source, self)) ) + return 1; + + return 0; +} + +static int +check_breakpoint_by_expr(VALUE breakpoint_object, VALUE binding) +{ + breakpoint_t *breakpoint; + VALUE args, expr_result; + + if (NIL_P(breakpoint_object)) + return 0; + + Data_Get_Struct(breakpoint_object, breakpoint_t, breakpoint); + + if (Qtrue != breakpoint->enabled) + return 0; + + if (NIL_P(breakpoint->expr)) + return 1; + + args = rb_ary_new3(2, breakpoint->expr, binding); + expr_result = rb_protect(eval_expression, args, 0); + + return RTEST(expr_result); +} + +extern VALUE +find_breakpoint_by_pos(VALUE breakpoints, VALUE source, VALUE pos, + VALUE binding) +{ + VALUE breakpoint_object; + char *file; + int line; + int i; + + file = RSTRING_PTR(source); + line = FIX2INT(pos); + for (i = 0; i < RARRAY_LENINT(breakpoints); i++) + { + breakpoint_object = rb_ary_entry(breakpoints, i); + if (check_breakpoint_by_pos(breakpoint_object, file, line) && + check_breakpoint_by_expr(breakpoint_object, binding) && + check_breakpoint_by_hit_condition(breakpoint_object)) + { + return breakpoint_object; + } + } + return Qnil; +} + +extern VALUE +find_breakpoint_by_method(VALUE breakpoints, VALUE klass, ID mid, VALUE binding, + VALUE self) +{ + VALUE breakpoint_object; + int i; + + for (i = 0; i < RARRAY_LENINT(breakpoints); i++) + { + breakpoint_object = rb_ary_entry(breakpoints, i); + if (check_breakpoint_by_method(breakpoint_object, klass, mid, self) && + check_breakpoint_by_expr(breakpoint_object, binding) && + check_breakpoint_by_hit_condition(breakpoint_object)) + { + return breakpoint_object; + } + } + return Qnil; +} + +void +Init_breakpoint(VALUE mByebug) +{ + breakpoint_max = 0; + + cBreakpoint = rb_define_class_under(mByebug, "Breakpoint", rb_cObject); + + rb_define_alloc_func(cBreakpoint, brkpt_create); + rb_define_method(cBreakpoint, "initialize", brkpt_initialize, 3); + + rb_define_method(cBreakpoint, "enabled?" , brkpt_enabled , 0); + rb_define_method(cBreakpoint, "enabled=" , brkpt_set_enabled , 1); + rb_define_method(cBreakpoint, "expr" , brkpt_expr , 0); + rb_define_method(cBreakpoint, "expr=" , brkpt_set_expr , 1); + rb_define_method(cBreakpoint, "hit_count" , brkpt_hit_count , 0); + rb_define_method(cBreakpoint, "hit_condition" , brkpt_hit_condition , 0); + rb_define_method(cBreakpoint, "hit_condition=", brkpt_set_hit_condition, 1); + rb_define_method(cBreakpoint, "hit_value" , brkpt_hit_value , 0); + rb_define_method(cBreakpoint, "hit_value=" , brkpt_set_hit_value , 1); + rb_define_method(cBreakpoint, "id" , brkpt_id , 0); + rb_define_method(cBreakpoint, "pos" , brkpt_pos , 0); + rb_define_method(cBreakpoint, "source" , brkpt_source , 0); + + idEval = rb_intern("eval"); +} diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.o b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/breakpoint.o new file mode 100644 index 0000000000000000000000000000000000000000..a0b1de84e4292809b560c86715730338e09d5fed GIT binary patch literal 113764 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 + +static VALUE mByebug; /* Ruby Byebug Module object */ + +static VALUE tracing = Qfalse; +static VALUE post_mortem = Qfalse; +static VALUE verbose = Qfalse; + +static VALUE catchpoints = Qnil; +static VALUE breakpoints = Qnil; +static VALUE tracepoints = Qnil; + +/* Implements thread syncronization, we must stop threads when debugging */ +VALUE locker = Qnil; + +/* Threads table */ +VALUE threads = Qnil; +VALUE cThreadsTable; + +#define IS_STARTED (catchpoints != Qnil) +static void +check_started() +{ + if (!IS_STARTED) + { + rb_raise(rb_eRuntimeError, "Byebug is not started yet."); + } +} + +static void +trace_print(rb_trace_arg_t *trace_arg, debug_context_t *dc) +{ + if (trace_arg) + { + int i = 0; + VALUE path = rb_tracearg_path(trace_arg); + VALUE line = rb_tracearg_lineno(trace_arg); + VALUE event = rb_tracearg_event(trace_arg); + VALUE mid = rb_tracearg_method_id(trace_arg); + for (i=0; icalced_stack_size; i++) putc('|', stderr); + fprintf(stderr, "[#%d] %s@%s:%d %s\n", dc->thnum, + rb_id2name(SYM2ID(event)), RSTRING_PTR(path), NUM2INT(line), + NIL_P(mid) ? "" : rb_id2name(SYM2ID(mid))); + } +} + +static void +cleanup(debug_context_t *dc) +{ + VALUE thread; + + dc->stop_reason = CTX_STOP_NONE; + + /* checks for dead threads */ + check_thread_contexts(); + + /* release a lock */ + locker = Qnil; + + /* let the next thread to run */ + thread = remove_from_locked(); + if (thread != Qnil) + rb_thread_run(thread); +} + +#define EVENT_SETUP \ + rb_trace_arg_t *trace_arg = rb_tracearg_from_tracepoint(trace_point); \ + debug_context_t *dc; \ + VALUE context; \ + thread_context_lookup(rb_thread_current(), &context); \ + Data_Get_Struct(context, debug_context_t, dc); \ + if (verbose == Qtrue) trace_print(trace_arg, dc); \ + +#define EVENT_COMMON if (!trace_common(trace_arg, dc)) { return; } + +static int +trace_common(rb_trace_arg_t *trace_arg, debug_context_t *dc) +{ + /* return if thread marked as 'ignored', like byebug's control thread */ + if (CTX_FL_TEST(dc, CTX_FL_IGNORE)) + { + cleanup(dc); + return 0; + } + + halt_while_other_thread_is_active(dc); + + /* Get the lock! */ + locker = rb_thread_current(); + + /* Many events per line, but only *one* breakpoint */ + if (dc->last_line != rb_tracearg_lineno(trace_arg) || + dc->last_file != rb_tracearg_path(trace_arg)) + { + CTX_FL_SET(dc, CTX_FL_ENABLE_BKPT); + } + + return 1; +} + +static void +save_current_position(debug_context_t *dc, VALUE file, VALUE line) +{ + dc->last_file = file; + dc->last_line = line; + CTX_FL_UNSET(dc, CTX_FL_ENABLE_BKPT); + CTX_FL_UNSET(dc, CTX_FL_FORCE_MOVE); +} + +/* Functions that return control to byebug after the different events */ + +static VALUE +call_at(VALUE context_obj, debug_context_t *dc, ID mid, int argc, VALUE a0, + VALUE a1) +{ + struct call_with_inspection_data cwi; + VALUE argv[2]; + + argv[0] = a0; + argv[1] = a1; + + cwi.dc = dc; + cwi.context_obj = context_obj; + cwi.id = mid; + cwi.argc = argc; + cwi.argv = &argv[0]; + + return call_with_debug_inspector(&cwi); +} + +static VALUE +call_at_line(VALUE context_obj, debug_context_t *dc, VALUE file, VALUE line) +{ + save_current_position(dc, file, line); + return call_at(context_obj, dc, rb_intern("at_line"), 2, file, line); +} + +static VALUE +call_at_tracing(VALUE context_obj, debug_context_t *dc, VALUE file, VALUE line) +{ + return call_at(context_obj, dc, rb_intern("at_tracing"), 2, file, line); +} + +static VALUE +call_at_breakpoint(VALUE context_obj, debug_context_t *dc, VALUE breakpoint) +{ + dc->stop_reason = CTX_STOP_BREAKPOINT; + return call_at(context_obj, dc, rb_intern("at_breakpoint"), 1, breakpoint, 0); +} + +static VALUE +call_at_catchpoint(VALUE context_obj, debug_context_t *dc, VALUE exp) +{ + dc->stop_reason = CTX_STOP_CATCHPOINT; + return call_at(context_obj, dc, rb_intern("at_catchpoint"), 1, exp, 0); +} + +static VALUE +call_at_return(VALUE context_obj, debug_context_t *dc, VALUE file, VALUE line) +{ + dc->stop_reason = CTX_STOP_BREAKPOINT; + return call_at(context_obj, dc, rb_intern("at_return"), 2, file, line); + +} + +static void +call_at_line_check(VALUE context_obj, debug_context_t *dc, + VALUE breakpoint, VALUE file, VALUE line) +{ + dc->stop_reason = CTX_STOP_STEP; + + if (breakpoint != Qnil) + call_at_breakpoint(context_obj, dc, breakpoint); + + reset_stepping_stop_points(dc); + call_at_line(context_obj, dc, file, line); +} + + +/* TracePoint API event handlers */ + +static void +line_event(VALUE trace_point, void *data) +{ + VALUE breakpoint, file, line, binding; + int moved = 0; + + EVENT_SETUP + + breakpoint = Qnil; + file = rb_tracearg_path(trace_arg); + line = rb_tracearg_lineno(trace_arg); + binding = rb_tracearg_binding(trace_arg); + + EVENT_COMMON + + if (dc->calced_stack_size == 0) dc->calced_stack_size++; + + if (dc->last_line != rb_tracearg_lineno(trace_arg) || + dc->last_file != rb_tracearg_path(trace_arg)) + { + moved = 1; + } + + if (RTEST(tracing)) + call_at_tracing(context, dc, file, line); + + if (moved || !CTX_FL_TEST(dc, CTX_FL_FORCE_MOVE)) + { + dc->steps = dc->steps <= 0 ? -1 : dc->steps - 1; + if (dc->calced_stack_size <= dc->dest_frame) + { + dc->lines = dc->lines <= 0 ? -1 : dc->lines - 1; + if (dc->calced_stack_size < dc->dest_frame) + { + dc->dest_frame = dc->calced_stack_size; + rb_funcall(mByebug, rb_intern("print"), 1, + rb_str_new2("Next went up a frame because previous frame finished\n")); + } + } + } + + if (dc->steps == 0 || dc->lines == 0 || + (CTX_FL_TEST(dc, CTX_FL_ENABLE_BKPT) && + (!NIL_P( + breakpoint = find_breakpoint_by_pos(breakpoints, file, line, binding))))) + { + call_at_line_check(context, dc, breakpoint, file, line); + } + + cleanup(dc); +} + +static void +call_event(VALUE trace_point, void *data) +{ + VALUE breakpoint, klass, mid, binding, self, file, line; + + EVENT_SETUP + + dc->calced_stack_size++; + + EVENT_COMMON + + breakpoint = Qnil; + klass = rb_tracearg_defined_class(trace_arg); + mid = SYM2ID(rb_tracearg_method_id(trace_arg)); + binding = rb_tracearg_binding(trace_arg); + self = rb_tracearg_self(trace_arg); + file = rb_tracearg_path(trace_arg); + line = rb_tracearg_lineno(trace_arg); + + breakpoint = find_breakpoint_by_method(breakpoints, klass, mid, binding, self); + if (breakpoint != Qnil) + { + call_at_breakpoint(context, dc, breakpoint); + call_at_line(context, dc, file, line); + } + + cleanup(dc); +} + +static void +return_event(VALUE trace_point, void *data) +{ + EVENT_SETUP + + if (dc->calced_stack_size > 0) dc->calced_stack_size--; + + EVENT_COMMON + + if (dc->calced_stack_size + 1 == dc->before_frame) + { + VALUE file, line; + + reset_stepping_stop_points(dc); + file = rb_tracearg_path(trace_arg); + line = rb_tracearg_lineno(trace_arg); + call_at_return(context, dc, file, line); + } + + if (dc->calced_stack_size + 1 == dc->after_frame) + { + reset_stepping_stop_points(dc); + dc->steps = 1; + } + + cleanup(dc); +} + +static void +c_call_event(VALUE trace_point, void *data) +{ + EVENT_SETUP + + dc->calced_stack_size++; + + EVENT_COMMON + + cleanup(dc); +} + +static void +c_return_event(VALUE trace_point, void *data) +{ + EVENT_SETUP + + if (dc->calced_stack_size > 0) dc->calced_stack_size--; + + EVENT_COMMON + + cleanup(dc); +} + +static void +raise_event(VALUE trace_point, void *data) +{ + VALUE expn_class, aclass; + VALUE err; + VALUE ancestors; + int i; + debug_context_t *new_dc; + VALUE binding, path, lineno; + + EVENT_SETUP + + err = rb_errinfo(); + + EVENT_COMMON + + binding = rb_tracearg_binding(trace_arg); + path = rb_tracearg_path(trace_arg); + lineno = rb_tracearg_lineno(trace_arg); + + if (post_mortem == Qtrue) + { + context = context_dup(dc); + rb_ivar_set(err, rb_intern("@__bb_file") , path); + rb_ivar_set(err, rb_intern("@__bb_line") , lineno); + rb_ivar_set(err, rb_intern("@__bb_binding"), binding); + rb_ivar_set(err, rb_intern("@__bb_context"), context); + + Data_Get_Struct(context, debug_context_t, new_dc); + rb_debug_inspector_open(context_backtrace_set, (void *)new_dc); + } + + expn_class = rb_obj_class(err); + + if (catchpoints == Qnil || dc->calced_stack_size == 0 || + CTX_FL_TEST(dc, CTX_FL_CATCHING) || + RHASH_TBL(catchpoints)->num_entries == 0) + { + cleanup(dc); + return; + } + + ancestors = rb_mod_ancestors(expn_class); + for (i = 0; i < RARRAY_LENINT(ancestors); i++) + { + VALUE mod_name; + VALUE hit_count; + + aclass = rb_ary_entry(ancestors, i); + mod_name = rb_mod_name(aclass); + hit_count = rb_hash_aref(catchpoints, mod_name); + + /* increment exception */ + if (hit_count != Qnil) + { + rb_hash_aset(catchpoints, mod_name, INT2FIX(FIX2INT(hit_count) + 1)); + call_at_catchpoint(context, dc, err); + call_at_line(context, dc, path, lineno); + break; + } + } + + cleanup(dc); +} + + +/* Setup TracePoint functionality */ + +static void +register_tracepoints(VALUE self) +{ + int i; + VALUE traces = tracepoints; + + if (NIL_P(traces)) + { + int line_msk = RUBY_EVENT_LINE; + int call_msk = RUBY_EVENT_CALL | RUBY_EVENT_B_CALL | RUBY_EVENT_CLASS; + int return_msk = RUBY_EVENT_RETURN | RUBY_EVENT_B_RETURN | RUBY_EVENT_END; + int c_call_msk = RUBY_EVENT_C_CALL; + int c_return_msk = RUBY_EVENT_C_RETURN; + int raise_msk = RUBY_EVENT_RAISE; + + VALUE tpLine = rb_tracepoint_new(Qnil, line_msk , line_event , 0); + VALUE tpCall = rb_tracepoint_new(Qnil, call_msk , call_event , 0); + VALUE tpReturn = rb_tracepoint_new(Qnil, return_msk , return_event , 0); + VALUE tpCCall = rb_tracepoint_new(Qnil, c_call_msk , c_call_event , 0); + VALUE tpCReturn = rb_tracepoint_new(Qnil, c_return_msk, c_return_event, 0); + VALUE tpRaise = rb_tracepoint_new(Qnil, raise_msk , raise_event , 0); + + traces = rb_ary_new(); + rb_ary_push(traces, tpLine); + rb_ary_push(traces, tpCall); + rb_ary_push(traces, tpReturn); + rb_ary_push(traces, tpCCall); + rb_ary_push(traces, tpCReturn); + rb_ary_push(traces, tpRaise); + + tracepoints = traces; + } + + for (i = 0; i < RARRAY_LENINT(traces); i++) + rb_tracepoint_enable(rb_ary_entry(traces, i)); +} + +static void +clear_tracepoints(VALUE self) +{ + int i; + + for (i = RARRAY_LENINT(tracepoints)-1; i >= 0; i--) + rb_tracepoint_disable(rb_ary_entry(tracepoints, i)); +} + + +/* Byebug's Public API */ + +/* + * call-seq: + * Byebug.contexts -> array + * + * Returns an array of all contexts. + */ +static VALUE +bb_contexts(VALUE self) +{ + volatile VALUE list; + volatile VALUE new_list; + VALUE context; + threads_table_t *t_tbl; + debug_context_t *dc; + int i; + + check_started(); + + new_list = rb_ary_new(); + list = rb_funcall(rb_cThread, rb_intern("list"), 0); + + for (i = 0; i < RARRAY_LENINT(list); i++) + { + VALUE thread = rb_ary_entry(list, i); + thread_context_lookup(thread, &context); + rb_ary_push(new_list, context); + } + + threads_clear(threads); + Data_Get_Struct(threads, threads_table_t, t_tbl); + + for (i = 0; i < RARRAY_LENINT(new_list); i++) + { + context = rb_ary_entry(new_list, i); + Data_Get_Struct(context, debug_context_t, dc); + st_insert(t_tbl->tbl, dc->thread, context); + } + + return new_list; +} + +/* + * call-seq: + * Byebug.thread_context(thread) -> context + * + * Returns context of the thread passed as an argument. + */ +static VALUE +bb_thread_context(VALUE self, VALUE thread) +{ + VALUE context; + + check_started(); + + thread_context_lookup(thread, &context); + + return context; +} + +/* + * call-seq: + * Byebug.current_context -> context + * + * Returns the current context. + * Note: Byebug.current_context.thread == Thread.current + */ +static VALUE +bb_current_context(VALUE self) +{ + VALUE context; + + check_started(); + + thread_context_lookup(rb_thread_current(), &context); + + return context; +} + +/* + * call-seq: + * Byebug.started? -> bool + * + * Returns +true+ byebug is started. + */ +static VALUE +bb_started(VALUE self) +{ + return IS_STARTED; +} + +/* + * call-seq: + * Byebug.stop -> bool + * + * This method disables byebug. It returns +true+ if byebug was already + * disabled, otherwise it returns +false+. + */ +static VALUE +bb_stop(VALUE self) +{ + if (IS_STARTED) + { + clear_tracepoints(self); + + breakpoints = Qnil; + catchpoints = Qnil; + threads = Qnil; + + return Qfalse; + } + return Qtrue; +} + +/* + * call-seq: + * Byebug.start_ -> bool + * Byebug.start_ { ... } -> bool + * + * This method is internal and activates the debugger. Use Byebug.start (from + * lib/byebug.rb) instead. + * + * The return value is the value of !Byebug.started? before issuing the + * +start+; That is, +true+ is returned, unless byebug was previously started. + * + * If a block is given, it starts byebug and yields to block. When the block + * is finished executing it stops the debugger with Byebug.stop method. + */ +static VALUE +bb_start(VALUE self) +{ + VALUE result; + + if (IS_STARTED) + result = Qfalse; + else + { + locker = Qnil; + breakpoints = rb_ary_new(); + catchpoints = rb_hash_new(); + threads = threads_create(); + + register_tracepoints(self); + result = Qtrue; + } + + if (rb_block_given_p()) + rb_ensure(rb_yield, self, bb_stop, self); + + return result; +} + +/* + * call-seq: + * Byebug.debug_load(file, stop = false) -> nil + * + * Same as Kernel#load but resets current context's frames. + * +stop+ parameter forces byebug to stop at the first line of code in +file+ + */ +static VALUE +bb_load(int argc, VALUE *argv, VALUE self) +{ + VALUE file, stop, context; + debug_context_t *dc; + VALUE status = Qnil; + int state = 0; + + if (rb_scan_args(argc, argv, "11", &file, &stop) == 1) + { + stop = Qfalse; + } + + bb_start(self); + + context = bb_current_context(self); + Data_Get_Struct(context, debug_context_t, dc); + + if (RTEST(stop)) dc->steps = 1; + + /* Initializing $0 to the script's path */ + ruby_script(RSTRING_PTR(file)); + rb_load_protect(file, 0, &state); + if (0 != state) + { + status = rb_errinfo(); + reset_stepping_stop_points(dc); + } + + /* We should run all at_exit handler's in order to provide, for instance, a + * chance to run all defined test cases */ + rb_exec_end_proc(); + + return status; +} + +/* + * call-seq: + * Byebug.verbose -> bool + * + * Returns +true+ if verbose output of TracePoint API events is enabled. + */ +static VALUE +bb_verbose(VALUE self) +{ + return verbose; +} + +/* + * call-seq: + * Byebug.verbose = bool + * + * Enable verbose output of every TracePoint API events, useful for debugging + * byebug. + */ +static VALUE +bb_set_verbose(VALUE self, VALUE value) +{ + verbose = RTEST(value) ? Qtrue : Qfalse; + return value; +} + +/* + * call-seq: + * Byebug.tracing -> bool + * + * Returns +true+ if global tracing is enabled. + */ +static VALUE +bb_tracing(VALUE self) +{ + return tracing; +} + +/* + * call-seq: + * Byebug.tracing = bool + * + * Sets the global tracing flag. + */ +static VALUE +bb_set_tracing(VALUE self, VALUE value) +{ + tracing = RTEST(value) ? Qtrue : Qfalse; + return value; +} + +/* + * call-seq: + * Byebug.post_mortem? -> bool + * + * Returns +true+ if post-moterm debugging is enabled. + */ +static VALUE +bb_post_mortem(VALUE self) +{ + return post_mortem; +} + +/* + * call-seq: + * Byebug.post_mortem = bool + * + * Sets post-moterm flag. + */ +static VALUE +bb_set_post_mortem(VALUE self, VALUE value) +{ + post_mortem = RTEST(value) ? Qtrue : Qfalse; + return value; +} + +/* + * call-seq: + * Byebug.breakpoints -> array + * + * Returns an array of breakpoints. + */ +static VALUE +bb_breakpoints(VALUE self) +{ + return breakpoints; +} + +/* + * call-seq: + * Byebug.catchpoints -> array + * + * Returns an array of catchpoints. + */ +static VALUE +bb_catchpoints(VALUE self) +{ + return catchpoints; +} + +/* + * call-seq: + * Byebug.add_catchpoint(exception) -> exception + * + * Adds a new exception to the catchpoints array. + */ +static VALUE +bb_add_catchpoint(VALUE self, VALUE value) +{ + if (TYPE(value) != T_STRING) + rb_raise(rb_eTypeError, "value of a catchpoint must be String"); + + rb_hash_aset(catchpoints, rb_str_dup(value), INT2FIX(0)); + return value; +} + +/* + * Document-class: Byebug + * + * == Summary + * + * This is a singleton class allows controlling byebug. Use it to start/stop + * byebug, set/remove breakpoints, etc. + */ +void +Init_byebug() +{ + mByebug = rb_define_module("Byebug"); + + rb_define_module_function(mByebug, "add_catchpoint" , bb_add_catchpoint , 1); + rb_define_module_function(mByebug, "breakpoints" , bb_breakpoints , 0); + rb_define_module_function(mByebug, "catchpoints" , bb_catchpoints , 0); + rb_define_module_function(mByebug, "contexts" , bb_contexts , 0); + rb_define_module_function(mByebug, "current_context", bb_current_context, 0); + rb_define_module_function(mByebug, "debug_load" , bb_load , -1); + rb_define_module_function(mByebug, "post_mortem?" , bb_post_mortem , 0); + rb_define_module_function(mByebug, "post_mortem=" , bb_set_post_mortem, 1); + rb_define_module_function(mByebug, "_start" , bb_start , 0); + rb_define_module_function(mByebug, "started?" , bb_started , 0); + rb_define_module_function(mByebug, "stop" , bb_stop , 0); + rb_define_module_function(mByebug, "thread_context" , bb_thread_context , 1); + rb_define_module_function(mByebug, "tracing?" , bb_tracing , 0); + rb_define_module_function(mByebug, "tracing=" , bb_set_tracing , 1); + rb_define_module_function(mByebug, "verbose" , bb_verbose , 0); + rb_define_module_function(mByebug, "verbose=" , bb_set_verbose , 1); + + cThreadsTable = rb_define_class_under(mByebug, "ThreadsTable", rb_cObject); + + Init_context(mByebug); + Init_breakpoint(mByebug); + + rb_global_variable(&breakpoints); + rb_global_variable(&catchpoints); + rb_global_variable(&tracepoints); + rb_global_variable(&threads); +} diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.h b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.h new file mode 100644 index 0000000..e7767ac --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.h @@ -0,0 +1,128 @@ +#ifndef BYEBUG +#define BYEBUG + +#include +#include + +/* flags */ +#define CTX_FL_CATCHING (1<<1) /* catching of exceptions enabled */ +#define CTX_FL_DEAD (1<<2) /* this context belonged to a dead thread */ +#define CTX_FL_ENABLE_BKPT (1<<3) /* cab check for breakpoints */ +#define CTX_FL_FORCE_MOVE (1<<4) /* don't stop unless we've changed line */ +#define CTX_FL_IGNORE (1<<5) /* this context belongs to ignored thread */ +#define CTX_FL_SUSPEND (1<<6) /* thread currently suspended */ +#define CTX_FL_TRACING (1<<7) /* call at_tracing method */ +#define CTX_FL_WAS_RUNNING (1<<8) /* thread was previously running */ + +/* macro functions */ +#define CTX_FL_TEST(c,f) ((c)->flags & (f)) +#define CTX_FL_SET(c,f) do { (c)->flags |= (f); } while (0) +#define CTX_FL_UNSET(c,f) do { (c)->flags &= ~(f); } while (0) + +/* types */ +typedef enum { + CTX_STOP_NONE, + CTX_STOP_STEP, + CTX_STOP_BREAKPOINT, + CTX_STOP_CATCHPOINT +} ctx_stop_reason; + +typedef struct { + int calced_stack_size; + int flags; + ctx_stop_reason stop_reason; + + VALUE thread; + int thnum; + + int dest_frame; + int lines; /* # of lines in dest_frame before stopping */ + int steps; /* # of steps before stopping */ + int after_frame; /* stop right after returning from this frame */ + int before_frame; /* stop right before returning from this frame */ + + VALUE last_file; + VALUE last_line; + + VALUE backtrace; /* [[loc, self, klass, binding], ...] */ +} debug_context_t; + +enum frame_component { LOCATION, SELF, CLASS, BINDING }; + +struct call_with_inspection_data { + debug_context_t *dc; + VALUE context_obj; + ID id; + int argc; + VALUE *argv; +}; + +typedef struct { + st_table *tbl; +} threads_table_t; + +/* functions from locker.c */ +extern int is_in_locked(VALUE thread_id); +extern void add_to_locked(VALUE thread); +extern VALUE remove_from_locked(); + +/* functions from threads.c */ +extern VALUE threads_create(void); +extern void threads_clear(VALUE table); +extern void check_thread_contexts(void); +extern void thread_context_lookup(VALUE thread, VALUE *context); +extern void halt_while_other_thread_is_active(debug_context_t *dc); + +/* global variables */ +extern VALUE locker; +extern VALUE threads; +extern VALUE cThreadsTable; + +/* functions */ +extern void Init_context(VALUE mByebug); +extern VALUE context_create(VALUE thread); +extern VALUE context_dup(debug_context_t *context); +extern void reset_stepping_stop_points(debug_context_t *context); +extern VALUE call_with_debug_inspector(struct call_with_inspection_data *data); +extern VALUE context_backtrace_set(const rb_debug_inspector_t *inspector, + void *data); + +static inline int +classname_cmp(VALUE name, VALUE klass) +{ + VALUE mod_name; + VALUE class_name = (Qnil == name) ? rb_str_new2("main") : name; + if (klass == Qnil) return(0); + mod_name = rb_mod_name(klass); + return (mod_name != Qnil && rb_str_cmp(class_name, mod_name) == 0); +} + +/* breakpoints & catchpoints */ +enum bp_type { BP_POS_TYPE, BP_METHOD_TYPE }; + +enum hit_condition { HIT_COND_NONE, HIT_COND_GE, HIT_COND_EQ, HIT_COND_MOD }; + +typedef struct { + int id; + enum bp_type type; + VALUE source; + union + { + int line; + ID mid; + } pos; + VALUE expr; + VALUE enabled; + int hit_count; + int hit_value; + enum hit_condition hit_condition; +} breakpoint_t; + +extern VALUE catchpoint_hit_count(VALUE catchpoints, VALUE exception, VALUE *exception_name); +extern VALUE find_breakpoint_by_pos(VALUE breakpoints, VALUE source, VALUE pos, + VALUE binding); +extern VALUE find_breakpoint_by_method(VALUE breakpoints, VALUE klass, + VALUE mid, VALUE binding, VALUE self); +extern void Init_breakpoint(VALUE mByebug); + +#endif diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.o b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/byebug.o new file mode 100644 index 0000000000000000000000000000000000000000..ecd14f6f35b245d820d363548e99e01366422981 GIT binary patch literal 148460 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

(ZhlUz)%mPW$^}&Ta~Gq|15_VfGL# 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%0AjNxHN3b!Rn%_Pab=#I|<;X%7(;H9$pgn#)=E}*! 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%0A_Y4DaJk95z$64hI zx*Rp99co?lQN$z9i&|E;j&lUfNgfv-7=$MumT5%wHYT}WPH2~YW=CsFlMDfCxn4}J z)upYiMrsc=s+V}GkToZXNCV2~U+U?b%B~y<((=5FJUc9lgn{NIU`uhstb|SGMtaB z@65|uZ?kgjD9g?cilioN#lk9rr%0oc2?eCELG`-r6yKfak7Vg=&Gcd=B-M7}G$})& znzBtV@q)@b2*EIaa%=D2z3P&UbOrjyOSk1|n&B)>an8KwY?a8NRQ~gzK|OJX<-eEx=6OJ>4_uhh1NmR-BK-RCm}k#X>9wXvJD-~ z_W-t^g%Xmppc|i;jKu$$J&2IZ2x(CfkP*X85>Z1|wpcUV`GpAv&fWI-2w$Xw9~1=_ zS>NE(ZrAnOHtZasKK6VSbW^mwv$>XH!u`5uJa4jFjPcaZBE>D zn4BZuIXY01yHx&kV>QC?I7>we#zn#uJ*9ezYL|4AqA_vKoEK1?&o)-47MrC@2g0>x zjZ-UXoi2_`m8V%FDbv|n>3s5^yLwqJ7``>ua$@Ry>j~xEsj16$PwMJ8TzGB2*jU@{ ze4Elp-OU=d`>fTqoXwh7S=0$k>Mt^&vB?kYi{ zx^h!WRClfx+gN9MOT!a$Zzv@R(sEHl%@M@ z+M_zjq;fY@m=>qmM#`x(D@M}SqBc#G(D7c>SPzY_ba%DS0&5QbscGFiXH70hvFWNw z)7S^I^NRiS`2;Lm<=w+Jcj^Qbw{cI3oq<6&m$v*yjNMmuE4FKyz1zlW^?`f?X-{_2 z_GBTKc4fQVHqDOXcWrGeBx>BB1-eq@O&JM@J)?A9q_kWi>p28#kSydor)Yt&RQZFf zETzg<0PrMZt!C;X+#(UA%%Ubj*A%m zl-WevHa`C_Ykdrc8!}GaK1IOX1sPau+mmfeVrLPMYdNeUG2?1mUi59Uye2RXg~Fr~SjW(zDHUgqAcFqMsn=yLsY|YiHa=vD1SSk)G*YNZ(gYHgQs3Z8CH}aT%6xz& zpf_mtc7d@(HIDpJcyV^e!r(ecP)?9VI%F;^Q{o8oR!elV0z)7SabFRs=<5D;!$Iig`^gS7R|TpDX6|$}r?= z6ZGVh1+{oXiaKGPp?7RQR-VQ!CA$C(If6`Mk*WYelQ`kSl9KJ&g8n&WZwBhi7}>{{ zBUd2LF(R_wT0g#WYH1DQM>cYPI|XWqhYU+}&Gk*3Vbo8raPh2B8k{tEhw2b6b3}}3 z{0YXVww`e5VAiH!|5rx#Ho#RpJGRVh`H3KYGr@Vsa+dmO|H<`))zEy^eA$}CoH#6R zu0NV;F&wc5=T=Cjny&WFp3~zqhMam)qsKx1nM*=qdt7N{b8~%@DvPz8c#_-sk(8AW zeo3rIm1GsoRQ2nLXgqi3lyb4TY&$sMaU>1mT_O46wm*MCWtT`DC%Ms^WBNePz)Wz)y*CY3jl`*e0Su_F*}!hIr6-GPnCSmAekoz>U8&5fq8D{ zk}yx77x5P)BAbGFO()+C0kgc$C0>>~FWhq_oTTEx-#u4dV6-s5ZSJ@ezW!+@1o6q3 zwlF*$)4R&uN~WbV3u@+?U()Wb#yp$oY|h2FXs)kVtSeWVHElX= zy(MT%l7$8d((9^B&??rwDq|1a4bJ)SnbVZ<@gN;AX{4>>m;3rbCk^ z2eToBqo%;qchM+#y369GNo2W6%t&)E&-DZDIACu7Xnkywy@oQcxlamx3Fu4LzQ67B z`GW~DXI(=h*rc94M{D`D?org?Lt5iscey_VmG>y@5=I7f((oonf?oiF%vp4w&NDj7 zAuM?sqo9vf!@%h+X^acnV<@aN-n|yFKh1zk5T?3@_CxZ9?Ol6vE%b? zV`p##bIK4M8B_G1&NCJdxm5nWG;&Dh$%B|1cb-8+3GqjIwduOT!O6)RiJd-(qcLfH zzk<=~m`XkAgL?SKmRZ{b`E76G`$!warA51~Xcvs9=r#G~`Q+teGlMfjV`JXId&rh# z(OZ9IArRoFASM{?#4NTI;b+XZp*xXOQAxh?-$HC}eIoJJ#{2@G+EK0)@n;~On@U{H zV>`HktNCK$zk?V9?&zN$lgIVb&4@n>@!&Yy@+ijqDu)2Yod4d4rw$ILh&N8)$FxZ1 z&p~XS$Re?M4l5@9Jj6${)Mw5@{*RZ>5+ps*$M*VJ^zly+r}eSDeinUv`Eoula8fqH zDR$ddSI1V3zQW#|)q7!{gJC_F-?FFrV6^G~iZbxFFO|c58@N1cjhR?koVS9nDJS(9 zx2*yDeiodLV-!M(_R&I_RE+2-{Lq5rNc797RQlI1ALIM?@S!&LcpUiZ!>{Tfb)Fsp zbl-y4WnnmMDYbm#^09Ko9qrET_ous+)~z+`v&*H*MW^EL^2On&`vv0`7OE36bcLE>i+M&-J1YKF^j<6S$65(>6z`mop;%Vo(?n3cG?aT zz~#O@9cG&C=^i`G%#vhTqJjiPKqLo=0*WGH7DWt*iXe(&0+l3)33-9{`>PY4aGyJ2 z7yZBQ=f5AAzNe~AojP^mb55PA(J8rHsUILvw&CPN@V*{5Hm%QFIcqRf52*Wj6iyna zXB}An#lFdd=N6b5S$I^6{EB_EhtD&o29e}Y?EW5pgs_3L3sX34$-rI0oey0jh5cCF0M(Et>s@UkIgE^v;}CX zx+nd7rS8x(wM+0nZ}L6Eohoi@a%;oou}|Tx!}^B~B5!hTc~j0_w^!CzJMxTWvSDSg z+12UZ)y)0dON$#iBG|S=op5}(r?YEMNADk}6zk82CPZQ9mu7^cX z%#4e%`z>z~lN??HaH7~lbA>VI731{O#4!*o?&R{fO4?ThsXR#Td*S+vXv6T64~GM!g!h0t{g*0w2F4<6~n1AHYXUP3FL%uHkO9N7T$7*1!my!b^L! z*>c!FA+vly6%sUXQqf&~fs@5eYm{3=-L*i}zys&Gb*@|{>D0MOAjUv|`7Nfla#lfb z`GSM^ppxQJz`mZqthmattSDkEO&ZA;7pX!KB1#G_L>GzBKnNRx7vSDC3RF;eN0FB) zh!R;O@-(1|WC=v7N=}9-W=1K+Vno_Teu+TmAu1BBfm|YvT}VqJNR$-B30V_i@|YqC z0*xsrQ*x9otD9`$k*I-BB1UtXB7qvHsTY$(=;i5hQs9PM2ag`b@7;J1FBCyommn9{@Jo_}|PsG#f*TKI2+F&6VWpmb7}R zJ7nvU)?lVGQcs+(UA?o4%~mHNkM${1c&w3nvl~N6&RDPWwT5rDq-voBCio~_bFEud(lVsAn-!u+Iax89Qba+{rzW(aS=^~2S0jm;AoJyn5dmiu zvyHmB_2Gtii!JAothIIc^4$#}j=abZyk-V^%zx(9k|0|UK0qpo>R z3W3sQKVEG2_x23-@T_~FR^t(PFRlstSN56D1y4CTGlz#Q`;yp?s{;HU4B#)IlNbNB zUY(k*?Ca-f))SA6%3(^~&8;{P=+@tDuCQ8`+9nl3^@4X1jRDNuQyaG zaIjxSkN&gHBW_z5CrAax%n>tkfQC)lrq_K%3hLUX%gvldmTsKRnqMCSCMvsaUw5Z( z9>+X3Pp5DB0FGJA#{zl~BHKV+Zi^6d&@cS!==QGt=v(dxx_bt2v(SYjfPt=FnyPbP z!gUVIicP1+)%Jx=)$i+=OC??$&|EPEKM0ZSynrH24O&Pvhwyy_8JFWU6Vxy8TRfy)7n2k(s0?4+h|8S0s=%o8`H_?yt zkU>^z+)3a^0>=s~d&R)-_mal!-f!Ltpzg*~Mdu(Ru&>s~*vJwmjo7sx7Y8*uES?bt zr9YL+jZ}!wYmn8rfXoJ*3(bB*Lu5Eg!#h=c?#OhcojBU#5A@V z>aoQpHkfruC`)_oxFM~~~Yjj^0 z75zQ=$*FU{Ca=z13APHw8u)V+N)|j-h3)~J-?}>Zh09I&jL9_I#w|rKKu2)UmdTLR z!qtU;N9lzbx=ek#dNa5t6|!3Snq`V*T}jW8{!oaz86s7=K3sCd+PPezi9p5rg>2SJ zAi76fM+_Y8lPNS*tYYJjQS$a=^Jc2uonw5VdPfDsA2dKpJ}ke+Ii#GG3qHtXGKoL1m z8^Rmk+>xP~dY50wEV8!ef9(pX^0b3$GO$+xd^e8&ydEX;kz4a=RApi`n)OV=)_oLNH4b? z*a19J(?vLH4k!hssZWoMaZ8~fU2|2Iua;7|rF=!Xa^RRQi+I=6dL?&9io|H%jqmTQ z5-l>LJ%QljS(1E90w0|ko*v>XOu2?Fe|rL-o*F;6 zFuOqOTcO{PVCcIB`pz_nsHqP6T`6d+%6BI~e+^jvo&@AA1B~hSCg6qnaW)C6@dFcJ zxC1cw_od*IM%r@qW&ROc)MLwcUsbM*y9nZ3X`x-*%8apFHx{jUm!_&*=8r$xf&!`C zm=Wg>ncK3<>@wpJ_jBAmNR-R1$hl*4c9!H@#KjjCkV{DSh^2g`Bb*WL3zw0g| z;|iqe3U%G2eqeffLfUd&1d#-A6s~_rS4W1pwKd^g_pk>tzJjiIh{^_zQMs-m*!cAD ze5Pxd>W|?moaz~^>ltIiQ-SV5PGe%203RHIbE6Z)z;JmV5}|sC=U~+g%nNyS1Tvuy zxei#~6M%^@*BEH#h;NvOTJqrRjAMPRC5P(M3%>m83_$M>g+I&ysw0NbrhJ#P&EQj` z^DH)c5v4bp^InX0!@0W`)5!IXD}8^SZs8d0HQ2<^6pm!a{M69lVAF{2>%Pw*redy- zlJ?kd@I=fT61wT(Tan1h?TpZw+1P4bu32;QVY%DA$gjpn@byx;*Yd|RQT3`m1CiMU z0Pgq831dO4&VWzab(~h_K@SiQ5!{$c+hMD&;coK4I(p=&OgDoM_aIjgG&g&IJvI}k zTRgzjEWjf?!23oe&m%p=)MWAvVaijdpSt}-b8YLwkD=K9iUWRbd$*Z2#+TzGR^k5 zp$-qZ5D}9@!?Wh+bV*h)dcdZ~ka`L)2j#mvD=dV>y4iH^(Xhoh$Fu4YhR!I)IWB5b zo_KlX^wtXY#4F2=d}Rs?MD6d3IlC#$k*?|iirGW3Fcp#W$_117bw_=|sE64@7Sb-s zgPNl}X_PvA)gn{Gcy)1mC*izi+a9(!oS!MH!f4q3#kpu_*Sup7d-SA_*Yfh!Q57(& zINmC)uPtu3U86T?7^Yzu^|&I&njYKoJc|g`HOzPn2WAqXYObyI>Ta9)><(*KeeKw1 zlMiZUTaopJDeQE)gTp`y8ISL-t?yvzwY!0J3>S^OS<)k&Q&y&_iqCL9*hWXP6{07c z!FBHOwROGP+QZ|cMc#}PS)je@-ZPZS8zzLB#2g?@;YU|}dDFn`?1pELVV(u#bbyT5 z#^(n@a@Me0eihIk7A;naZ4U{zY6jfVurivkI6R)UVOP*V7Z5uj&R8Lg7KKi>ohO^? z0~5E3gJe4E@oCt(;yf(arrA4_ECKZRq8!+i999ue2=oE)L|?C*R3?%~+2pE!O64aN zQy(CT6!J9EKeR<|fz|<@?qG^=GQy%vlx7H{M-JID2=L6ZuQC(12R+MW)co%u&kjT> z*bg}>h`9MNRzDo50*sB&a}r*G?74wV%nS&f_X`4qqdVjFyg(LU^x)?w+ydDP0-3lO z5V{ve**Ft3Za*5xpfVWyq#sMT1+o_fGI0xZKOVX1R>#=AIM6}nfRy@@gkL0lX&@BC zNcj_vk^m_-Hfe^J1-bx(-%pm!zEp-#^`VgwHsW(kChKd*m%KF|mb0bu%gYBx=MTuZti8!-?kg5dfJ0Z*YJ(Z~c@@vx6PJRroi$^!S{-!jOKG$E(j;?|yS2 z;FCcFZ*l2E$7ZIjHQwsdL&MW^w*P;dOXK2O)IaS~^9P3}C(UU7?G7+ufVzqJ4hI@O z;O5SEx+F&@V(>HNxfy4_Rn?E#QBLUC6ddN^gQG*yQ;LEP?Yn$V_CrekoJ-z1J~1(K zP=KFz0DXt{DE;mv?O%)jg6A+jYsz_#OY$kCbyrz_(LvDmw5$Gm9e{2ye8fuqB?n-+ zvbQPZ`DF)T+E%<4Q|hlc&{!Jws{uAjFHu>)=JPQ-nJRwWrR_t}0Kbs}OwA3M4t~>f z(MPYCyw9c8+}0q!<hOPm1uU;^T_!F7{Abg(h)4kYA z>;UeVV{B;TuwKBB`A;02(>douN3ah^*eD-7g8XTO(C-}RBPr0Fhkew;(DCT}%+R>? z>OYHwoHQG^k41j|Dd>KNWK)uz&C{ z1{P;?%K48D!XoNw{ZEn8%n^>DT^IOt1Rk7?z|T0~$iy@T?_%{?2Vi2*1F^}WIqP?y zi_jt44~z2i4klCbN8y49$Ul3Cwksa=1qVXib53tx^qeB#UmRebaY1htn=b{D(OW&_ zUmav@_>iBS{>=fxwE6Eo$M}@ZqW|HNoWNP~KV4GZ@x}hjF3Gxsg+J;4@@OtDY-0F| zOUpvuiTuAKz<08*M!@KlZS2100A`NwL0@;E$y>EQQZY|)FZz`{=(bS~a8R4BQP)II zbs*ae)zMkVd$%Wbkm<3JA?q+tbKse2H@!aHCqw!fK5eh`kl>jvJ?GD*B-FD!=+MIa zh#&ON_Mq{DLlg71jEnGx9CT!&&dP>slhOLjp%H7XANH69>jKY-scvO^u1n60&y1Sx zf5fNl;FQ(bEU-oRJcmewp6@_*d?}I__{TBU-FSN=5AAs9dK@o+lwj}V2z>7oumd}N zsAQ+>$qa%^0!K%~hP=<`-+ze1s^7_adjeCWqo+!*805LOue?^HjPY^N3c2JkU?MG z)qPa&brtq59GlN_z^>}Pz9OgCh*_T-8ne;$2FH?*On)3NvY&FmIf9*z)Q^piPMEIV z=%C@)erTSpv6ix_L!->ZMy$+l%91e}jdIGm`J1yy!)T71=ZT{-za@)jo=!ew-r9%@ zGT6XZ{s;1};%6O& zuI_9;eV0q?Ij0^(nf`ySGBTl)a?Cy^SV%A)`gsSb?%BV+$>;aGU8bOQWAqCSrd|4| zO^NSu!*cW}7G>ev{f3j9r&ew_vv^`_abxF({aeQw*EbNvbeo6G+c(tqV}!8pG?r0& zc;WV-aE`?X{xMGE@lK)&bg;@!&5zlkSDOxo6!VtAJuTw~Px*TgBHmuLJn+7_g&Z3l;*`zbODXc1v^+jH ztzc?$(ioGyrOL8P+7K>PIEoX}QngZLHI>9X1=FQcSF-)m)(!q{ubuU%cQYm-c zH8MIITB@vP(nsgUOO;a@5P3GT03+ITFyfyb(72Vrbs6KjV_z(v>P_-S0SS zlqy_COM}4{!5&MMDtBT!ICPjxOe^Z~_4=*c1Y^ITrsJGQ_xE$9GJZA-;21sJjdy5q z9pd6pJ?*)q&9H&qJ3D$C-iaP3-$r`g>=E_q!+F-+*IwOA7cm|MZI(XP3<4|lFlD7lH^Tg3`%?l;#4C@ z^X4M3=-*OSOGY{(nIuW!-&U@xBSnIr&ZI^0_A<|itUHFn-jRbqWq~c?XdM*fcYIfH z4JF85dWa2L0sbZpu>H^{(-1e1MfguSFk@NZ&v~$EtEPpf@_7$(r8;-zQLbK5d?8JN znd=ubX|escEL$17RQ^3z=TiAUauDVGN;;f=A4)?|-4AEd;`|~H ziG5VSm*#=)Q~u>1oSEuG|7wrWq^2~x8><05SIIZ|r24JWZ}Vx_O9gqShcKNe`Ex!Q zCqDt->w%g1j|<C=b$W)(;D)dje%v6ugiOQ>1K= zKN_KhbF9xEr_el$=Cf@16Opr>jmMLB)YtOK$~Sqp&RjW}p6DMB#pbJ2xt4z?=hrqsC$~0P(7=hA$Zz!I zQxoUQAWDK56Ro9fbqRL_7sI;>rA3#W(YtK!xAbqROrufB4Ct{jZ&BA(~SjttDx8aO)m(+fC)i5wM&_V}ja zyf4G$IizsO6Vuuxpb@@JcUM5a(1^Fqy%9|m?&olxxUz&B1zy>k>mzk5&1=~Ke2cwK zBb+SdZFgRnha4R$a_rf~Eut>l?PHWzyJs$kl~KLy zC7z{jjtzKGxn4>x^W}L@C2@{GQ*y9NsjsfDoLk)5sy^m+yxovyX0wk;S5@7eZg$w+ zY`a~d+HLBlF@tm5t=Mo04 zQ`isx9v@JP2R$julpvK+8Z`PD>#5;EAW z?lMBgkGQj$vg?Si7Gj{#c3R&HEl+Q`e@km)Beq=eE#>>vxp3b-&YtWJ{BN(U}i*=HW!!7W{sBI6+Ya|0WM#I=Q;Ocw!sKH+#q`of|VEAec~FS*r=rw*=7giYNM3 z4>_^3b0>Ko;FIf1Co$y%KumHDdh}UoB zfxy^}*r|rgnIe9FiWr}Y^l_+lFu`Qzwvu(?F97>Mxo);%#)0(jx{UKG@q+AK+^<~8$*~W8|Z#jK6Z2*If&2L7docNgcPj-&Woq zKI;6;M5&ooveeS^?F?1EzT_~;4)-C+xKZ*>l& ze7k>S$Y?#c%gx`3qV=B1gtX^urYhn{AKyN^c-r-St~u&mecJh@ zTr)bKNQ`1Zb#Yg{<(BFIF7R=@xr(=XImZ_?q&fc>upJz_b-X>xhE5x!wMK_7u`KF$ zMuXs-22&#%QRG8k4&9RdiVa^?;k2L%2n!SP2QebPtIrX5r*7<;-1pZWe5{?VK6Id? zdhJ;sgKW!Uka6Ej@Uak@S-+Q-6nqT+euUoKPzXNaO^+$vxF?OKzgkaLah;v3t3n6m zrj;tVuy#6+;`2CR4F^*uiz7i4FTq8qoyJvNqQdWmZoBO}PYldqUZPv;3Nf}@kzO+j z<-#V{G5dNp{U;y3i<&GSD?Po$v|IKv&pO z389hMSZOHLmFGAHvf@$`%0O3C3rD4YS62faT2W`=+R3T8Si4Wa7a9vB4hgerk0UbU zhYX_i^_vp+X@+!tYyB~`+ZifQ*b=vOzOm~@?iLgO`g+mua zAJeHdDOAsOOCx+t*X`ER9935{s!mZ!U?+$h=dI;Op4{0yzT#%Iz+Cf*LO>0HTlY8v z91!Ks=1CG!l0ZBxN{=(*QRD0eZQv}i#d*v)`vEP$!Q(64wH)U_d}uwvS?)&}XV=1k zvr{6kevGqkeQ};RzS7r|;~a=5*AtvLx3=`QaM^6@ioGAP^|$5w8ovm1@;WEGW!cuo zS)Ml?e0v0N>{KZ{Co^+0P*yg2QmL%#=KzQq48xfPzK*93ng>J65c(ex_sEsS#k>g- zm(g>#EnwMUnd|i**u?;aB6TaBhVMoUAJKD3aVCZCrxQ>t#c&&5!XSTAv@WbAU%T?)IPRIb1C2o6bsbg)~?P9~%ah#dL7cQeA{oTyYoNVpwk0GNz6K|JE$$)Kf z0^y~wxSbUVMKnmqQka%bC;U!|OJR`4(P3u*ybpx>51|HenzIcI-?n!;)L!{)!d4x+D!k?VM7cPhhc?hZr-f=S zo!p{)MRUmRR7nOguV`e!=C2!K$#hWjwYa z->Z~QaSwbngq*6MkQ|h4cj=f*AC%iQ{o-7xiLU8=D7y)ghzn{7xEMdTq4&KGQS2OR zTOk-iImHw;1xlc?$&wx(v=XJ`hCTAfM1v1=6TE0=$WEAcwE>OSos`4W1cVa11KP%Vjm*_OtwtPS9qmUEq%M&dvxuMa)(F3iK z-gk4t9M8Ml67Fsz>9L$)T*~rAFiU;hGG||Wwl;+*Ar~U+&}_YWOSRMWzaRxc4itF6 z?&o-2eb2;VxxXZ_(7EKYFY+K)*MEatwRp<;(by52^frw*wR;n^adKOTuo$ZOh|{uiVvTsVTYhUAdelAc*ODXE zSG)c@JFAtI^gosL-_`-GtfWt=tpBD?WhFK1CtpeW$%!~$F)l4&>=j)* zCQD;_XTu&}%R9ZPaBuAvYj}svo8l~ouMZaw%K|Pp$?molF+0hI?Ap`h)@t@CzBb7! z?;>ygl&ZP3eR_khhpiRaJ!*HJTexkyW3KPio@9%y9skyvZfOIX;_Y3)vR!MYqNY1T zHYEA&43bl&4#t*~oeddmw>oY84ikBtu054@0#*sg+!v15nQIf<)`^Raa(?6{{m7-u zae*x1LSJ+WtuJ+%WRfOwwDsjY9BYmvWQ80#4yUf-=vu<@Jr6$yMe+@o60JMO$Tg|h zCH>CVBduQcdAVS6FP)xgsmqxkQ$*vKB%6eHH4wS(_MEG1(CuvAQP&CE_R8sw4LaND#{FV4bEdZgWN5mcc~tTp z8y70&vaj5$-QW*firh-%$aIJ6$+SGuXeMpFOW*XI{4}l)fj!4zt}Ys#A)jS}A|Q2& z_tvWdHmif?xp)laGzTa0g!Q@ENDV8RTZo#D)WD{Aq^7Xc`Jy%f1F?D}L43ONe9{{QFT761;sz}24+?Q^ zL_PC94w>l{4wUAEar1q=QKNsnu(+{I5O=*}z-sh`_xbKJFXK`ck^rx+G@4E3Oe4!5 z##FL_A&xUwFG*fus$h7!v7Zd;IJf)i zCm#&#nc~L-pB5}8sZ(feXA^Txj`cI9npp61i>8fon08!^^&w17fAm8aa&!y@x3WY? zI%hQEbkv;ws;4+MA%mLVZ3LVOk(}$r`z!{=alCDKrNuPT2SJpx0gHAR9ib+RSw-W4S9RjLcUE~Q+c(& zN3I}xs!i2SHiX@`<*%t-leV*_O_7u;@27d))uuOY#iHh^mwiv=!Ma~MeP^li5PqE6 zJhM`&RQbgvTd8t2Jn?c`s_fAZ5nZEF4D?X@CD?V4>&~fEd6>I6DpjsOzO*U8Uc19n z2;`f;x25HQyuig$1Sb{FcIScLhmpG(^tccKW+jSEyG!vJmZ(Tc=%#h)W1Wur-H~GG zXtgaxAS0n7dmv0VI0YZTC_K(QW$x&A0dlvVhW?;Y+B?n^tsd|pH1-Hd)GZl@{{(RF zhcH2y+4!r<&=W+%szCS)q<*zPm>)Tq1xDMao6gq=ju`ps8uGP5Qm#WLQWS*XYPSrp z_XSHcglU8S8$!7PS+M|rDioU4Aec9X5`{T`fl$AttomCtI$EMv0j%C?AXQWxEMywc zw;5E`6f_lb3*1i|PPKGpMwJ%D_tG5pGm=q{gcbBNt>d3f5CxikSAuP(@1ILZE=B9_ zPO^DjINkq30uKraE%2TM6||D{Wa{{f2|m$`>kPwfMa@s1Up7TX#Ymg3O@1YX2!e!` z`PCFINRn-zUrSLWvRts0-e)!N(cn@8;R6vK+bF5Ib>iQR6wTV{_anunG}8xTu1qWa zNdyPoB=Vru4@Y!RPX_&wh)#5Kfp+?sQ)mp77n

5_pg#+Y+Bh2!bqGg1<=!5@{~j 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 literal 0 HcmV?d00001 diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.c b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.c new file mode 100644 index 0000000..4804fcd --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.c @@ -0,0 +1,660 @@ +#include + +static VALUE cContext; +static VALUE cDebugThread; +static int thnum_max = 0; + +/* "Step", "Next" and "Finish" do their work by saving information about where + * to stop next. reset_stepping_stop_points removes/resets this information. */ +extern void +reset_stepping_stop_points(debug_context_t *context) +{ + context->dest_frame = -1; + context->lines = -1; + context->steps = -1; + context->after_frame = -1; + context->before_frame = -1; +} + +/* + * call-seq: + * context.dead? -> bool + * + * Returns +true+ if context doesn't represent a live context and is created + * during post-mortem exception handling. + */ +static inline VALUE +Context_dead(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + return CTX_FL_TEST(context, CTX_FL_DEAD) ? Qtrue : Qfalse; +} + +static void +context_mark(void *data) +{ + debug_context_t *context = (debug_context_t *)data; + rb_gc_mark(context->backtrace); +} + +static void +context_free(void *data) +{ + +} + +static int +real_stack_size() +{ + return FIX2INT(rb_funcall(cContext, rb_intern("real_stack_size"), 0)); +} + +extern VALUE +context_create(VALUE thread) +{ + debug_context_t *context = ALLOC(debug_context_t); + + context->last_file = Qnil; + context->last_line = Qnil; + context->flags = 0; + context->calced_stack_size = real_stack_size(); + context->thnum = ++thnum_max; + context->thread = thread; + reset_stepping_stop_points(context); + context->stop_reason = CTX_STOP_NONE; + context->backtrace = Qnil; + + if (rb_obj_class(thread) == cDebugThread) CTX_FL_SET(context, CTX_FL_IGNORE); + + return Data_Wrap_Struct(cContext, context_mark, context_free, context); +} + +extern VALUE +context_dup(debug_context_t *context) +{ + debug_context_t *new_context = ALLOC(debug_context_t); + + memcpy(new_context, context, sizeof(debug_context_t)); + reset_stepping_stop_points(new_context); + new_context->backtrace = context->backtrace; + CTX_FL_SET(new_context, CTX_FL_DEAD); + + return Data_Wrap_Struct(cContext, context_mark, context_free, new_context); +} + +static VALUE +dc_backtrace(const debug_context_t *context) +{ + return context->backtrace; +} + +static VALUE +dc_frame_get(const debug_context_t *context, int frame_index, + enum frame_component type) +{ + VALUE frame; + + if (NIL_P(dc_backtrace(context))) + rb_raise(rb_eRuntimeError, "Backtrace information is not available"); + + if (frame_index >= RARRAY_LENINT(dc_backtrace(context))) + rb_raise(rb_eRuntimeError, "That frame doesn't exist!"); + + frame = rb_ary_entry(dc_backtrace(context), frame_index); + return rb_ary_entry(frame, type); +} + +static VALUE +dc_frame_location(const debug_context_t *context, int frame_index) +{ + return dc_frame_get(context, frame_index, LOCATION); +} + +static VALUE +dc_frame_self(const debug_context_t *context, int frame_index) +{ + return dc_frame_get(context, frame_index, SELF); +} + +static VALUE +dc_frame_class(const debug_context_t *context, int frame_index) +{ + return dc_frame_get(context, frame_index, CLASS); +} + +static VALUE +dc_frame_binding(const debug_context_t *context, int frame_index) +{ + return dc_frame_get(context, frame_index, BINDING); +} + +static VALUE +load_backtrace(const rb_debug_inspector_t *inspector) +{ + VALUE backtrace = rb_ary_new(); + VALUE locs = rb_debug_inspector_backtrace_locations(inspector); + int i; + + for (i=0; ibacktrace = load_backtrace(inspector); + + return Qnil; +} + +static VALUE +open_debug_inspector_i(const rb_debug_inspector_t *inspector, void *data) +{ + struct call_with_inspection_data *cwi = + (struct call_with_inspection_data *)data; + cwi->dc->backtrace = load_backtrace(inspector); + + return rb_funcall2(cwi->context_obj, cwi->id, cwi->argc, cwi->argv); +} + +static VALUE +open_debug_inspector(struct call_with_inspection_data *cwi) +{ + return rb_debug_inspector_open(open_debug_inspector_i, cwi); +} + +static VALUE +close_debug_inspector(struct call_with_inspection_data *cwi) +{ + cwi->dc->backtrace = Qnil; + return Qnil; +} + +extern VALUE +call_with_debug_inspector(struct call_with_inspection_data *data) +{ + return rb_ensure(open_debug_inspector, (VALUE)data, + close_debug_inspector, (VALUE)data); +} + +#define FRAME_SETUP \ + debug_context_t *context; \ + VALUE frame_no; \ + int frame_n, stack_size; \ + Data_Get_Struct(self, debug_context_t, context); \ + if (!rb_scan_args(argc, argv, "01", &frame_no)) \ + frame_n = 0; \ + else \ + frame_n = FIX2INT(frame_no); \ + stack_size = real_stack_size(); \ + if (frame_n < 0 || frame_n >= stack_size) \ + { \ + rb_raise(rb_eArgError, "Invalid frame number %d, stack (0...%d)", \ + frame_n, stack_size - 1); \ + } \ + +/* + * call-seq: + * context.frame_binding(frame_position=0) -> binding + * + * Returns frame's binding. + */ +static VALUE +Context_frame_binding(int argc, VALUE *argv, VALUE self) +{ + FRAME_SETUP + + return dc_frame_binding(context, frame_n); +} + +/* + * call-seq: + * context.frame_class(frame_position=0) -> binding + * + * Returns frame's defined class. + */ + static VALUE +Context_frame_class(int argc, VALUE *argv, VALUE self) +{ + FRAME_SETUP + + return dc_frame_class(context, frame_n); +} + +/* + * call-seq: + * context.frame_file(frame_position=0) -> string + * + * Returns the name of the file in the frame. + */ +static VALUE +Context_frame_file(int argc, VALUE *argv, VALUE self) +{ + VALUE loc; + + FRAME_SETUP + + loc = dc_frame_location(context, frame_n); + + return rb_funcall(loc, rb_intern("path"), 0); +} + +/* + * call-seq: + * context.frame_line(frame_position) -> int + * + * Returns the line number in the file. + */ +static VALUE +Context_frame_line(int argc, VALUE *argv, VALUE self) +{ + VALUE loc; + + FRAME_SETUP + + loc = dc_frame_location(context, frame_n); + + return rb_funcall(loc, rb_intern("lineno"), 0); +} + +/* + * call-seq: + * context.frame_method(frame_position=0) -> sym + * + * Returns the sym of the called method. + */ +static VALUE +Context_frame_method(int argc, VALUE *argv, VALUE self) +{ + VALUE loc; + + FRAME_SETUP + + loc = dc_frame_location(context, frame_n); + + return rb_str_intern(rb_funcall(loc, rb_intern("label"), 0)); +} + +/* + * call-seq: + * context.frame_self(frame_postion=0) -> obj + * + * Returns self object of the frame. + */ +static VALUE +Context_frame_self(int argc, VALUE *argv, VALUE self) +{ + FRAME_SETUP + + return dc_frame_self(context, frame_n); +} + +/* + * call-seq: + * context.ignored? -> bool + * + * Returns the ignore flag for the context, which marks whether the associated + * thread is ignored while debugging. + */ +static inline VALUE +Context_ignored(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + return CTX_FL_TEST(context, CTX_FL_IGNORE) ? Qtrue : Qfalse; +} + +static void +context_resume_0(debug_context_t *context) +{ + if (!CTX_FL_TEST(context, CTX_FL_SUSPEND)) return; + + CTX_FL_UNSET(context, CTX_FL_SUSPEND); + + if (CTX_FL_TEST(context, CTX_FL_WAS_RUNNING)) + rb_thread_wakeup(context->thread); +} + +/* + * call-seq: + * context.resume -> nil + * + * Resumes thread from the suspended mode. + */ +static VALUE +Context_resume(VALUE self) +{ + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + + if (!CTX_FL_TEST(context, CTX_FL_SUSPEND)) + rb_raise(rb_eRuntimeError, "Thread is not suspended."); + + context_resume_0(context); + + return Qnil; +} + +/* + * call-seq: + * context.calced_stack_size-> int + * + * Returns the calculated size of the context stack. + * + * NOTE: it shouldn't be necessary to expose this, this is only done to ease + * the detection of TracePoint API bugs. + */ +static inline VALUE +Context_calced_stack_size(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + + return INT2FIX(context->calced_stack_size); +} + +static VALUE +Context_stop_reason(VALUE self) +{ + debug_context_t *context; + const char *symbol; + + Data_Get_Struct(self, debug_context_t, context); + + if (CTX_FL_TEST(context, CTX_FL_DEAD)) + symbol = "post-mortem"; + else switch (context->stop_reason) + { + case CTX_STOP_STEP: + symbol = "step"; + break; + case CTX_STOP_BREAKPOINT: + symbol = "breakpoint"; + break; + case CTX_STOP_CATCHPOINT: + symbol = "catchpoint"; + break; + case CTX_STOP_NONE: + default: + symbol = "none"; + } + return ID2SYM(rb_intern(symbol)); +} + +/* + * call-seq: + * context.step_into(steps, force = false) + * + * Stops the current context after a number of +steps+ are made. + * +force+ parameter (if true) ensures that the cursor moves away from the + * current line. + */ +static VALUE +Context_step_into(int argc, VALUE *argv, VALUE self) +{ + VALUE steps; + VALUE force; + debug_context_t *context; + + rb_scan_args(argc, argv, "11", &steps, &force); + if (FIX2INT(steps) < 0) + rb_raise(rb_eRuntimeError, "Steps argument can't be negative."); + + Data_Get_Struct(self, debug_context_t, context); + context->steps = FIX2INT(steps); + + if (RTEST(force)) + CTX_FL_SET(context, CTX_FL_FORCE_MOVE); + else + CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE); + + return steps; +} + +/* + * call-seq: + * context.step_out(frame) + * + * Stops after frame number +frame+ is activated. Implements +finish+ and + * +next+ commands. + */ +static VALUE +Context_step_out(VALUE self, VALUE frame) +{ + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + + if (FIX2INT(frame) < 0 || FIX2INT(frame) >= context->calced_stack_size) + rb_raise(rb_eRuntimeError, "Stop frame is out of range."); + + context->after_frame = context->calced_stack_size - FIX2INT(frame); + + return frame; +} + +/* + * call-seq: + * context.step_over(lines, frame = nil, force = false) + * + * Steps over +lines+ lines. + * Make step over operation on +frame+, by default the current frame. + * +force+ parameter (if true) ensures that the cursor moves away from the + * current line. + */ +static VALUE +Context_step_over(int argc, VALUE *argv, VALUE self) +{ + VALUE lines, frame, force; + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + + if (context->calced_stack_size == 0) + rb_raise(rb_eRuntimeError, "No frames collected."); + + rb_scan_args(argc, argv, "12", &lines, &frame, &force); + if (FIX2INT(frame) < 0 || FIX2INT(frame) >= context->calced_stack_size) + rb_raise(rb_eRuntimeError, "Destination frame is out of range."); + + context->lines = FIX2INT(lines); + context->dest_frame = context->calced_stack_size - FIX2INT(frame); + + if (RTEST(force)) + CTX_FL_SET(context, CTX_FL_FORCE_MOVE); + else + CTX_FL_UNSET(context, CTX_FL_FORCE_MOVE); + + return Qnil; +} + +/* + * call-seq: + * context.stop_return(frame) + * + * Stops before frame number +frame+ is activated. Useful when you enter the + * debugger after the last statement in a method. + */ +static VALUE +Context_stop_return(VALUE self, VALUE frame) +{ + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + if (FIX2INT(frame) < 0 || FIX2INT(frame) >= context->calced_stack_size) + rb_raise(rb_eRuntimeError, "Stop frame is out of range."); + + context->before_frame = context->calced_stack_size - FIX2INT(frame); + + return frame; +} + +static void +context_suspend_0(debug_context_t *context) +{ + VALUE status = rb_funcall(context->thread, rb_intern("status"), 0); + + if (rb_str_cmp(status, rb_str_new2("run")) == 0) + CTX_FL_SET(context, CTX_FL_WAS_RUNNING); + else if (rb_str_cmp(status, rb_str_new2("sleep")) == 0) + CTX_FL_UNSET(context, CTX_FL_WAS_RUNNING); + else + return; + + CTX_FL_SET(context, CTX_FL_SUSPEND); +} + +/* + * call-seq: + * context.suspend -> nil + * + * Suspends the thread when it is running. + */ +static VALUE +Context_suspend(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + + if (CTX_FL_TEST(context, CTX_FL_SUSPEND)) + rb_raise(rb_eRuntimeError, "Already suspended."); + + context_suspend_0(context); + return Qnil; +} + +/* + * call-seq: + * context.suspended? -> bool + * + * Returns +true+ if the thread is suspended by debugger. + */ +static VALUE +Context_is_suspended(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + + return CTX_FL_TEST(context, CTX_FL_SUSPEND) ? Qtrue : Qfalse; +} + +/* + * call-seq: + * context.thnum -> int + * + * Returns the context's number. + */ +static inline VALUE +Context_thnum(VALUE self) { + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + return INT2FIX(context->thnum); +} + +/* + * call-seq: + * context.thread -> thread + * + * Returns the thread this context is associated with. + */ +static inline VALUE +Context_thread(VALUE self) +{ + debug_context_t *context; + Data_Get_Struct(self, debug_context_t, context); + return context->thread; +} + +/* + * call-seq: + * context.tracing -> bool + * + * Returns the tracing flag for the current context. + */ +static VALUE +Context_tracing(VALUE self) +{ + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + return CTX_FL_TEST(context, CTX_FL_TRACING) ? Qtrue : Qfalse; +} + +/* + * call-seq: + * context.tracing = bool + * + * Controls the tracing for this context. + */ +static VALUE +Context_set_tracing(VALUE self, VALUE value) +{ + debug_context_t *context; + + Data_Get_Struct(self, debug_context_t, context); + + if (RTEST(value)) + CTX_FL_SET(context, CTX_FL_TRACING); + else + CTX_FL_UNSET(context, CTX_FL_TRACING); + return value; +} + + +/* :nodoc: */ +static VALUE +DebugThread_inherited(VALUE klass) +{ + rb_raise(rb_eRuntimeError, "Can't inherit Byebug::DebugThread class"); +} + +/* + * Document-class: Context + * + * == Summary + * + * Byebug keeps a single instance of this class. + */ +void +Init_context(VALUE mByebug) +{ + cContext = rb_define_class_under(mByebug, "Context", rb_cObject); + + rb_define_method(cContext, "dead?" , Context_dead , 0); + rb_define_method(cContext, "frame_binding" , Context_frame_binding , -1); + rb_define_method(cContext, "frame_class" , Context_frame_class , -1); + rb_define_method(cContext, "frame_file" , Context_frame_file , -1); + rb_define_method(cContext, "frame_line" , Context_frame_line , -1); + rb_define_method(cContext, "frame_method" , Context_frame_method , -1); + rb_define_method(cContext, "frame_self" , Context_frame_self , -1); + rb_define_method(cContext, "ignored?" , Context_ignored , 0); + rb_define_method(cContext, "resume" , Context_resume , 0); + rb_define_method(cContext, "calced_stack_size", Context_calced_stack_size, 0); + rb_define_method(cContext, "step_into" , Context_step_into , -1); + rb_define_method(cContext, "step_out" , Context_step_out , 1); + rb_define_method(cContext, "step_over" , Context_step_over , -1); + rb_define_method(cContext, "stop_return" , Context_stop_return , 1); + rb_define_method(cContext, "stop_reason" , Context_stop_reason , 0); + rb_define_method(cContext, "suspend" , Context_suspend , 0); + rb_define_method(cContext, "suspended?" , Context_is_suspended , 0); + rb_define_method(cContext, "thnum" , Context_thnum , 0); + rb_define_method(cContext, "thread" , Context_thread , 0); + rb_define_method(cContext, "tracing" , Context_tracing , 0); + rb_define_method(cContext, "tracing=" , Context_set_tracing , 1); + + cDebugThread = rb_define_class_under(mByebug, "DebugThread", rb_cThread); + rb_define_singleton_method(cDebugThread, "inherited", DebugThread_inherited, 1); +} diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.o b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/context.o new file mode 100644 index 0000000000000000000000000000000000000000..6d641ecc16faa3aa9d4837353b69eee98f6db1fd GIT binary patch literal 128892 zcmeFa34EPZwKx1c=bVHS8fZuh6e)0M3nY-XIZ2wPbj)xv&@_n|Ixu)hlanTrCNV=> z<{={HhAM*tPKe@!f{LP|IDjC7GwO@_>b>H?1r-%RMZw|y|JU04d7g7}PAS8^-*?~d z>#rw!@3q!md+oK?p7*o&rHR%?*L5BH&vn9%A99?hZqrbe5R^D4IEw{;sEP2*z5DMt zng0D>JcZ6|!?MV%^T4L^2m*KV&%OIUON7C9J@NN{{p(+s-x~sG`pHH6r-_?kB=OBU zGm&LNV%SbUxp?O6WkrElGZ!seG<(sq*v#azg|m~(mOX&Tg=Df$BhEGzJ$wK2NMyDn zGPUTkUtBuV5t#*xnWqqI5n?QyzHjlpmwo-R-~Q+RJ&=L?7Y6xH3RTSGTV?n*7J&_u zTr|5W0v`7~kw5)tC?o$bkzXNY+CO>nOO>Yx@!h+pA9U~i?P1ph|Gh+cG=F)oRQ?=K zyq6_U~%J1PP$nK@ z`3+ySCT`7%w)ALp`oY8R9k^y|dIhP1xi!zR#63l``B&aO|Ml+&zx@r%%20n6!YzSY z1a}$SLQNCCD5_)w+z8xFUecug>ch|NYo0xP&DSrk18!OA!!vCQAO7pJV94q-)3|81 zF*0@3^rL^6X@osgNo_vsHTPa4cKTpZI@C*VZcUb&{o7wjy!7lXLb@@^wtu=K4^`OI z{ptG_on@Mho|&(0+Zz8%dbBdBt}|uK=wkIZEL$}5)nC7j3X$gKo+su{KN?3bvW_l&SQ_8vWt0MKuxWn}U@mF>$t#wA>=jNw#@uE7(1b zav;ZiaqUz1WQxD~=WnmhT}sy&ewpnRn+ zY?5B6De7KUa^?5-ok5wTAGf+h?AfhFGxt3FH?K)LWAW@6k*NjKKmWtb8Elf!8rgBe zLq$GF@+g%-eEy(f;F=fF|73dkD+Dq+8gEp1in?>KRdk;;dEKj>`w4ARUE{5HALG}BaLkx@A=LA>0g8o zWRVhW`UyA9;!I}*DWkp>m;vcmDC_i->oES)4#jJ0%f*5(T2>YR*Ua#;n*Vo|&BYTe zm#N)aCX?rCd92p*sL3o3j^1r+fM$cXR*sgiY8LsLzHi;VMz8nfHrW@USBzi(r`Y$$ zs28#C_rYiF`x^SizIUlU2Q&2v0#Bbauc|-2<&HvTE-8HYuQU0& zDl~n!JA=874(rVD@PS4dFg(yGD@_@x-Am(np6xxKgro8$4}FY6>QX} z?<>Oe>j3$k%*gKpv-vZJaF*4CxmI+h2@|ivnI_D_ie{RMW*ZmIG%cKMTr|^!+4JI= zrp2?3v6-gWY~!+-re(8@B{NMWvyEjlO=Yu<<(R@*xe=OfkAP?S0i+I0DUH+|&laLc zi=OzwQH7+Gz9(w&*4scElL6B8oSSeExPO`ooatT`wbfcCfwufJ zil3w2n733{#p$zI_8>1wYyb6^p^+d%UGRV}f)Nx4rOu41-`M;9>2o1PItwiz($fsB zNc*RYFoZog%4-fgSjr;EbZ|V&3l5g@ZY+!*Bu{E7O?`geMOU7dJ_(yWILfCm+&ef* z=Kws@HGeJ!G`V;NN0(T_L1UJSGM(q6raF4Yj&V9GCd)mY=XVcUOOGBv&UAg=bkJJr zIB3eEgQmP2!sOCYx}4`8fHJ717pjltiD->`JY0oUX~#*hH*%eAm?O)W~G4Pgw6v#YR%Q5OEJloVwn=^Cri8`w)L* zV03)9as;oD(aBivp5CG1-krlK$7vba(>pxWZ_*l>+PyP19y_VOEH*I-4zZH*6)RSp z)L-h1jZRE1-#t1$ncD44Abn>igg$RFb^B8&vPe=t#oSJaPr$(HK;S`dL#~q_9laBy#dE5bm z;iQP2oEW+w1=`+8lU)C3YJ&Pt?HihyJkdekQ^U^i&`4@z)EVoY9CYeOM; z+?VPP%1Bivp~F#8Y7zx)JbO~(@Qsco$5WG2vuRGyhR#spLSPWt-q0k(~17caZF>lnx3IMs0??nP);+_#{I>qHZ7|7}vN1Vii5 zYK4DLgFrZP$h+u-4!IM=kw_j5CNI(jSpIe*-2D0A6n3NU1XobU=(zc}f;t?^3m*a} zn)g$ZL=X8VYG~+Iv~!V~3lTT8iY)iPmuw<=$AdI9j;uz_=wQM>Pdq#Fm-hx`G-Cxx#&mWN=f# z0I?PBMhP|)9MAk#y1OOVSa3Lnta9%Y&P@d_O|BJ!RCb+%erwq25;MoPgWN?cKo?Gx62HV`_61TsAgQdIg&$|hd`UIp6n=_=epwX~DSRu{^;Iq5C`|2g${qPUm>foX zV0I3tWfDr85a@3#^b|m!LSTOA7W~a08~|NWOM{a?MBfqL2lGh&TU~a`#UFs6PVrgz z8!A2*fJpI0K<5|NB75QDBjI<8KLQe`_;L6{#pU>Wc=3(MN7Olj93uH&b)O@r2K;e~ zm*+Fa8-?~Nq#iC_2~LsXKT=)AWRze0UYPtL#W#X7T6`J)78D

Ydu> zUxws^C84H-9`#%?tAhC;wtemdv6R5NKik=fai9y^`K(NejBk|MTIEK!LVk5xC}m z!2}Bnc7b{RU16;fMb09ZbjL6V#gN^ro?ym*ArZobk+TpA4I|@+9N!1*v0IR`n->{{ zKYu&^ERIBvek92`vO7x_A~ zw?Y)rF4dAOEc_yI%apRH@CU@5tf7U4tU}RKG_!3Dl2?9Ln}2@?u6P%T7DBmJAN!5 zMjx$sGo0dYfyycVndJNd$@wGr8+PWU0ACob;sEu8{yrzViazG}UtkffR=$xFhWef8 z>c2xoX7~yec(kTbR8v^E6%nFq)P{;sK-6CBeIRkSxs2|z?>Vst?A&eif}{XWKIxY1 zC*6~-5+(p%dL}3UVa%l~p#|e#CJcV>QaoqLQ=oJ|ZK7S|Mf-Fhn))@`XEfSL@1zjV z;Yi8tj3OML6V$T(Fgf?{68+?5$D@)V!0aNeHz7rLen>_9sh8G#sjSNXh>(hP5hK3M zh_xEZUP@H~(g;RNsVMlVDb3~Egy%BafqR4cw^L#7P`}9cP9yr0RK+HU-buEC+GLb* zK9%umlj_Apiw<8M;L@d}v9%Q896`8ufl`a*94VnHvN?y6p7>Uv+}FGo#HUCRoXgU1 zV$F;_p|OAI#h&nEPcXI<`ww#3t#tDsx2Ce&r`xS`4wZhs(p7qN=lgW$E8U04?^2~Z z%cHy0r@K_>O5FbdG8C8YG3;JL$_F5LD9)zi#5*BzD9#S*#J@u0p*Xuur*uDU;#2?t z;%_qYSwuXQZIFAaG(p!o&S_s~IjTu-R8`7h1 zN{jvoNZq(b=M42){Jsd-@$+n6;_1;V(xR`28r>xt{U${H1%6K;`Z-?oCF#+ZrA6;y z-iNd*JcX#`(AGk@@Aje(i5a1!H1Fq0#jvVd&Qh+?=!`m!-zG%=i5I;lJ^Jav=;aHk zx?_dnGQ_+GzhT5a8cR8+N--X5iaajGb{rcGoAi@RdR&v{x`L!D2#Tj2ZzVQ2YA!PxzVGUNE@Gzj*4VE#a6(j38PhXDFEd{yl9+^eWf>aA)W>+l;H zoQH_3P# zA;#%30D(QdOx(!Y8n_(ltRr;|C`paJaJ}_!AjL+KZ)9BjTf_eIT#$VaKWgs|GTsIt z8TW}BSgAnqzGc%FVQ0${xMJ8&Nc za1;CCWAR&rDDKgr`5>xh+qd>@0R9sc)y)Xi-i%OQn5`)Ots`sp7i5iIcD?m)Alr>h z1OL{r+vTd@$MHJ_f_#<&{2oB&>^X5Gr{@D1x;9!{Ebidi#ctSqii7k2GVXMr;TL0k!er>_PSi^q#^wdtcoH3>HPpu17mPc0%0Ay{9oaB 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 literal 0 HcmV?d00001 diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/extconf.rb b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/extconf.rb new file mode 100644 index 0000000..2201533 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/extconf.rb @@ -0,0 +1,17 @@ +require 'mkmf' + +RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC'] + +if RUBY_VERSION < "2.0" + STDERR.print("Ruby version is too old\n") + exit(1) +end + +if RbConfig::MAKEFILE_CONFIG['CC'] =~ /gcc/ + $CFLAGS ||= '' + $CFLAGS += ' -Wall -Werror -Wno-unused-parameter' + $CFLAGS += ' -gdwarf-2 -g3 -O0' if ENV['debug'] +end + +dir_config("ruby") +create_makefile('byebug/byebug') diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.c b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.c new file mode 100644 index 0000000..22cd9fc --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.c @@ -0,0 +1,54 @@ +#include + +typedef struct locked_thread_t { + VALUE thread; + struct locked_thread_t *next; +} locked_thread_t; + +static locked_thread_t *locked_head = NULL; +static locked_thread_t *locked_tail = NULL; + +extern int +is_in_locked(VALUE thread) +{ + locked_thread_t *node; + + if (!locked_head) return 0; + + for (node = locked_head; node != locked_tail; node = node->next) + { + if (node->thread == thread) return 1; + } + return 0; +} + +extern void +add_to_locked(VALUE thread) +{ + locked_thread_t *node; + + if (is_in_locked(thread)) return; + + node = ALLOC(locked_thread_t); + node->thread = thread; + node->next = NULL; + if (locked_tail) locked_tail->next = node; + locked_tail = node; + if (!locked_head) locked_head = node; +} + +extern VALUE +remove_from_locked() +{ + VALUE thread; + locked_thread_t *node; + + if (locked_head == NULL) return Qnil; + + node = locked_head; + locked_head = locked_head->next; + if (locked_tail == node) locked_tail = NULL; + thread = node->thread; + xfree(node); + return thread; +} diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.o b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/locker.o new file mode 100644 index 0000000000000000000000000000000000000000..f6150ea67208945f47436b15400f52844ee2696a GIT binary patch literal 91328 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 literal 0 HcmV?d00001 diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.c b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.c new file mode 100644 index 0000000..e1732cc --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.c @@ -0,0 +1,113 @@ +#include + +static int +t_tbl_mark_keyvalue(st_data_t key, st_data_t value, st_data_t tbl) +{ + VALUE thread = (VALUE)key; + + if (!value) return ST_CONTINUE; + + rb_gc_mark((VALUE)value); + rb_gc_mark(thread); + + return ST_CONTINUE; +} + +static void +t_tbl_mark(void* data) +{ + threads_table_t *t_tbl = (threads_table_t *)data; + st_table *tbl = t_tbl->tbl; + st_foreach(tbl, t_tbl_mark_keyvalue, (st_data_t)tbl); +} + +static void +t_tbl_free(void* data) +{ + threads_table_t *t_tbl = (threads_table_t*)data; + st_free_table(t_tbl->tbl); + xfree(t_tbl); +} + +VALUE +threads_create(void) +{ + threads_table_t *t_tbl; + + t_tbl = ALLOC(threads_table_t); + t_tbl->tbl = st_init_numtable(); + return Data_Wrap_Struct(cThreadsTable, t_tbl_mark, t_tbl_free, t_tbl); +} + +void +threads_clear(VALUE table) +{ + threads_table_t *t_tbl; + + Data_Get_Struct(table, threads_table_t, t_tbl); + st_clear(t_tbl->tbl); +} + +static int +is_living_thread(VALUE thread) +{ + return rb_funcall(thread, rb_intern("alive?"), 0) == Qtrue; +} + +static int +t_tbl_check_i(st_data_t key, st_data_t value, st_data_t dummy) +{ + VALUE thread; + + if (!value) return ST_DELETE; + + thread = (VALUE)key; + + if (!is_living_thread(thread)) return ST_DELETE; + + return ST_CONTINUE; +} + +void +check_thread_contexts(void) +{ + threads_table_t *t_tbl; + + Data_Get_Struct(threads, threads_table_t, t_tbl); + st_foreach(t_tbl->tbl, t_tbl_check_i, 0); +} + +void +thread_context_lookup(VALUE thread, VALUE *context) +{ + threads_table_t *t_tbl; + + Data_Get_Struct(threads, threads_table_t, t_tbl); + if (!st_lookup(t_tbl->tbl, thread, context) || !*context) + { + *context = context_create(thread); + st_insert(t_tbl->tbl, thread, *context); + } +} + +void +halt_while_other_thread_is_active(debug_context_t *dc) +{ + while (1) + { + /* halt execution of current thread if debugger is activated in another */ + while (locker != Qnil && locker != rb_thread_current()) + { + add_to_locked(rb_thread_current()); + rb_thread_stop(); + } + + /* stop the current thread if it's marked as suspended */ + if (CTX_FL_TEST(dc, CTX_FL_SUSPEND) && locker != rb_thread_current()) + { + CTX_FL_SET(dc, CTX_FL_WAS_RUNNING); + rb_thread_stop(); + } + else break; + } +} diff --git a/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.o b/vendor/bundle/gems/byebug-2.7.0/ext/byebug/threads.o new file mode 100644 index 0000000000000000000000000000000000000000..095ea64e35483f632f70b84963c0da46f662b2be GIT binary patch literal 97632 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 Rd>6 bool + # Byebug.start(options) { ... } -> obj + # + # If it's called without a block, it returns +true+ unless byebug was + # already started. + # + # If a block is given, it starts byebug and yields block. After the block is + # executed it stops byebug with Byebug.stop method. Inside the block you + # will probably want to have a call to Byebug.byebug. For example: + # + # Byebug.start { byebug; foo } # Stop inside of foo + # + # Also, byebug only allows one invocation of byebug at a time; nested + # Byebug.start's have no effect and you can't use this inside byebug itself. + # + # Note that if you want to stop byebug, you must call Byebug.stop as + # many times as you called Byebug.start method. + # + # +options+ is a hash used to set various debugging options. + # :init - true if you want to save ARGV and some other variables to + # make a byebug restart possible. Only the first time :init + # is set to true the values will get set. Since ARGV is + # saved, you should make sure it hasn't been changed before + # the (first) call. + # :post_mortem - true if you want to enter post-mortem debugging on an + # uncaught exception. Once post-mortem debugging is set, it + # can't be unset. + # + def start(options={}, &block) + options = Byebug::DEFAULT_START_SETTINGS.merge(options) + if options[:init] + Byebug.const_set('ARGV', ARGV.clone) unless defined? Byebug::ARGV + Byebug.const_set('PROG_SCRIPT', $0) unless defined? Byebug::PROG_SCRIPT + Byebug.const_set('INITIAL_DIR', Dir.pwd) unless defined? Byebug::INITIAL_DIR + end + Byebug.tracing = options[:tracing] unless options[:tracing].nil? + retval = Byebug._start(&block) + post_mortem if options[:post_mortem] + return retval + end + + # + # Runs normal byebug initialization scripts. + # + # Reads and executes the commands from init file (if any) in the current + # working directory. This is only done if the current directory is + # different from your home directory. Thus, you can have more than one init + # file, one generic in your home directory, and another, specific to the + # program you are debugging, in the directory where you invoke byebug. + # + def run_init_script(out = handler.interface) + cwd_script = File.expand_path(File.join(".", INITFILE)) + run_script(cwd_script, out) if File.exist?(cwd_script) + + home_script = File.expand_path(File.join(ENV['HOME'].to_s, INITFILE)) + if File.exist?(home_script) and cwd_script != home_script + run_script(home_script, out) + end + end + + # + # Runs a script file + # + def run_script(file, out = handler.interface, verbose=false) + interface = ScriptInterface.new(File.expand_path(file), out) + processor = ControlCommandProcessor.new(interface) + processor.process_commands(verbose) + end + + # + # Activates the post-mortem mode. + # + # By calling Byebug.post_mortem method, you install an at_exit hook that + # intercepts any exception not handled by your script and enables + # post-mortem mode. + # + def post_mortem + return if self.post_mortem? + at_exit { handle_post_mortem($!) if post_mortem? } + self.post_mortem = true + end + + def handle_post_mortem(exp) + return if !exp + Byebug.last_exception = exp + return if !exp.__bb_context || !exp.__bb_context.calced_stack_size + orig_tracing = Byebug.tracing? + Byebug.tracing = false + handler.at_line(exp.__bb_context, exp.__bb_file, exp.__bb_line) + ensure + Byebug.tracing = orig_tracing + end + private :handle_post_mortem + end +end + +class Exception + attr_reader :__bb_file, :__bb_line, :__bb_binding, :__bb_context +end + +module Kernel + # + # Enters byebug after _steps_into_ line events and _steps_out_ return events + # occur. Before entering byebug startup, the init script is read. + # + def byebug(steps_into = 1, steps_out = 2) + Byebug.start + Byebug.run_init_script(StringIO.new) + if Byebug.current_context.calced_stack_size > 2 + Byebug.current_context.stop_return steps_out if steps_out >= 1 + end + Byebug.current_context.step_into steps_into if steps_into >= 0 + end + + alias_method :debugger, :byebug +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command.rb new file mode 100644 index 0000000..9afcda4 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command.rb @@ -0,0 +1,229 @@ +require 'columnize' +require 'forwardable' +require_relative 'helper' + +module Byebug + + module CommandFunctions + # + # Pad a string with dots at the end to fit :width setting + # + def pad_with_dots(string) + if string.size > Command.settings[:width] + string[Command.settings[:width]-3 .. -1] = "..." + end + end + end + + class Command + Subcmd = Struct.new(:name, :min, :help) + + class << self + def commands + @commands ||= [] + end + + attr_accessor :allow_in_control, :unknown, :need_context + attr_writer :allow_in_post_mortem, :always_run + + def allow_in_post_mortem + @allow_in_post_mortem ||= !defined?(@allow_in_post_mortem) ? true : false + end + + def always_run + @always_run ||= 0 + end + + def help(args) + if args && args[1] + output = format_subcmd(args[1]) + else + output = description.gsub(/^ +/, '') + "\n" + output += format_subcmds if defined? self::Subcommands + end + output + end + + def find(subcmds, param) + param.downcase! + for try_subcmd in subcmds do + if (param.size >= try_subcmd.min) and + (try_subcmd.name[0..param.size-1] == param) + return try_subcmd + end + end + return nil + end + + def format_subcmd(subcmd_name) + subcmd = find(self::Subcommands, subcmd_name) + return "Invalid \"#{names.join("|")}\" " \ + "subcommand \"#{args[1]}\"." unless subcmd + + return "#{subcmd.help}.\n" + end + + def format_subcmds + cmd_name = names.join("|") + s = "\n" \ + "--\n" \ + "List of \"#{cmd_name}\" subcommands:\n" \ + "--\n" + w = self::Subcommands.map(&:name).max_by(&:size).size + for subcmd in self::Subcommands do + s += sprintf "%s %-#{w}s -- %s\n", cmd_name, subcmd.name, subcmd.help + end + return s + end + + def inherited(klass) + commands << klass + end + + def load_commands + Dir[File.join(File.dirname(__FILE__), 'commands', '*')].each { + |file| require file } + Byebug.constants.grep(/Functions$/).map { + |name| Byebug.const_get(name) }.each { |mod| include mod } + end + + def settings_map + @@settings_map ||= {} + end + private :settings_map + + def settings + unless defined? @settings and @settings + @settings = Object.new + map = settings_map + c = class << @settings; self end + c.send(:define_method, :[]) do |name| + raise "No such setting #{name}" unless map.has_key?(name) + map[name][:getter].call + end + c.send(:define_method, :[]=) do |name, value| + raise "No such setting #{name}" unless map.has_key?(name) + map[name][:setter].call(value) + end + end + @settings + end + + def register_setting_var(name, default) + var_name = "@@#{name}" + class_variable_set(var_name, default) + register_setting_get(name) { class_variable_get(var_name) } + register_setting_set(name) { |value| class_variable_set(var_name, value) } + end + + def register_setting_get(name, &block) + settings_map[name] ||= {} + settings_map[name][:getter] = block + end + + def register_setting_set(name, &block) + settings_map[name] ||= {} + settings_map[name][:setter] = block + end + + def command_exists?(command) + ENV['PATH'].split(File::PATH_SEPARATOR).any? { + |d| File.exist? File.join(d, command) } + end + + def terminal_width + if ENV['COLUMNS'] =~ /^\d+$/ + ENV['COLUMNS'].to_i + elsif STDIN.tty? && command_exists?('stty') + `stty size`.scan(/\d+/)[1].to_i + else + nil + end + end + end + + # Register default settings + register_setting_var(:basename, false) + register_setting_var(:callstyle, :long) + register_setting_var(:testing, false) + register_setting_var(:forcestep, false) + register_setting_var(:fullpath, true) + register_setting_var(:listsize, 10) + register_setting_var(:stack_on_error, false) + register_setting_var(:linetrace_plus, false) + cols = terminal_width || 160 + register_setting_var(:width, cols > 10 ? cols : 160) + Byebug::ARGV = ARGV.clone unless defined? Byebug::ARGV + register_setting_var(:argv, Byebug::ARGV) + + def initialize(state) + @match, @state = nil, state + end + + def match(input) + @match = regexp.match(input) + end + + protected + + extend Forwardable + def_delegators :@state, :errmsg, :print + + def confirm(msg) + @state.confirm(msg) == 'y' + end + + def bb_eval(str, b = get_binding) + begin + eval(str, b) + rescue StandardError, ScriptError => e + at = eval('Thread.current.backtrace_locations(1)', b) + print "#{at.shift}: #{e.class} Exception(#{e.message})\n" + for i in at + print "\tfrom #{i}\n" + end + nil + end + end + + def bb_warning_eval(str, b = get_binding) + begin + eval(str, b) + rescue StandardError, ScriptError => e + print "#{e.class} Exception: #{e.message}\n" + nil + end + end + + def get_binding pos = @state.frame_pos + @state.context ? @state.context.frame_binding(pos) : TOPLEVEL_BINDING + end + + def get_context(thnum) + Byebug.contexts.find {|c| c.thnum == thnum} + end + end + + Command.load_commands + + ## + # Returns ths settings object. + # Use Byebug.settings[] and Byebug.settings[]= methods to query and set + # byebug settings. These settings are available: + # + # :autoeval - evaluates input in the current binding if it's not + # recognized as a byebug command + # :autoirb - automatically calls 'irb' command on breakpoint + # :autolist - automatically calls 'list' command on breakpoint + # :autoreload - makes 'list' command always display up-to-date source + # code + # :frame_class_names - displays method's class name when showing frame stack + # :forcestep - stepping command always move to the new line + # :fullpath - displays full paths when showing frame stack + # :stack_on_error - shows full stack trace if eval command results in an + # exception + # + def self.settings + Command.settings + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command_processor.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command_processor.rb new file mode 100644 index 0000000..16c7c53 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/command_processor.rb @@ -0,0 +1,255 @@ +require 'forwardable' +require_relative 'interface' +require_relative 'command' + +module Byebug + + class CommandProcessor < Processor + attr_reader :display + + def initialize(interface = LocalInterface.new) + super(interface) + + @display = [] + @mutex = Mutex.new + @last_cmd = nil # To allow empty (just ) commands + @last_file = nil # Filename the last time we stopped + @last_line = nil # Line number the last time we stopped + @context_was_dead = false # Assume we haven't started. + end + + def interface=(interface) + @mutex.synchronize do + @interface.close if @interface + @interface = interface + end + end + + require 'pathname' # For cleanpath + + # + # Regularize file name. + # + # This is also used as a common funnel place if basename is desired or if we + # are working remotely and want to change the basename. Or we are eliding + # filenames. + def self.canonic_file(filename) + return filename if ['(irb)', '-e'].include?(filename) + + # For now we want resolved filenames + if Command.settings[:basename] + File.basename(filename) + else + Pathname.new(filename).cleanpath.to_s + end + end + + def self.protect(mname) + alias_method "__#{mname}", mname + module_eval <<-END, __FILE__, __LINE__+1 + def #{mname}(*args) + @mutex.synchronize do + return unless @interface + __#{mname}(*args) + end + rescue IOError, Errno::EPIPE + self.interface = nil + rescue SignalException + raise + rescue Exception + print "INTERNAL ERROR!!! #\{$!\}\n" rescue nil + print $!.backtrace.map{|l| "\t#\{l\}"}.join("\n") rescue nil + end + END + end + + def at_breakpoint(context, breakpoint) + n = Byebug.breakpoints.index(breakpoint) + 1 + file = CommandProcessor.canonic_file(breakpoint.source) + line = breakpoint.pos + print "Stopped by breakpoint #{n} at #{file}:#{line}\n" + end + protect :at_breakpoint + + def at_catchpoint(context, excpt) + file = CommandProcessor.canonic_file(context.frame_file(0)) + line = context.frame_line(0) + print "Catchpoint at %s:%d: `%s' (%s)\n", file, line, excpt, excpt.class + end + protect :at_catchpoint + + def at_tracing(context, file, line) + if file != @last_file || line != @last_line || Command.settings[:linetrace_plus] + @last_file, @last_line = file, line + print "Tracing: #{CommandProcessor.canonic_file(file)}:#{line} " \ + "#{Byebug.line_at(file,line)}\n" + end + always_run(context, file, line, 2) + end + protect :at_tracing + + def at_line(context, file, line) + Byebug.source_reload if Command.settings[:autoreload] + process_commands(context, file, line) + end + protect :at_line + + def at_return(context, file, line) + process_commands(context, file, line) + end + protect :at_return + + private + # + # Prompt shown before reading a command. + # + def prompt(context) + return "(byebug#{context.dead? ? ':post-mortem' : ''}) " + end + + # + # Run commands everytime. + # + # For example display commands or possibly the list or irb in an + # "autolist" or "autoirb". + # + # @return List of commands acceptable to run bound to the current state + # + def always_run(context, file, line, run_level) + cmds = Command.commands + + # Remove some commands in post-mortem + cmds = cmds.find_all { |cmd| cmd.allow_in_post_mortem } if context.dead? + + state = State.new(cmds, context, @display, file, @interface, line) + + # Change default when in irb or code included in command line + Command.settings[:autolist] = 0 if ['(irb)', '-e'].include?(file) + + # Bind commands to the current state. + commands = cmds.map { |cmd| cmd.new(state) } + + commands.select { |cmd| cmd.class.always_run >= run_level } + .each { |cmd| cmd.execute } + + return state, commands + end + + # + # Splits a command line of the form "cmd1 ; cmd2 ; ... ; cmdN" into an + # array of commands: [cmd1, cmd2, ..., cmdN] + # + def split_commands(cmd_line) + cmd_line.split(/;/).inject([]) do |m, v| + if m.empty? + m << v + else + if m.last[-1] == ?\\ + m.last[-1,1] = '' + m.last << ';' << v + else + m << v + end + end + m + end + end + + # + # Handle byebug commands. + # + def process_commands(context, file, line) + state, commands = always_run(context, file, line, 1) + + if Command.settings[:testing] + Thread.current.thread_variable_set('state', state) + else + Thread.current.thread_variable_set('state', nil) + end + + preloop(commands, context) + print state.location if Command.settings[:autolist] == 0 + + while !state.proceed? + input = @interface.command_queue.empty? ? + @interface.read_command(prompt(context)) : + @interface.command_queue.shift + break unless input + catch(:debug_error) do + if input == "" + next unless @last_cmd + input = @last_cmd + else + @last_cmd = input + end + split_commands(input).each do |cmd| + one_cmd(commands, context, cmd) + end + end + end + end + + # + # Executes a single byebug command + # + def one_cmd(commands, context, input) + if cmd = commands.find { |c| c.match(input) } + if context.dead? && cmd.class.need_context + print "Command is unavailable\n" + else + cmd.execute + end + else + unknown_cmd = commands.find { |c| c.class.unknown } + if unknown_cmd + unknown_cmd.execute + else + errmsg "Unknown command: \"#{input}\". Try \"help\".\n" + end + end + end + + # + # Tasks to do before processor loop + # + def preloop(commands, context) + @context_was_dead = true if context.dead? and not @context_was_dead + + if @context_was_dead + print "The program finished.\n" + @context_was_dead = false + end + end + + class State + attr_accessor :commands, :context, :display, :file, :frame_pos + attr_accessor :interface, :line, :previous_line + + def initialize(commands, context, display, file, interface, line) + @commands, @context, @display = commands, context, display + @file, @interface, @line = file, interface, line + @frame_pos, @previous_line, @proceed = 0, nil, false + end + + extend Forwardable + def_delegators :@interface, :errmsg, :print, :confirm + + def proceed? + @proceed + end + + def proceed + @proceed = true + end + + def location + loc = "#{CommandProcessor.canonic_file(@file)} @ #{@line}\n" + loc += "#{Byebug.line_at(@file, @line)}\n" unless + ['(irb)', '-e'].include? @file + loc + end + end + + end # class CommandProcessor + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/breakpoints.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/breakpoints.rb new file mode 100644 index 0000000..5a0dc9b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/breakpoints.rb @@ -0,0 +1,137 @@ +module Byebug + + # Implements byebug "break" command. + class BreakCommand < Command + self.allow_in_post_mortem = false + self.allow_in_control = true + + def regexp + /^\s* b(?:reak)? (?:\s+#{Position_regexp})? (?:\s+(.+))? \s*$/x + end + + def execute + return print BreakCommand.help(nil) if BreakCommand.names.include?(@match[0]) + + if @match[1] + line, _, _, expr = @match.captures + else + _, file, line, expr = @match.captures + end + if expr + if expr !~ /^\s*if\s+(.+)/ + if file or line + errmsg "Expecting \"if\" in breakpoint condition; got: #{expr}.\n" + else + errmsg "Invalid breakpoint location: #{expr}.\n" + end + return + else + expr = $1 + end + end + + brkpt_filename = file + if file.nil? + unless @state.context + errmsg "We are not in a state that has an associated file.\n" + return + end + brkpt_filename = @state.file + if line.nil? + # Set breakpoint at current line + line = @state.line.to_s + end + elsif line !~ /^\d+$/ + # See if "line" is a method/function name + klass = bb_warning_eval(file) + if klass && klass.kind_of?(Module) + class_name = klass.name if klass + else + errmsg "Unknown class #{file}.\n" + throw :debug_error + end + end + + if line =~ /^\d+$/ + line = line.to_i + if LineCache.cache(brkpt_filename, Command.settings[:autoreload]) + last_line = LineCache.size(brkpt_filename) + return errmsg "There are only #{last_line} lines in file " \ + "#{brkpt_filename}\n" if line > last_line + + return errmsg "Line #{line} is not a stopping point in file " \ + "#{brkpt_filename}\n" unless + LineCache.trace_line_numbers(brkpt_filename).member?(line) + else + errmsg "No source file named #{brkpt_filename}\n" + return unless confirm("Set breakpoint anyway? (y/n) ") + end + + b = Byebug.add_breakpoint brkpt_filename, line, expr + print "Created breakpoint #{b.id} at " \ + "#{CommandProcessor.canonic_file(brkpt_filename)}:#{line.to_s}\n" + unless syntax_valid?(expr) + errmsg "Expression \"#{expr}\" syntactically incorrect; breakpoint" \ + " disabled.\n" + b.enabled = false + end + else + method = line.intern + b = Byebug.add_breakpoint class_name, method, expr + print "Created breakpoint #{b.id} at #{class_name}::#{method.to_s}\n" + end + end + + class << self + def names + %w(break) + end + + def description + %{b[reak] file:line [if expr] + b[reak] class(.|#)method [if expr] + + Set breakpoint to some position, (optionally) if expr == true} + end + end + end + + # Implements byebug "delete" command. + class DeleteCommand < Command + self.allow_in_post_mortem = false + self.allow_in_control = true + + def regexp + /^\s* del(?:ete)? (?:\s+(.*))?$/x + end + + def execute + return errmsg "We are not in a state we can delete breakpoints.\n" unless + @state.context + + if not @match[1] + Byebug.breakpoints.clear if confirm("Delete all breakpoints? (y or n) ") + else + @match[1].split(/[ \t]+/).each do |pos| + return unless pos = get_int(pos, "Delete", 1) + errmsg "No breakpoint number %d\n", pos unless + Byebug.remove_breakpoint(pos) + end + end + end + + class << self + def names + %w(delete) + end + + def description + %{del[ete][ nnn...] + + Without and argument, deletes all breakpoints. With integer arguments, + it deletes specific breakpoints.} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/catchpoint.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/catchpoint.rb new file mode 100644 index 0000000..a44c815 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/catchpoint.rb @@ -0,0 +1,46 @@ +module Byebug + + class CatchCommand < Command + self.allow_in_control = true + + def regexp + /^\s* cat(?:ch)? (?:\s+(\S+))? (?:\s+(off))? \s*$/x + end + + def execute + excn = @match[1] + return info_catch unless excn + + if not @match[2] + if 'off' == @match[1] + Byebug.catchpoints.clear if + confirm("Delete all catchpoints? (y or n) ") + else + print "Warning #{@match[1]} is not known to be a Class\n" unless + bb_eval "#{@match[1]}.is_a?(Class)", get_binding + Byebug.add_catchpoint @match[1] + print "Catching exception #{@match[1]}.\n" + end + elsif @match[2] != 'off' + errmsg "Off expected. Got #{@match[2]}\n" + elsif Byebug.catchpoints.member?(@match[1]) + Byebug.catchpoints.delete @match[1] + print "Catch for exception #{match[1]} removed.\n" + else + return errmsg "Catch for exception #{@match[1]} not found\n" + end + end + + class << self + def names + %w(catch) + end + + def description + %{cat[ch]\t\t\t\tLists catchpoints + cat[ch] off\t\t\tDeletes all catchpoints + cat[ch] [off]\tEnable/disable handling .} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/condition.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/condition.rb new file mode 100644 index 0000000..51004ed --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/condition.rb @@ -0,0 +1,41 @@ +module Byebug + + class ConditionCommand < Command + self.allow_in_post_mortem = false + + def regexp + /^\s* cond(?:ition)? (?:\s+(\d+)(?:\s+(.*))?)? \s*$/x + end + + def execute + return print ConditionCommand.help(nil) unless @match[1] + + breakpoints = Byebug.breakpoints.sort_by{|b| b.id } + largest = breakpoints.inject(0) do |tally, b| + tally = b.id if b.id > tally + end + + return print "No breakpoints have been set.\n" if 0 == largest + return unless pos = get_int(@match[1], "Condition", 1, largest) + + breakpoint = breakpoints.select{ |b| b.id == pos }.first + breakpoint.expr = @match[2] if breakpoint + end + + class << self + def names + %w(condition) + end + + def description + %{cond[ition] nnn[ expr] + + Specify breakpoint number nnn to break only if expr is true. nnn is an + integer and expr is an expression to be evaluated whenever breakpoint + nnn is reached. If no expression is specified, the condition is + removed.} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/continue.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/continue.rb new file mode 100644 index 0000000..9d5a27e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/continue.rb @@ -0,0 +1,37 @@ +module Byebug + + # Implements byebug "continue" command. + class ContinueCommand < Command + self.allow_in_post_mortem = true + self.need_context = false + + def regexp + /^\s* c(?:ont(?:inue)?)? (?:\s+(\S+))? \s*$/x + end + + def execute + if @match[1] && !@state.context.dead? + filename = File.expand_path(@state.file) + return unless line_number = get_int(@match[1], "Continue", 0, nil, 0) + return errmsg "Line #{line_number} is not a stopping point in file " \ + "\"#{filename}\"\n" unless + LineCache.trace_line_numbers(filename).member?(line_number) + + Byebug.add_breakpoint filename, line_number + end + @state.proceed + end + + class << self + def names + %w(continue) + end + + def description + %{c[ont[inue]][ nnn] + + Run until program ends, hits a breakpoint or reaches line nnn} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/control.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/control.rb new file mode 100644 index 0000000..dc3dab3 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/control.rb @@ -0,0 +1,90 @@ +module Byebug + + class RestartCommand < Command + self.allow_in_control = true + + def regexp + /^\s* (?:restart|R) (?:\s+(.+))? \s*$/x + end + + def execute + return errmsg "Don't know name of debugged program\n" unless + defined? Byebug::PROG_SCRIPT + + return errmsg "Ruby program #{Byebug::PROG_SCRIPT} doesn't exist\n" unless + File.exist?(File.expand_path(Byebug::PROG_SCRIPT)) + + if not defined? Byebug::BYEBUG_SCRIPT + print "Byebug was not called from the outset...\n" + if not File.executable?(Byebug::PROG_SCRIPT) + print "Ruby program #{Byebug::PROG_SCRIPT} not executable... " \ + "We'll add a call to Ruby.\n" + cmd = "ruby -rbyebug -I#{$:.join(' -I')} #{Byebug::PROG_SCRIPT}" + else + cmd = Byebug::PROG_SCRIPT + end + else + cmd = "#{Byebug::BYEBUG_SCRIPT} #{Byebug::PROG_SCRIPT}" + end + + begin + Dir.chdir(Byebug::INITIAL_DIR) + rescue + print "Failed to change initial directory #{Byebug::INITIAL_DIR}" + end + + if @match[1] + cmd += " #{@match[1]}" + elsif not defined? Command.settings[:argv] + return errmsg "Arguments not set. Use 'set args' to set them.\n" + else + require 'shellwords' + cmd += " #{Command.settings[:argv].compact.shelljoin}" + end + + # An execv would be preferable to the "exec" below. + print "Re exec'ing:\n\t#{cmd}\n" + exec cmd + rescue Errno::EOPNOTSUPP + print "Restart command is not available at this time.\n" + end + + class << self + def names + %w(restart) + end + + def description + %{restart|R [args] + + Restart the program. This is a re-exec - all byebug state + is lost. If command arguments are passed those are used.} + end + end + end + + class InterruptCommand < Command + self.allow_in_control = true + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s*i(?:nterrupt)?\s*$/ + end + + def execute + context = Byebug.thread_context(Thread.main) + context.interrupt + end + + class << self + def names + %w(interrupt) + end + + def description + %{i|nterrupt\t interrupt the program} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/display.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/display.rb new file mode 100644 index 0000000..a36b526 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/display.rb @@ -0,0 +1,116 @@ +module Byebug + + module DisplayFunctions + def display_expression(exp) + print "#{exp} = #{bb_warning_eval(exp).inspect}\n" + end + + def active_display_expressions? + @state.display.select{|d| d[0]}.size > 0 + end + + def print_display_expressions + n = 1 + for d in @state.display + if d[0] + print "#{n}: " + display_expression(d[1]) + end + n += 1 + end + end + end + + class AddDisplayCommand < Command + self.allow_in_post_mortem = false + + def regexp + /^\s* disp(?:lay)? \s+ (.+) \s*$/x + end + + def execute + exp = @match[1] + @state.display.push [true, exp] + print "#{@state.display.size}: " + display_expression(exp) + end + + class << self + def names + %w(display) + end + + def description + %{disp[lay] \tadd expression into display expression list} + end + end + end + + class DisplayCommand < Command + self.allow_in_post_mortem = false + + def self.always_run + 2 + end + + def regexp + /^\s* disp(?:lay)? \s*$/x + end + + def execute + print_display_expressions + end + + class << self + def names + %w(display) + end + + def description + %{disp[lay]\t\tdisplay expression list} + end + end + end + + class DeleteDisplayCommand < Command + self.allow_in_post_mortem = false + + def regexp + /^\s* undisp(?:lay)? (?:\s+(\S+))? \s*$/x + end + + def execute + unless pos = @match[1] + if confirm("Clear all expressions? (y/n) ") + for d in @state.display + d[0] = false + end + end + else + pos = get_int(pos, "Undisplay") + return unless pos + if @state.display[pos-1] + @state.display[pos-1][0] = nil + else + errmsg "Display expression %d is not defined.\n", pos + end + end + end + + class << self + def names + %w(undisplay) + end + + def description + %{undisp[lay][ nnn] + + Cancel some expressions to be displayed when program stops. Arguments + are the code numbers of the expressions to stop displaying. No + argument means cancel all automatic-display expressions. "delete + display" has the same effect as this command. Do "info display" to see + the current list of code numbers.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/edit.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/edit.rb new file mode 100644 index 0000000..a09354e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/edit.rb @@ -0,0 +1,50 @@ +module Byebug + + class Edit < Command + self.allow_in_control = true + + def regexp + /^\s* ed(?:it)? (?:\s+(\S+))? \s*$/x + end + + def execute + if not @match[1] + unless @state.file + return errmsg "We are not in a state that has an associated file.\n" + end + file = @state.file + line = @state.line if @state.line + elsif @pos_match = /([^:]+)[:]([0-9]+)/.match(@match[1]) + file, line = @pos_match.captures + elsif File.exist?(@match[1]) + file = @match[1] + else + return errmsg "Invalid file[:line] number specification: #{@match[1]}\n" + end + + editor = ENV['EDITOR'] || 'vim' + + if File.readable?(file) + system("#{editor} +#{line} #{file}") if line + system("#{editor} #{file}") unless line + else + errmsg "File \"#{file}\" is not readable.\n" + end + end + + class << self + def names + %w(edit) + end + + def description + %{edit[ file:lineno]\tEdit specified file. + + With no argument, edits file containing most recent line listed. + Editing targets can also be specified to start editing at a specific + line in a specific file.} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/enable.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/enable.rb new file mode 100644 index 0000000..bc5a2e2 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/enable.rb @@ -0,0 +1,155 @@ +module Byebug + + # Mix-in module to assist in command parsing. + module EnableDisableFunctions + def enable_disable_breakpoints(is_enable, args) + return errmsg "No breakpoints have been set." if Byebug.breakpoints.empty? + + all_breakpoints = Byebug.breakpoints.sort_by {|b| b.id } + if args.empty? + selected_breakpoints = all_breakpoints + else + selected_ids = [] + args.each do |pos| + pos = get_int(pos, "#{is_enable} breakpoints", 1, all_breakpoints.last.id) + return nil unless pos + selected_ids << pos + end + selected_breakpoints = all_breakpoints.select { + |b| selected_ids.include?(b.id) } + end + + selected_breakpoints.each do |b| + enabled = ('enable' == is_enable) + if enabled && !syntax_valid?(b.expr) + errmsg "Expression \"#{b.expr}\" syntactically incorrect; " \ + "breakpoint remains disabled.\n" + else + b.enabled = enabled + end + end + end + + def enable_disable_display(is_enable, args) + if 0 == @state.display.size + errmsg "No display expressions have been set.\n" + return + end + args.each do |pos| + pos = get_int(pos, "#{is_enable} display", 1, @state.display.size) + return nil unless pos + @state.display[pos-1][0] = ('enable' == is_enable) + end + end + end + + class EnableCommand < Command + Subcommands = [ + ['breakpoints', 2, 'Enable breakpoints. This is used to cancel the ' \ + 'effect of the "disable" command. Give breakpoint' \ + ' numbers (separated by spaces) as arguments or ' \ + 'no argument at all if you want to reenable ' \ + 'every breakpoint' ], + ['display' , 2, 'Enable some expressions to be displayed when ' \ + 'program stops. Arguments are the code numbers of' \ + ' the expressions to resume displaying. Do "info ' \ + 'display" to see the current list of code numbers' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(Subcommands) + + def regexp + /^\s* en(?:able)? (?:\s+(.+))? \s*$/x + end + + def execute + return errmsg "\"enable\" must be followed by \"display\", " \ + "\"breakpoints\" or breakpoint numbers.\n" unless @match[1] + + args = @match[1].split(/[ \t]+/) + param = args.shift + subcmd = Command.find(Subcommands, param) + if subcmd + send("enable_#{subcmd.name}", args) + else + send('enable_breakpoints', args.unshift(param)) + end + end + + def enable_breakpoints(args) + enable_disable_breakpoints('enable', args) + end + + def enable_display(args) + enable_disable_display('enable', args) + end + + class << self + def names + %w(enable) + end + + def description + %{Enable breakpoints or displays. + + This is used to cancel the effect of the "disable" command.} + end + end + end + + class DisableCommand < Command + Subcommands = [ + ['breakpoints', 1, 'Disable breakpoints. A disabled breakpoint is ' \ + 'not forgotten, but has no effect until ' \ + 'reenabled. Give breakpoint numbers (separated by' \ + 'spaces) as arguments or no argument at all if ' \ + 'you want to disable every breakpoint' ], + ['display' , 1, 'Disable some display expressions when program ' \ + 'stops. Arguments are the code numbers of the ' \ + 'expressions to stop displaying. Do "info ' \ + 'display" to see the current list of code numbers.' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(Subcommands) + + def regexp + /^\s* dis(?:able)? (?:\s+(.+))? \s*$/x + end + + def execute + return errmsg "\"disable\" must be followed by \"display\", " \ + "\"breakpoints\" or breakpoint numbers.\n" unless @match[1] + + args = @match[1].split(/[ \t]+/) + param = args.shift + subcmd = Command.find(Subcommands, param) + if subcmd + send("disable_#{subcmd.name}", args) + else + send('disable_breakpoints', args.unshift(param)) + end + end + + def disable_breakpoints(args) + enable_disable_breakpoints('disable', args) + end + + def disable_display(args) + enable_disable_display('disable', args) + end + + class << self + def names + %w(disable) + end + + def description + %{Disable breakpoints or displays. + + A disabled item is not forgotten, but has no effect until reenabled. + Use the "enable" command to have it take effect again.} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/eval.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/eval.rb new file mode 100644 index 0000000..c1baeec --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/eval.rb @@ -0,0 +1,175 @@ +require 'pp' + +module Byebug + module EvalFunctions + def run_with_binding + binding = get_binding + yield binding + end + end + + class EvalCommand < Command + self.allow_in_control = true + + register_setting_get(:autoeval) do + EvalCommand.unknown + end + register_setting_set(:autoeval) do |value| + EvalCommand.unknown = value + end + + # Set default value + Command.settings[:autoeval] = true + + def match(input) + @input = input + super + end + + def regexp + /^\s* (p|e(?:val)?)\s+/x + end + + def execute + expr = @match ? @match.post_match : @input + run_with_binding do |b| + if Command.settings[:stack_on_error] + print "#{bb_eval(expr, b).inspect}\n" + else + print "#{bb_warning_eval(expr, b).inspect}\n" + end + end + rescue + print "#{$!.class} Exception: #{$!.message}\n" + end + + class << self + def names + %w(p eval) + end + + def description + %{(p|e[val]) expression + + Evaluate expression and print its value + * NOTE - unknown input is automatically evaluated, to turn this off + use 'set noautoeval'} + end + end + end + + class PPCommand < Command + self.allow_in_control = true + + def regexp + /^\s* pp \s+/x + end + + def execute + out = StringIO.new + run_with_binding do |b| + if Command.settings[:stack_on_error] + PP.pp(bb_eval(@match.post_match, b), out) + else + PP.pp(bb_warning_eval(@match.post_match, b), out) + end + end + print out.string + rescue + out.puts $!.message + end + + class << self + def names + %w(pp) + end + + def description + %{pp expression\tevaluate expression and pretty-print its value} + end + end + end + + class PutLCommand < Command + include Columnize + self.allow_in_control = true + + def regexp + /^\s* putl\s+/x + end + + def execute + out = StringIO.new + run_with_binding do |b| + if Command.settings[:stack_on_error] + vals = bb_eval(@match.post_match, b) + else + vals = bb_warning_eval(@match.post_match, b) + end + if vals.is_a?(Array) + vals = vals.map{|item| item.to_s} + print "#{columnize(vals, Command.settings[:width])}\n" + else + PP.pp(vals, out) + print out.string + end + end + rescue + out.puts $!.message + end + + class << self + def names + %w(putl) + end + + def description + %{putl expression + + Evaluate expression, an array, and columnize its value} + end + end + end + + class PSCommand < Command + include Columnize + self.allow_in_control = true + + def regexp + /^\s* ps\s+/x + end + + def execute + out = StringIO.new + run_with_binding do |b| + if Command.settings[:stack_on_error] + vals = bb_eval(@match.post_match, b) + else + vals = bb_warning_eval(@match.post_match, b) + end + if vals.is_a?(Array) + vals = vals.map{|item| item.to_s} + print "#{columnize(vals.sort!, Command.settings[:width])}\n" + else + PP.pp(vals, out) + print out.string + end + end + rescue + out.puts $!.message + end + + class << self + def names + %w(ps) + end + + def description + %{ps expression + + Evaluate expression, an array, sort and columnize its value} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/finish.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/finish.rb new file mode 100644 index 0000000..94c8ec9 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/finish.rb @@ -0,0 +1,42 @@ +module Byebug + + # Implements byebug's 'finish' command. + class FinishCommand < Command + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* fin(?:ish)? (?:\s+(\S+))? \s*$/x + end + + def execute + if not @match[1] + frame_pos = @state.frame_pos + else + max_frame = Context.stack_size - @state.frame_pos + frame_pos = get_int(@match[1], "finish", 0, max_frame-1, 0) + return nil unless frame_pos + end + @state.context.step_out frame_pos + @state.frame_pos = 0 + @state.proceed + end + + class << self + def names + %w(finish) + end + + def description + %{fin[ish][ frame-number]\tExecute until selected stack frame returns. + + If no frame number is given, we run until the currently selected frame + returns. The currently selected frame starts out the most-recent frame + or 0 if no frame positioning (e.g "up", "down" or "frame") has been + performed. + + If a frame number is given we run until that frame returns.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/frame.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/frame.rb new file mode 100644 index 0000000..40c6125 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/frame.rb @@ -0,0 +1,256 @@ +# encoding: utf-8 +module Byebug + + # Mix-in module to assist in command parsing. + module FrameFunctions + def c_frame?(frame_no) + @state.context.frame_binding(frame_no).nil? + end + + def switch_to_frame(frame_no) + if frame_no < 0 + abs_frame_no = Context.stack_size + frame_no + else + abs_frame_no = frame_no + end + end + + def navigate_to_frame(jump_no) + return if jump_no == 0 + total_jumps, current_jumps, new_pos = jump_no.abs, 0, @state.frame_pos + step = jump_no/total_jumps + loop do + new_pos += step + return new_pos if new_pos < 0 || new_pos >= Context.stack_size + + next if c_frame?(new_pos) + + current_jumps += 1 + break if current_jumps == total_jumps + end + return new_pos + end + + def adjust_frame(frame_pos, absolute) + if absolute + abs_frame_pos = switch_to_frame(frame_pos) + return errmsg "Can't navigate to c-frame\n" if c_frame?(abs_frame_pos) + else + abs_frame_pos = navigate_to_frame(frame_pos) + end + + return errmsg "Can't navigate beyond the oldest frame\n" if + abs_frame_pos >= Context.stack_size + return errmsg "Can't navigate beyond the newest frame\n" if + abs_frame_pos < 0 + + @state.frame_pos = abs_frame_pos + @state.file = @state.context.frame_file @state.frame_pos + @state.line = @state.context.frame_line @state.frame_pos + @state.previous_line = nil + ListCommand.new(@state).execute + end + + def get_frame_class(style, pos) + frame_class = style == :short ? '' : "#{@state.context.frame_class pos}" + return frame_class == '' ? '' : "#{frame_class}." + end + + def get_frame_block_and_method(pos) + frame_deco_regexp = /((?:block(?: \(\d+ levels\))?|rescue) in )?(.+)/ + frame_deco_method = "#{@state.context.frame_method pos}" + frame_block_and_method = frame_deco_regexp.match(frame_deco_method)[1..2] + return frame_block_and_method.map{ |x| x.nil? ? '' : x } + end + + def get_frame_args(style, pos) + args = @state.context.frame_args pos + return '' if args.empty? + + locals = @state.context.frame_locals pos if style == :long + my_args = args.map do |arg| + case arg[0] + when :block + prefix, default = '&', 'block' + when :rest + prefix, default = '*', 'args' + else + prefix, default = '', nil + end + klass = style == :long && arg[1] ? "##{locals[arg[1]].class}" : '' + "#{prefix}#{arg[1] || default}#{klass}" + end + + return "(#{my_args.join(', ')})" + end + + def get_frame_call(prefix, pos) + frame_block, frame_method = get_frame_block_and_method(pos) + frame_class = get_frame_class(Command.settings[:callstyle], pos) + frame_args = get_frame_args(Command.settings[:callstyle], pos) + + call_str = frame_block + frame_class + frame_method + frame_args + + max_call_str_size = Command.settings[:width] - prefix.size + if call_str.size > max_call_str_size + call_str = call_str[0..max_call_str_size - 5] + "...)" + end + + return call_str + end + + def print_backtrace + realsize = Context.stack_size + calcedsize = @state.context.calced_stack_size + if calcedsize != realsize + if Byebug.post_mortem? + stacksize = calcedsize + else + errmsg "Byebug's stacksize (#{calcedsize}) should be #{realsize}. " \ + "This might be a bug in byebug or ruby's debugging API's\n" + stacksize = realsize + end + else + stacksize = calcedsize + end + (0...stacksize).each do |idx| + print_frame(idx) + end + end + + def print_frame(pos, mark_current = true) + file = @state.context.frame_file pos + line = @state.context.frame_line pos + + unless Command.settings[:fullpath] + path_components = file.split(/[\\\/]/) + if path_components.size > 3 + path_components[0...-3] = '...' + file = path_components.join(File::ALT_SEPARATOR || File::SEPARATOR) + end + end + + if mark_current + frame_str = (pos == @state.frame_pos) ? '--> ' : ' ' + else + frame_str = "" + end + frame_str += c_frame?(pos) ? ' ͱ-- ' : '' + + frame_str += sprintf "#%-2d ", pos + frame_str += get_frame_call frame_str, pos + file_line = "at #{CommandProcessor.canonic_file(file)}:#{line}" + if frame_str.size + file_line.size + 1 > Command.settings[:width] + frame_str += "\n #{file_line}\n" + else + frame_str += " #{file_line}\n" + end + + print frame_str + end + end + + # Implements byebug "where" or "backtrace" command. + class WhereCommand < Command + def regexp + /^\s* (?:w(?:here)?|bt|backtrace) \s*$/x + end + + def execute + print_backtrace + end + + class << self + def names + %w(where backtrace) + end + + def description + %{w[here]|bt|backtrace\tdisplay stack frames + + Print the entire stack frame. Each frame is numbered; the most recent + frame is 0. A frame number can be referred to in the "frame" command; + "up" and "down" add or subtract respectively to frame numbers shown. + The position of the current frame is marked with -->. C-frames hang + from their most immediate Ruby frame to indicate that they are not + navigable} + end + end + end + + class UpCommand < Command + def regexp + /^\s* u(?:p)? (?:\s+(\S+))? \s*$/x + end + + def execute + pos = get_int(@match[1], "Up") + return unless pos + adjust_frame(pos, false) + end + + class << self + def names + %w(up) + end + + def description + %{up[ count]\tmove to higher frame} + end + end + end + + class DownCommand < Command + def regexp + /^\s* down (?:\s+(\S+))? \s*$/x + end + + def execute + pos = get_int(@match[1], "Down") + return unless pos + adjust_frame(-pos, false) + end + + class << self + def names + %w(down) + end + + def description + %{down[ count]\tmove to lower frame} + end + end + end + + class FrameCommand < Command + def regexp + /^\s* f(?:rame)? (?:\s+(\S+))? \s*$/x + end + + def execute + return print_frame @state.frame_pos unless @match[1] + return unless pos = get_int(@match[1], "Frame") + adjust_frame(pos, true) + end + + class << self + def names + %w(frame) + end + + def description + %{f[rame][ frame-number] + + Move the current frame to the specified frame number, or the 0 if no + frame-number has been given. + + A negative number indicates position from the other end, so "frame -1" + moves to the oldest frame, and "frame 0" moves to the newest frame. + + Without an argument, the command prints the current stack frame. Since + the current position is redisplayed, it may trigger a resyncronization + if there is a front end also watching over things.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/help.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/help.rb new file mode 100644 index 0000000..ff4f96f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/help.rb @@ -0,0 +1,50 @@ +module Byebug + + # Implements byebug "help" command. + class HelpCommand < Command + include Columnize + + self.allow_in_control = true + + def regexp + /^\s* h(?:elp)? (?:\s+(.+))? \s*$/x + end + + def execute + if @match[1] + args = @match[1].split + cmds = @state.commands.select { |cmd| cmd.names.include?(args[0]) } + unless cmds.empty? + help = cmds.map{ |cmd| cmd.help(args) }.join("\n") + help = help.split("\n").map{|l| l.gsub(/^ +/, '')} + help.shift if help.first && help.first.empty? + help.pop if help.last && help.last.empty? + return print help.join("\n") + "\n" + else + return errmsg "Undefined command: \"#{args[0]}\". Try \"help\".\n" if + args[0] + end + end + + print "byebug help v#{Byebug::VERSION}\n" unless + Command.settings[:testing] + + print "Type \"help \" for help on a specific command\n\n" + print "Available commands:\n" + cmds = @state.commands.map{ |cmd| cmd.names }.flatten.uniq.sort + print columnize(cmds, Command.settings[:width]) + end + + class << self + def names + %w(help) + end + + def description + %{h[elp]\t\tprint this help + h[elp] command\tprint help on command + h[elp] command subcommand\tprint help on subcommand} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/info.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/info.rb new file mode 100644 index 0000000..19d5d1e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/info.rb @@ -0,0 +1,301 @@ +module Byebug + + module InfoFunctions + def info_catch(*args) + return print "No frame selected.\n" unless @state.context + + if Byebug.catchpoints and not Byebug.catchpoints.empty? + Byebug.catchpoints.each do |exception, hits| + print "#{exception}: #{exception.is_a?(Class)}\n" + end + else + print "No exceptions set to be caught.\n" + end + end + end + + # Implements byebug "info" command. + class InfoCommand < Command + include Columnize + self.allow_in_control = true + + Subcommands = [ + ['args' , 1, 'Argument variables of current stack frame' ], + ['breakpoints' , 1, 'Status of user-settable breakpoints', + 'Without argument, list info about all ' \ + 'breakpoints. With an integer argument, ' \ + 'list info on that breakpoint.' ], + ['catch' , 3, 'Exceptions that can be caught in the ' \ + 'current stack frame' ], + ['display' , 2, 'Expressions to display when program stops' ], + ['file' , 4, 'Info about a particular file read in', + 'After the file name is supplied, you can' \ + 'list file attributes that you wish to ' \ + 'see. Attributes include: "all", "basic",' \ + ' "breakpoint", "lines", "mtime", "path" ' \ + 'and "sha1".' ], + ['files' , 5, 'File names and timestamps of files read in' ], + ['global_variables' , 2, 'Global variables' ], + ['instance_variables', 2, 'Instance variables in current stack frame' ], + ['line' , 2, 'Line number and file name of current ' \ + 'position in source file' ], + ['locals' , 2, 'Local variables of the current stack frame' ], + ['program' , 2, 'Execution status of the program' ], + ['stack' , 2, 'Backtrace of the stack' ], + ['variables' , 1, 'Local and instance variables of the ' \ + 'current stack frame' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(Subcommands) + + InfoFileSubcommands = [ + ['all' , 1, 'All file information available - breakpoints, ' \ + 'lines, mtime, path and sha1' ], + ['basic' , 2, 'basic information - path, number of lines' ], + ['breakpoints', 2, 'Show trace line numbers', + 'These are the line number where a breakpoint ' \ + 'can be set.' ], + ['lines' , 1, 'Show number of lines in the file' ], + ['mtime' , 1, 'Show modification time of file' ], + ['path' , 4, 'Show full file path name for file' ], + ['sha1' , 1, 'Show SHA1 hash of contents of the file' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(InfoFileSubcommands) + + def regexp + /^\s* i(?:nfo)? (?:\s+(.+))? \s*$/x + end + + def execute + return print InfoCommand.help(nil) unless @match[1] + + args = @match[1].split(/[ \t]+/) + param = args.shift + subcmd = Command.find(Subcommands, param) + return errmsg "Unknown info command #{param}\n" unless subcmd + + if @state.context + send("info_#{subcmd.name}", *args) + else + errmsg "info_#{subcmd.name} not available without a context.\n" + end + end + + def info_args(*args) + locals = @state.context.frame_locals + args = @state.context.frame_args + return if args == [[:rest]] + + args.map do |_, name| + s = "#{name} = #{locals[name].inspect}" + pad_with_dots(s) + print "#{s}\n" + end + end + + def info_breakpoint(brkpt) + expr = brkpt.expr.nil? ? '' : " if #{brkpt.expr}" + print "%-3d %-3s at %s:%s%s\n" % + [brkpt.id, brkpt.enabled? ? 'y' : 'n', brkpt.source, brkpt.pos, expr] + hits = brkpt.hit_count + if hits > 0 + s = (hits > 1) ? 's' : '' + print "\tbreakpoint already hit #{hits} time#{s}\n" + end + end + private :info_breakpoint + + def info_breakpoints(*args) + return print "No breakpoints.\n" if Byebug.breakpoints.empty? + + brkpts = Byebug.breakpoints.sort_by{|b| b.id} + unless args.empty? + indices = args.map{|a| a.to_i} + brkpts = brkpts.select{|b| indices.member?(b.id)} + return errmsg "No breakpoints found among list given.\n" if + brkpts.empty? + end + print "Num Enb What\n" + brkpts.each { |b| info_breakpoint(b) } + end + + def info_display(*args) + return print "There are no auto-display expressions now.\n" unless + @state.display.find{|d| d[0]} + + print "Auto-display expressions now in effect:\n" \ + "Num Enb Expression\n" + n = 1 + for d in @state.display + print "%3d: %s %s\n" % [n, (d[0] ? 'y' : 'n'), d[1]] + n += 1 + end + end + + def info_file_path(file) + print "File #{file}" + path = File.expand_path(file) + print " - #{path}\n" if path and path != file + end + private :info_file_path + + def info_file_lines(file) + lines = LineCache.size(file) + print "\t #{lines} lines\n" if lines + end + private :info_file_lines + + def info_file_breakpoints(file) + breakpoints = LineCache.trace_line_numbers(file) + if breakpoints + print "\tbreakpoint line numbers:\n" + print columnize(breakpoints.to_a.sort, Command.settings[:width]) + end + end + private :info_file_breakpoints + + def info_file_mtime(file) + stat = LineCache.stat(file) + print "\t#{stat.mtime}\n" if stat + end + private :info_file_mtime + + def info_file_sha1(file) + print "\t#{LineCache.sha1(file)}\n" + end + private :info_file_sha1 + + def info_file(*args) + return info_files unless args[0] + + subcmd = Command.find(InfoFileSubcommands, args[1] || 'basic') + return errmsg "Invalid parameter #{args[1]}\n" unless subcmd + + if %w(all basic).member?(subcmd.name) + info_file_path(args[0]) + info_file_lines(args[0]) + if subcmd.name == 'all' + info_file_breakpoints(args[0]) + info_file_mtime(args[0]) + info_file_sha1(args[0]) + end + else + print "File #{args[0]}\n" if subcmd.name != 'path' + send("info_file_#{subcmd.name}", args[0]) + end + end + + def info_files(*args) + files = SCRIPT_LINES__.keys + files.uniq.sort.each do |file| + info_file_path(file) + info_file_mtime(file) + end + end + + def info_instance_variables(*args) + obj = bb_eval('self') + var_list(obj.instance_variables) + end + + def info_line(*args) + print "Line #{@state.line} of \"#{@state.file}\"\n" + end + + def info_locals(*args) + locals = @state.context.frame_locals + print_hash(locals) + end + + def print_hash(vars) + vars.keys.sort.each do |name| + begin + s = "#{name} = #{vars[name].inspect}" + rescue + begin + s = "#{name} = #{vars[name].to_s}" + rescue + s = "#{name} = *Error in evaluation*" + end + end + pad_with_dots(s) + print "#{s}\n" + end + end + private :print_hash + + def info_stop_reason(stop_reason) + case stop_reason + when :step + print "It stopped after stepping, next'ing or initial start.\n" + when :breakpoint + print("It stopped at a breakpoint.\n") + when :catchpoint + print("It stopped at a catchpoint.\n") + else + print "unknown reason: %s\n" % @state.context.stop_reason.to_s + end + end + private :info_stop_reason + + def info_program(*args) + if @state.context.dead? + print "The program crashed.\n" + print "Exception: #{Byebug.last_exception.inspect}\n" if Byebug.last_exception + return + end + + print "Program stopped. " + info_stop_reason @state.context.stop_reason + end + + def info_stack(*args) + print_backtrace + end + + def info_global_variables(*args) + var_global + end + + def info_variables(*args) + locals = @state.context.frame_locals + locals[:self] = @state.context.frame_self(@state.frame_pos) + print_hash(locals) + + obj = bb_eval('self') + var_list(obj.instance_variables, obj.instance_eval{binding()}) + var_class_self + end + + class << self + def names + %w(info) + end + + def description + %{info[ subcommand] + + Generic command for showing things about the program being debugged.} + end + + def help(args) + return description + format_subcmds unless args and args[1] + + return format_subcmd(args[1]) unless 'file' == args[1] and args[2] + + str = subcmd.short_help + '.' + subsubcmd = Command.find(InfoFileSubcommands, args[2]) + if subsubcmd + str += "\nInvalid \"file\" attribute \"#{args[2]}\"." + else + str += "\n" + subsubcmd.short_help + '.' + end + + return str + end + end + + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/kill.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/kill.rb new file mode 100644 index 0000000..90dedb6 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/kill.rb @@ -0,0 +1,44 @@ +module Byebug + + # Implements byebug "kill" command + class KillCommand < Command + self.allow_in_control = true + + def regexp + /^\s* (?:kill) \s* (?:\s+(\S+))? \s*$/x + end + + def execute + if @match[1] + signame = @match[1] + unless Signal.list.member?(signame) + errmsg("signal name #{signame} is not a signal I know about\n") + return false + end + if 'KILL' == signame + @state.interface.finalize + end + else + if not confirm("Really kill? (y/n) ") + return + else + signame = 'KILL' + end + end + Process.kill(signame, Process.pid) + end + + class << self + def names + %w(kill) + end + + def description + %{kill[ SIGNAL] + + Send [signal] to Process.pid + Equivalent of Process.kill(Process.pid)} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/list.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/list.rb new file mode 100644 index 0000000..6806316 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/list.rb @@ -0,0 +1,121 @@ +module Byebug + + # Implements byebug "list" command. + class ListCommand < Command + + register_setting_get(:autolist) do + ListCommand.always_run + end + register_setting_set(:autolist) do |value| + ListCommand.always_run = value + end + + # Set default value + Command.settings[:autolist] = 1 + + def regexp + /^\s* l(?:ist)? (?:\s*([-=])|\s+(\S+))? \s*$/x + end + + def execute + Byebug.source_reload if Command.settings[:autoreload] + lines = getlines(@state.file, @state.line) + if !lines + errmsg "No sourcefile available for #{@state.file}\n" + return @state.previous_line + end + + b, e = set_line_range(Command.settings[:listsize], lines.size) + return @state.previous_line if b < 0 + + print "\n[#{b}, #{e}] in #{@state.file}\n" + @state.previous_line = display_list(b, e, lines, @state.line) + end + + class << self + def names + %w(list) + end + + def description + %{l[ist]\t\tlist forward + l[ist] -\tlist backward + l[ist] =\tlist current line + l[ist] nn-mm\tlist given lines + * NOTE - to turn on autolist, use 'set autolist'} + end + end + + private + + ## + # Set line range to be printed by list + # + # @param listsize - number of lines to be printed + # @param maxline - max line number that can be printed + # + def set_line_range(listsize, maxline) + if !@match || !(@match[1] || @match[2]) + b = @state.previous_line ? + @state.previous_line + listsize : @state.line - (listsize/2) + elsif @match[1] == '-' + b = if @state.previous_line + if @state.previous_line > 0 + @state.previous_line - listsize + else + @state.previous_line + end + else + @state.line - (listsize/2) + end + elsif @match[1] == '=' + @state.previous_line = nil + b = @state.line - (listsize/2) + else + b, e = @match[2].split(/[-,]/) + if e + b = b.to_i + e = e.to_i + else + b = b.to_i - (listsize/2) + end + end + + if b > maxline + errmsg "Invalid line range" + return [ -1, -1 ] + end + + b = [1, b].max + e ||= b + listsize - 1 + + if e > maxline + e = maxline + b = e - listsize + 1 + b = [1, b].max + end + + return [ b, e ] + end + + ## + # Show file lines in LINES from line B to line E where CURRENT is the + # current line number. If we can show from B to E then we return B, + # otherwise we return the previous line @state.previous_line. + # + def display_list(b, e, lines, current) + width = e.to_s.size + b.upto(e) do |n| + if n > 0 && lines[n-1] + if n == current + print "=> %#{width}d: %s\n", n, lines[n-1].chomp + else + print " %#{width}d: %s\n", n, lines[n-1].chomp + end + end + end + print "\n" + return e == lines.size ? @state.previous_line : b + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/method.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/method.rb new file mode 100644 index 0000000..0149ad7 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/method.rb @@ -0,0 +1,77 @@ +module Byebug + + begin + require 'methodsig' + have_methodsig = true + rescue LoadError + have_methodsig = false + end + + # Implements byebug's 'method sig' command. + class MethodSigCommand < Command + def regexp + /^\s* m(?:ethod)? \s+ sig(?:nature)? \s+ (\S+) \s*$/x + end + + def execute + obj = bb_eval('method(:%s)' % @match[1]) + if obj.is_a?(Method) + begin + print "%s\n", obj.signature.to_s + rescue + errmsg("Can't get signature for '#{@match[1]}'\n") + end + else + errmsg("Can't make method out of '#{@match[1]}'\n") + end + end + + class << self + def names + %w(method) + end + + def description + %{m[ethod] sig[nature] \tshow the signature of a method} + end + end + end if have_methodsig + + # Implements byebug's 'method' command. + class MethodCommand < Command + include Columnize + + def regexp + /^\s* m(?:ethod)? \s+ ((iv)|(i(:?nstance)?)\s+)?/x + end + + def execute + obj = bb_eval(@match.post_match) + if @match[1] == "iv" + obj.instance_variables.sort.each do |v| + print "#{v} = #{obj.instance_variable_get(v).inspect}\n" + end + elsif @match[1] + print "#{columnize(obj.methods.sort(), Command.settings[:width])}\n" + else + return print "Should be Class/Module: #{@match.post_match}\n" unless + obj.kind_of? Module + print "#{columnize(obj.instance_methods(false).sort(), + Command.settings[:width])}\n" + end + end + + class << self + def names + %w(method) + end + + def description + %{m[ethod] i[nstance] \tshow methods of object + m[ethod] iv \t\tshow instance variables of object + m[ethod] \t\tshow instance methods of class or module} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/quit.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/quit.rb new file mode 100644 index 0000000..388c71e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/quit.rb @@ -0,0 +1,32 @@ +module Byebug + + # Implements byebug "quit" command + class QuitCommand < Command + self.allow_in_control = true + + def regexp + /^\s* (?:q(?:uit)?|exit) \s* (!|\s+unconditionally)? \s*$/x + end + + def execute + if @match[1] or confirm("Really quit? (y/n) ") + @state.interface.finalize + exit! # exit -> exit!: No graceful way to stop... + end + end + + class << self + def names + %w(quit exit) + end + + def description + %{q[uit]|exit [!|unconditionally]\tExits from byebug. + + Normally we prompt before exiting. However if the parameter + "unconditionally" is given or command is suffixed with !, we exit + without asking further questions.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/reload.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/reload.rb new file mode 100644 index 0000000..587aa63 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/reload.rb @@ -0,0 +1,50 @@ +module Byebug + + module ReloadFunctions + def getlines(file, line) + unless (lines = SCRIPT_LINES__[file]) and lines != true + Tracer::Single.get_line(file, line) if File.exist?(file) + lines = SCRIPT_LINES__[file] + lines = nil if lines == true + end + lines + end + end + + # Implements byebug "reload" command. + class ReloadCommand < Command + self.allow_in_control = true + self.allow_in_post_mortem = false + + register_setting_get(:autoreload) do + Byebug.class_variable_get(:@@autoreload) + end + + register_setting_set(:autoreload) do |value| + Byebug.class_variable_set(:@@autoreload, value) + end + Command.settings[:autoreload] = true + + def regexp + /^\s* r(?:eload)? \s*$/x + end + + def execute + Byebug.source_reload + print "Source code is reloaded. Automatic reloading is " \ + "#{Command.settings[:autoreload] ? 'on' : 'off'}.\n" + end + + private + + class << self + def names + %w(reload) + end + + def description + %{r[eload]\tforces source code reloading} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/repl.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/repl.rb new file mode 100644 index 0000000..17a8ef5 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/repl.rb @@ -0,0 +1,138 @@ +module IRB + module ExtendCommand + class Continue + def self.execute(conf) + throw :IRB_EXIT, :cont + end + end + class Next + def self.execute(conf) + throw :IRB_EXIT, :next + end + end + class Step + def self.execute(conf) + throw :IRB_EXIT, :step + end + end + end + + require 'irb' + ExtendCommandBundle.def_extend_command "cont", :Continue + ExtendCommandBundle.def_extend_command "n", :Next + ExtendCommandBundle.def_extend_command "step", :Step + + def self.start_session(binding) + unless @__initialized ||= false + args = ARGV.dup + ARGV.replace([]) + IRB.setup(nil) + ARGV.replace(args) + @__initialized = true + end + + workspace = WorkSpace.new(binding) + irb = Irb.new(workspace) + + @CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC] + @CONF[:MAIN_CONTEXT] = irb.context + + trap("SIGINT") do + irb.signal_handle + end + + catch(:IRB_EXIT) do + irb.eval_input + end + end +end + +module Byebug + + # Implements byebug's "irb" command. + class IRBCommand < Command + register_setting_get(:autoirb) do + IRBCommand.always_run + end + register_setting_set(:autoirb) do |value| + IRBCommand.always_run = value + end + + def regexp + /^\s* irb \s*$/x + end + + def execute + unless @state.interface.kind_of?(LocalInterface) + print "Command is available only in local mode.\n" + throw :debug_error + end + + cont = IRB.start_session(get_binding) + case cont + when :cont + @state.proceed + when :step + force = Command.settings[:forcestep] + @state.context.step_into 1, force + @state.proceed + when :next + force = Command.settings[:forcestep] + @state.context.step_over 1, @state.frame_pos, force + @state.proceed + else + print @state.location + @state.previous_line = nil + end + end + + + class << self + def names + %w(irb) + end + + def description + %{irb\tstarts an Interactive Ruby (IRB) session. + + IRB is extended with methods "cont", "n" and "step" which run the + corresponding byebug commands. In contrast to the real byebug commands + these commands don't allow arguments.} + end + end + end + + begin + require 'pry' + has_pry = true + rescue LoadError + has_pry = false + end + + # Implements byebug's "pry" command + class PryCommand < Command + def regexp + /^\s* pry \s*$/x + end + + def execute + unless @state.interface.kind_of?(LocalInterface) + print "Command is available only in local mode.\n" + throw :debug_error + end + + get_binding.pry + end + + class << self + def names + %w(pry) + end + + def description + %{pry\tstarts a Pry session.} + end + end + end if has_pry + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/save.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/save.rb new file mode 100644 index 0000000..749d77b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/save.rb @@ -0,0 +1,87 @@ +module Byebug + + module SaveFunctions + # Create a temporary file to write in if file is nil + def open_save + require "tempfile" + file = Tempfile.new("byebug-save") + # We want close to not unlink, so redefine. + def file.close + @tmpfile.close if @tmpfile + end + return file + end + end + + class SaveCommand < Command + self.allow_in_control = true + + def save_breakpoints(file) + Byebug.breakpoints.each do |b| + file.puts "break #{b.source}:#{b.pos}#{" if #{b.expr}" if b.expr}" + end + end + + def save_catchpoints(file) + Byebug.catchpoints.keys.each do |c| + file.puts "catch #{c}" + end + end + + def save_displays(file) + for d in @state.display + if d[0] + file.puts "display #{d[1]}" + end + end + end + + def save_settings(file) + # FIXME put routine in set + %w(autoeval basename testing).each do |setting| + on_off = show_onoff(Command.settings[setting.to_sym]) + file.puts "set #{setting} #{on_off}" + end + %w(autolist autoirb).each do |setting| + on_off = show_onoff(Command.settings[setting.to_sym] > 0) + file.puts "set #{setting} #{on_off}" + end + end + + def regexp + /^\s* sa(?:ve)? (?:\s+(\S+))? \s*$/x + end + + def execute + if not @match[1] + file = open_save() + else + file = open(@match[1], 'w') + end + save_breakpoints(file) + save_catchpoints(file) + save_displays(file) + save_settings(file) + print "Saved to '#{file.path}'\n" + if @state and @state.interface + @state.interface.restart_file = file.path + end + file.close + end + + class << self + def names + %w(save) + end + + def description + %{save[ FILE] + + Saves current byebug state to FILE as a script file. This includes + breakpoints, catchpoints, display expressions and some settings. If + no filename is given, we will fabricate one. + Use the "source" command in another debug session to restore them.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/set.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/set.rb new file mode 100644 index 0000000..b6ddeb9 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/set.rb @@ -0,0 +1,159 @@ +module Byebug + + # Mix-in module to setting settings + module SetFunctions + + def set_setting(setting_name, setting_value, setting_args) + case setting_name + when /^args$/ + if defined?(Byebug::BYEBUG_SCRIPT) + Command.settings[:argv][1..-1] = setting_args + else + Command.settings[:argv] = setting_args + end + when /^autoirb$/ + Command.settings[:autoirb] = (setting_value ? 1 : 0) + when /^autolist$/ + Command.settings[:autolist] = (setting_value ? 1 : 0) + when /^callstyle$/ + if setting_args[0] and ['short', 'long'].include?(setting_args[0]) + Command.settings[:callstyle] = setting_args[0].to_sym + else + print "Invalid callstyle. Should be one of: \"short\" or \"long\"\n" + end + when /^verbose$/ + Byebug.verbose = setting_value + when /^history$/ + try_subcmd = setting_args[0] + subcmd = Command.find(SetCommand::SetHistorySubcommands, try_subcmd) + return print "Invalid history parameter #{try_subcmd}. Should be" \ + ' "filename", "save" or "size"' unless subcmd + + sub_sub_cmd = setting_args[1] + iface = @state.interface + case subcmd.name + when /^save$/ + iface.history_save = sub_sub_cmd ? get_onoff(sub_sub_cmd) : true + when /^size$/ + return print 'You need to specify the history size' unless sub_sub_cmd + iface.history_length = get_int(sub_sub_cmd, "Set history size") + when /^filename$/ + return print 'You need to specify a filename' unless sub_sub_cmd + iface.histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", sub_sub_cmd) + end + when /^linetrace$/ + Byebug.tracing = setting_value + when /^listsize$/ + listsize = get_int(setting_args[0], "Set listsize", 1, nil, 10) + return unless listsize + Command.settings[:listsize] = listsize + when /^width$/ + return unless width = get_int(setting_args[0], "Set width", 10, nil, 80) + Command.settings[:width] = width + when /^post_mortem$/ + if setting_value == true + Byebug.post_mortem + else + return print 'Sorry... not implemented yet. Restart byebug' + end + when /^autoeval|autoreload|basename|forcestep|fullpath|linetrace_plus| + testing|stack_on_error$/x + Command.settings[setting_name.to_sym] = setting_value + else + return print "Unknown setting #{@match[1]}.\n" + end + end + end + + # Implements byebug "set" command. + class SetCommand < Command + Subcmd2 = Struct.new(:name, :min, :is_bool, :help) unless defined?(Subcmd2) + + Subcommands = [ + ['args' , 2 , false, 'Set argument list to the program ' \ + 'being debugged when it is started' ], + ['autoeval' , 4 , true , 'Evaluate every unrecognized command' ], + ['autolist' , 4 , true , 'Execute "list" command on every ' \ + 'breakpoint' ], + ['autoirb' , 4 , true , 'Invoke IRB on every stop' ], + ['autoreload' , 4 , true , 'Reload source code when changed' ], + ['basename' , 1 , true , 'Set filename display style' ], + ['callstyle' , 2 , false, 'Set how you want call parameters ' \ + 'displayed' ], + ['testing' , 2 , false, 'Used when testing byebug' ], + ['forcestep' , 2 , true , 'Make sure "next/step" commands always' \ + 'move to a new line' ], + ['fullpath' , 2 , true , 'Display full file names in frames' ], + ['history' , 2 , false, 'Command for setting command history ' \ + 'parameters, namely, "filename", ' \ + '"save" and "size"' ], + ['linetrace' , 3 , true , 'Enable line execution tracing' ], + ['linetrace_plus', 10, true , 'Set line execution tracing to show' \ + 'different lines' ], + ['listsize' , 3 , false, 'Set number of source lines to list by' \ + 'default' ], + ['post_mortem' , 2 , true , 'Enable post-mortem mode' ], + ['stack_on_error', 1 , true , 'Display stack trace when "eval" ' \ + 'raises exception' ], + ['verbose' , 1 , true , 'Enable verbose output of TracePoint ' \ + 'API events is enabled' ], + ['width' , 1 , false, 'Number of characters per line for ' \ + 'byebug\'s output' ] + ].map do |name, min, is_bool, help| + Subcmd2.new(name, min, is_bool, help) + end unless defined?(Subcommands) + + SetHistorySubcommands = [ + ['filename', 1, 'Set the filename in which to record command history'], + ['save' , 1, 'Set saving of the history record on exit' ], + ['size' , 1, 'Set the size of the command history' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(SetHistorySubcommands) + + self.allow_in_control = true + + def regexp + /^\s* set (?:\s+(.*))? \s*$/x + end + + def execute + return print SetCommand.help(nil) if SetCommand.names.include?(@match[0]) + + args = @match[1].split(/[ \t]+/) + try_subcmd = args.shift + try_subcmd.downcase! + if try_subcmd =~ /^no/i + set_on = false + try_subcmd = try_subcmd[2..-1] + else + set_on = true + end + + subcmd = Command.find(Subcommands, try_subcmd) + return print "Unknown set command \"#{try_subcmd}\"\n" unless subcmd + + begin + set_on = get_onoff(args[0]) if subcmd.is_bool and args.size > 0 + rescue RuntimeError + return + end + + set_setting(subcmd.name, set_on, args) + + return print "#{show_setting(subcmd.name)}\n" + end + + class << self + def names + %w(set) + end + + def description + %{Modifies parts of byebug environment. Boolean values take on, off, 1 + or 0. You can see these environment settings with the "show" command.} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/show.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/show.rb new file mode 100644 index 0000000..58ef987 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/show.rb @@ -0,0 +1,224 @@ +module Byebug + + # Mix-in module to showing settings + module ShowFunctions + + def show_setting(setting_name) + case setting_name + when /^args$/ + if Command.settings[:argv] and Command.settings[:argv].size > 0 + if defined?(Byebug::BYEBUG_SCRIPT) + # byebug was called initially. 1st arg is script name. + args = Command.settings[:argv][1..-1].join(' ') + else + # byebug wasn't called initially. 1st arg is not script name. + args = Command.settings[:argv].join(' ') + end + else + args = '' + end + return "Argument list to give program being debugged when it is started is \"#{args}\"." + when /^autolist$/ + on_off = Command.settings[:autolist] > 0 + return "autolist is #{show_onoff(on_off)}." + when /^autoeval$/ + on_off = Command.settings[:autoeval] + return "autoeval is #{show_onoff(on_off)}." + when /^autoreload$/ + on_off = Command.settings[:autoreload] + return "autoreload is #{show_onoff(on_off)}." + when /^autoirb$/ + on_off = Command.settings[:autoirb] > 0 + return "autoirb is #{show_onoff(on_off)}." + when /^basename$/ + on_off = Command.settings[:basename] + return "basename is #{show_onoff(on_off)}." + when /^callstyle$/ + style = Command.settings[:callstyle] + return "Frame call-display style is #{style}." + when /^commands(:?\s+(\d+))?$/ + if @state.interface.readline_support? + s = ''; + args = @match[1].split + if args[1] + first_line = args[1].to_i - 4 + last_line = first_line + 10 - 1 + if first_line > Readline::HISTORY.length + first_line = last_line = Readline::HISTORY.length + elsif first_line <= 0 + first_line = 1 + end + if last_line > Readline::HISTORY.length + last_line = Readline::HISTORY.length + end + i = first_line + commands = Readline::HISTORY.to_a[first_line..last_line] + else + if Readline::HISTORY.length > 10 + commands = Readline::HISTORY.to_a[-10..-1] + i = Readline::HISTORY.length - 10 + else + commands = Readline::HISTORY.to_a + i = 1 + end + end + commands.each do |cmd| + s += ("%5d %s\n" % [i, cmd]) + i += 1 + end + else + s='No readline support' + end + return s + when /^testing$/ + on_off = Command.settings[:testing] + return "Currently testing byebug is #{show_onoff(on_off)}." + when /^forcestep$/ + on_off = Command.settings[:forcestep] + return "force-stepping is #{show_onoff(on_off)}." + when /^fullpath$/ + on_off = Command.settings[:fullpath] + return "Displaying frame's full file names is #{show_onoff(on_off)}." + when /^history(:?\s+(filename|save|size))?$/ + args = @match[1].split + interface = @state.interface + if args[1] + show_save = show_size = show_filename = false + prefix = false + if args[1] == "save" + show_save = true + elsif args[1] == "size" + show_size = true + elsif args[1] == "filename" + show_filename = true + end + else + show_save = show_size = show_filename = true + prefix = true + end + s = [] + if show_filename + msg = "#{prefix ? 'filename:' : ''} The command history file is " \ + "#{interface.histfile.inspect}" + s << msg + end + if show_save + msg = (prefix ? "save: " : "") + + "Saving of history save is #{show_onoff(interface.history_save)}." + s << msg + end + if show_size + msg = (prefix ? "size: " : "") + + "Byebug history size is #{interface.history_length}" + s << msg + end + return s.join("\n") + when /^linetrace$/ + on_off = Byebug.tracing? + return "line tracing is #{show_onoff(on_off)}." + when /^linetrace_plus$/ + if Command.settings[:linetrace_plus] + return "line tracing style is every line." + else + return "line tracing style is different consecutive lines." + end + when /^listsize$/ + listlines = Command.settings[:listsize] + return "Number of source lines to list is #{listlines}." + when /^post_mortem$/ + on_off = Byebug.post_mortem? + return "post-mortem mode is #{show_onoff(on_off)}" + when /^stack_on_error$/ + on_off = Command.settings[:stack_on_error] + return "Displaying stack trace is #{show_onoff(on_off)}." + when /^verbose$/ + on_off = Byebug.verbose + return "Verbose output of TracePoint API events is #{show_onoff(on_off)}." + when /^version$/ + return "Byebug #{Byebug::VERSION}" + when /^width$/ + return "width is #{Command.settings[:width]}." + else + return "Unknown show subcommand #{setting_name}." + end + end + end + + # Implements byebug "show" command. + class ShowCommand < Command + + Subcommands = [ + ['args' , 2 , 'Show argument list to the program being ' \ + 'debugged when it is started' ], + ['autoeval' , 4 , 'Show whether unrecognized commands are ' \ + 'evaluated' ], + ['autolist' , 4 , 'Show whether "list" command is run on stopping' ], + ['autoirb' , 4 , 'Show whether IRB is invoked on stopping' ], + ['autoreload' , 4 , 'Show whether source code is reloaded when ' \ + 'changed' ], + ['basename' , 1 , 'Show whether basename is used when reporting' \ + ' files' ], + ['callstyle' , 2 , 'Show parameter style used when showing call' \ + ' frames' ], + ['commands' , 2 , 'Show the history of commands you typed. You ' \ + 'can supply a command number to start with' ], + ['forcestep' , 1 , 'Show whether "next/step" commands are set to' \ + ' always move to a line' ], + ['fullpath' , 2 , 'Show whether full paths are displayed in frames'], + ['history' , 2 , 'Show command history configurations. ' ], + ['linetrace' , 3 , 'Show line execution tracing status' ], + ['linetrace_plus', 10, 'Show whether different consecutive lines are' \ + ' shown in tracing' ], + ['listsize' , 3 , 'Show number of source lines to list by default' ], + ['post_mortem' , 3 , 'Show whether we should go into post-mortem ' \ + 'debugging on an uncaught exception' ], + ['stack_on_error', 1 , 'Show whether a stack trace is displayed when' \ + ' "eval" raises an exception' ], + ['verbose' , 4 , 'Show whether verbose output for debugging ' \ + 'byebug itself is enabled' ], + ['version' , 1 , 'Show byebug\'s version' ], + ['width' , 1 , 'Show the number of characters per line for ' \ + 'byebug' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(Subcommands) + + ShowHistorySubcommands = [ + ['filename', 1, 'Show the filename in which to record command history' ], + ['save' , 1, 'Show whether history record should be saved on exit' ], + ['size' , 1, 'Show the size of the command history' ] + ].map do |name, min, help| + Subcmd.new(name, min, help) + end unless defined?(SetHistorySubcommands) + + self.allow_in_control = true + + def regexp + /^\s* show (?:\s+(.+))? \s*$/x + end + + def execute + return print ShowCommand.help(nil) unless @match[1] + + args = @match[1].split(/[ \t]+/) + param = args.shift + subcmd = Command.find(Subcommands, param) + if subcmd + print "%s\n" % show_setting(subcmd.name) + else + print "Unknown show command #{param}\n" + end + end + + class << self + def names + %w(show) + end + + def description + %{Generic command for showing things about byebug.} + end + end + + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/skip.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/skip.rb new file mode 100644 index 0000000..d3bd829 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/skip.rb @@ -0,0 +1,30 @@ +module Byebug + + # Implements byebug "skip" command + class SkipCommand < Command + self.allow_in_control = true + + def regexp + /^\s* sk(?:ip)? \s*$/x + end + + def execute + Byebug::skip_next_exception + print "ok\n" + end + + class << self + def names + %w(skip) + end + + def description + %{sk[ip]\tskip the next thrown exception + + This is useful if you've explicitly caught an exception through the + "catch" command, and wish to pass the exception on to the code that + you're debugging.} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/source.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/source.rb new file mode 100644 index 0000000..a353dc0 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/source.rb @@ -0,0 +1,36 @@ +module Byebug + + # Implements byebug "source" command. + class SourceCommand < Command + self.allow_in_control = true + + def regexp + /^\s* so(?:urce)? (?:\s+(\S+))? \s*$/x + end + + def execute + return print SourceCommand.help(nil) if + SourceCommand.names.include?(@match[0]) + + file = File.expand_path(@match[1]).strip + return errmsg "File \"#{file}\" not found\n" unless File.exist?(file) + + if @state and @state.interface + @state.interface.command_queue += File.open(file).readlines + else + Byebug.run_script(file, @state) + end + end + + class << self + def names + %w(source) + end + + def description + %{source FILE\texecutes a file containing byebug commands} + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/stepping.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/stepping.rb new file mode 100644 index 0000000..886c281 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/stepping.rb @@ -0,0 +1,78 @@ +module Byebug + + # Mix-in module to assist in command parsing. + module SteppingFunctions + def parse_stepping_args(command_name, match) + if match[1].nil? + force = Command.settings[:forcestep] + elsif match[1] == '+' + force = true + elsif match[1] == '-' + force = false + end + steps = get_int(match[2], command_name, 1) + return [steps, force] + end + end + + # Implements byebug "next" command. + class NextCommand < Command + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* n(?:ext)?([+-])? (?:\s+(\S+))? \s*$/x + end + + def execute + steps, force = parse_stepping_args("Next", @match) + return unless steps + @state.context.step_over steps, @state.frame_pos, force + @state.proceed + end + + class << self + def names + %w(next) + end + + def description + %{n[ext][+-]?[ nnn]\tstep over once or nnn times, + \t\t'+' forces to move to another line. + \t\t'-' is the opposite of '+' and disables the :forcestep setting. + } + end + end + end + + # Implements byebug "step" command. + class StepCommand < Command + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* s(?:tep)?([+-]) ?(?:\s+(\S+))? \s*$/x + end + + def execute + steps, force = parse_stepping_args("Step", @match) + return unless steps + @state.context.step_into steps, force + @state.proceed + end + + class << self + def names + %w(step) + end + + def description + %{ + s[tep][+-]?[ nnn]\tstep (into methods) once or nnn times + \t\t'+' forces to move to another line. + \t\t'-' is the opposite of '+' and disables the :forcestep setting. + } + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/threads.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/threads.rb new file mode 100644 index 0000000..6910cc6 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/threads.rb @@ -0,0 +1,204 @@ +module Byebug + module ThreadFunctions + def display_context(context, should_show_top_frame = true) + args = thread_arguments(context, should_show_top_frame) + print "%s%s%d %s\t%s\n", args[:status_flag], args[:debug_flag], args[:id], + args[:thread], args[:file_line] + end + + def thread_arguments(context, should_show_top_frame = true) + status_flag = if context.suspended? + "$" + else + context.thread == Thread.current ? '+' : ' ' + end + debug_flag = context.ignored? ? '!' : ' ' + if should_show_top_frame + if context.thread == Thread.current && !context.dead? + file = context.frame_file(0) + line = context.frame_line(0) + else + if context.thread.backtrace_locations && + context.thread.backtrace_locations[0] + file = context.thread.backtrace_locations[0].path + line = context.thread.backtrace_locations[0].lineno + end + end + file_line = "#{file}:#{line}" + end + { + status_flag: status_flag, + debug_flag: debug_flag, + id: context.thnum, + thread: context.thread.inspect, + file_line: file_line ? file_line : '' + } + end + + def parse_thread_num(subcmd, arg) + if '' == arg + errmsg "\"#{subcmd}\" needs a thread number" + nil + else + thread_num = get_int(arg, subcmd, 1) + return nil unless thread_num + get_context(thread_num) + end + end + + def parse_thread_num_for_cmd(subcmd, arg) + c = parse_thread_num(subcmd, arg) + return nil unless c + case + when nil == c + errmsg 'No such thread' + when @state.context == c + errmsg "It's the current thread" + when c.ignored? + errmsg "Can't #{subcmd} thread #{arg}" + else + return c + end + return nil + end + + end + + class ThreadListCommand < Command + self.allow_in_control = true + + def regexp + /^\s* th(?:read)? \s+ l(?:ist)? \s*$/x + end + + def execute + Byebug.contexts.select { |c| Thread.list.include?(c.thread) } + .sort_by(&:thnum).each { |c| display_context(c) } + end + + class << self + def names + %w(thread) + end + + def description + %{ + th[read] l[ist]\t\t\tlist all threads + } + end + end + end + + class ThreadCurrentCommand < Command + self.need_context = true + + def regexp + /^\s* th(?:read)? \s+ (?:cur(?:rent)?)? \s*$/x + end + + def execute + display_context(@state.context) + end + + class << self + def names + %w(thread) + end + + def description + %{th[read] [cur[rent]]\t\tshow current thread} + end + end + end + + class ThreadStopCommand < Command + self.allow_in_control = true + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* th(?:read)? \s+ stop \s* (\S*) \s*$/x + end + + def execute + c = parse_thread_num_for_cmd('thread stop', @match[1]) + return unless c + c.suspend + display_context(c) + end + + class << self + def names + %w(thread) + end + + def description + %{th[read] stop \t\tstop thread nnn} + end + end + end + + class ThreadResumeCommand < Command + self.allow_in_control = true + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* th(?:read)? \s+ resume \s* (\S*) \s*$/x + end + + def execute + c = parse_thread_num_for_cmd('thread resume', @match[1]) + return unless c + if !c.suspended? + errmsg 'Already running' + return + end + c.resume + display_context(c) + end + + class << self + def names + %w(thread) + end + + def description + %{th[read] resume \t\tresume thread nnn} + end + end + end + + class ThreadSwitchCommand < Command + self.allow_in_control = true + self.allow_in_post_mortem = false + self.need_context = true + + def regexp + /^\s* th(?:read)? \s+ (?:sw(?:itch)?\s+)? (\S+) \s*$/x + end + + def execute + if @match[1] =~ /switch/ + errmsg '"thread switch" needs a thread number' + return + end + c = parse_thread_num_for_cmd('thread switch', @match[1]) + return unless c + display_context(c) + c.step_into 1 + c.thread.run + @state.proceed + end + + class << self + def names + %w(thread) + end + + def description + %{th[read] [sw[itch]] \tswitch thread context to nnn} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/trace.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/trace.rb new file mode 100644 index 0000000..547b9be --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/trace.rb @@ -0,0 +1,49 @@ +module Byebug + + class TraceCommand < Command + def regexp + /^\s* tr(?:ace)? (?: \s+ (\S+)) # on | off | var(iable) + (?: \s+ (\S+))? # (variable-name)? + (?: \s+ (\S+))? # (stop | nostop)? + \s*$/x + end + + def execute + if @match[1] =~ /on|off/ + onoff = 'on' == @match[1] + Byebug.tracing = onoff + print "#{show_setting('linetrace')}\n" + elsif @match[1] =~ /var(?:iable)?/ + varname = @match[2] + if global_variables.include?("$#{varname}".to_sym) + if @match[3] && @match[3] !~ /(:?no)?stop/ + errmsg "expecting \"stop\" or \"nostop\"; got \"#{@match[3]}\"\n" + else + dbg_cmd = (@match[3] && @match[3] !~ /nostop/) ? 'byebug(1,0)' : '' + end + eval("trace_var(:\"\$#{varname}\") do |val| + print \"traced global variable '#{varname}' has value '\#{val}'\"\n + #{dbg_cmd} + end") + print "Tracing global variable \"#{varname}\".\n" + else + errmsg "'#{varname}' is not a global variable.\n" + end + else + errmsg "expecting \"on\", \"off\", \"var\" or \"variable\"; got: " \ + "\"#{@match[1]}\"\n" + end + end + + class << self + def names + %w(trace) + end + + def description + %{tr[ace] (on|off)\tset trace mode + tr[ace] var(iable) VARNAME [stop|nostop]\tset trace variable on VARNAME} + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/variables.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/variables.rb new file mode 100644 index 0000000..d229d4d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/commands/variables.rb @@ -0,0 +1,189 @@ +module Byebug + + module VarFunctions + def var_list(ary, b = get_binding) + ary.sort! + for v in ary + begin + s = bb_eval(v.to_s, b).inspect + rescue + begin + s = bb_eval(v.to_s, b).to_s + rescue + s = "*Error in evaluation*" + end + end + pad_with_dots(s) + print "#{v} = #{s}\n" + end + end + def var_class_self + obj = bb_eval('self') + var_list(obj.class.class_variables, get_binding) + end + def var_global + var_list(global_variables.reject { |v| [:$=, :$KCODE, :$-K].include?(v) }) + end + end + + # Implements byebug's 'var class' command + class VarClassVarCommand < Command + def regexp + /^\s* v(?:ar)? \s+ cl(?:ass)? \s*/x + end + + def execute + unless @state.context + errmsg "can't get class variables here.\n" + return + end + var_class_self + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] cl[ass] \t\t\tshow class variables of self} + end + end + end + + class VarConstantCommand < Command + def regexp + /^\s* v(?:ar)? \s+ co(?:nst(?:ant)?)? \s+/x + end + + def execute + obj = bb_eval(@match.post_match) + if obj.kind_of? Module + constants = bb_eval("#{@match.post_match}.constants") + constants.sort! + for c in constants + next if c =~ /SCRIPT/ + value = obj.const_get(c) rescue "ERROR: #{$!}" + print " %s => %p\n", c, value + end + else + print "Should be Class/Module: #{@match.post_match}\n" + end + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] co[nst] \t\tshow constants of object} + end + end + end + + class VarGlobalCommand < Command + def regexp + /^\s* v(?:ar)? \s+ g(?:lobal)? \s*$/x + end + + def execute + var_global + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] g[lobal]\t\t\tshow global variables} + end + end + end + + class VarInstanceCommand < Command + def regexp + /^\s* v(?:ar)? \s+ ins(?:tance)? \s*/x + end + + def execute + obj = bb_eval(@match.post_match.empty? ? 'self' : @match.post_match) + var_list(obj.instance_variables, obj.instance_eval{binding()}) + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] i[nstance] \tshow instance variables of object} + end + end + end + + # Implements byebug's 'var local' command + class VarLocalCommand < Command + def regexp + /^\s* v(?:ar)? \s+ l(?:ocal)? \s*$/x + end + + def execute + _self = @state.context.frame_self(@state.frame_pos) + locals = @state.context.frame_locals + locals.keys.sort.each do |name| + print " %s => %p\n", name, locals[name] + end + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] l[ocal]\t\t\tshow local variables} + end + end + end + + begin + require 'classtree' + have_classtree = true + rescue LoadError + have_classtree = false + end + + # Implements byebug's 'var inherit' command + class VarInheritCommand < Command + def regexp + /^\s* v(?:ar)? \s+ ct \s*$/x + end + + def execute + unless @state.context + errmsg "can't get object inheritance.\n" + return + end + puts @match.post_match + obj = bb_eval("#{@match.post_match}.classtree") + if obj + print obj + else + errmsg "Trouble getting object #{@match.post_match}\n" + end + end + + class << self + def names + %w(var) + end + + def description + %{v[ar] ct\t\t\tshow class heirarchy of object} + end + end + end if have_classtree + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/context.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/context.rb new file mode 100644 index 0000000..376991b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/context.rb @@ -0,0 +1,89 @@ +module Byebug + + class Context + + class << self + def stack_size + if backtrace = Thread.current.backtrace_locations(0) + backtrace.drop_while { |l| !ignored(l.path) } + .drop_while { |l| ignored(l.path) } + .take_while { |l| !ignored(l.path) } + .size + else + print 'No backtrace available!!' + 0 + end + end + + def real_stack_size + if backtrace = Thread.current.backtrace_locations(0) + backtrace.size + end + end + + def ignored(path) + IGNORED_FILES.include?(path) + end + private :ignored + end + + def interrupt + self.step_into 1 + end + + def frame_locals frame_no = 0 + bind = frame_binding frame_no + eval "local_variables.inject({}){|h, v| h[v] = eval(v.to_s); h}", bind + end + + def c_frame_args frame_no + myself = frame_self frame_no + return [] unless myself.to_s != 'main' + myself.send(:method, frame_method(frame_no)).parameters + end + + def ruby_frame_args bind + return [] unless eval '__method__', bind + begin + eval "self.method(__method__).parameters", bind + rescue NameError => e + print "WARNING: Got exception #{e.class}: \"#{e.message}\" " \ + "while retreving parameters from frame\n" + return [] + end + end + + def frame_args frame_no = 0 + bind = frame_binding frame_no + if bind.nil? + c_frame_args frame_no + else + ruby_frame_args bind + end + end + + def handler + Byebug.handler or raise 'No interface loaded' + end + + def at_breakpoint(brkpnt) + handler.at_breakpoint(self, brkpnt) + end + + def at_catchpoint(excpt) + handler.at_catchpoint(self, excpt) + end + + def at_tracing(file, line) + handler.at_tracing(self, file, line) + end + + def at_line(file, line) + handler.at_line(self, file, line) + end + + def at_return(file, line) + handler.at_return(self, file, line) + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/control_command_processor.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/control_command_processor.rb new file mode 100644 index 0000000..e3654d2 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/control_command_processor.rb @@ -0,0 +1,79 @@ +require 'forwardable' +require_relative 'interface' +require_relative 'command' + +module Byebug + + class ControlCommandProcessor < Processor + def initialize(interface) + super(interface) + @context_was_dead = false # Assume we haven't started. + end + + def process_commands(verbose=false) + control_cmds = Command.commands.select do |cmd| + cmd.allow_in_control + end + state = State.new(@interface, control_cmds) + commands = control_cmds.map{|cmd| cmd.new(state) } + + if @context_was_dead + print "The program finished.\n" + @context_was_dead = false + end + + while input = @interface.read_command(prompt(nil)) + print "+#{input}" if verbose + catch(:debug_error) do + if cmd = commands.find{|c| c.match(input) } + cmd.execute + else + errmsg "Unknown command\n" + end + end + end + rescue IOError, Errno::EPIPE + rescue Exception + print "INTERNAL ERROR!!! #{$!}\n" rescue nil + print $!.backtrace.map{|l| "\t#{l}"}.join("\n") rescue nil + ensure + @interface.close + end + + # + # Prompt shown before reading a command. + # + def prompt(context) + return '(byebug:ctrl) ' + end + + class State + attr_reader :commands, :interface + + def initialize(interface, commands) + @interface = interface + @commands = commands + end + + def proceed + end + + extend Forwardable + def_delegators :@interface, :errmsg, :print + + def confirm(*args) + 'y' + end + + def context + nil + end + + def file + errmsg "No filename given.\n" + throw :debug_error + end + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/helper.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/helper.rb new file mode 100644 index 0000000..90904f9 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/helper.rb @@ -0,0 +1,69 @@ +module Byebug + + module ParseFunctions + Position_regexp = '(?:(\d+)|(.+?)[:.#]([^.:\s]+))' + + # Parse 'str' of command 'cmd' as an integer between + # min and max. If either min or max is nil, that + # value has no bound. + def get_int(str, cmd, min=nil, max=nil, default=1) + return default unless str + begin + int = Integer(str) + if min and int < min + print "\"#{cmd}\" argument \"#{str}\" needs to be at least #{min}.\n" + return nil + elsif max and int > max + print "\"#{cmd}\" argument \"#{str}\" needs to be at most #{max}.\n" + return nil + end + return int + rescue + print "\"#{cmd}\" argument \"#{str}\" needs to be a number.\n" + return nil + end + end + + # Return true if arg is 'on' or 1 and false arg is 'off' or 0. + # Any other value raises RuntimeError. + def get_onoff(arg, default=nil, print_error=true) + if arg.nil? or arg == '' + if default.nil? + if print_error + print "Expecting 'on', 1, 'off', or 0. Got nothing.\n" + raise RuntimeError + end + return default + end + end + case arg.downcase + when '1', 'on' + return true + when '0', 'off' + return false + else + if print_error + print "Expecting 'on', 1, 'off', or 0. Got: #{arg.to_s}.\n" + raise RuntimeError + end + end + end + + # Return 'on' or 'off' for supplied parameter. The parameter should + # be true, false or nil. + def show_onoff(bool) + if not [TrueClass, FalseClass, NilClass].member?(bool.class) + return "??" + end + return bool ? 'on' : 'off' + end + + # Return true if code is syntactically correct for Ruby. + def syntax_valid?(code) + eval("BEGIN {return true}\n#{code}", nil, "", 0) + rescue Exception + false + end + + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interface.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interface.rb new file mode 100644 index 0000000..576093b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interface.rb @@ -0,0 +1,34 @@ +module Byebug + class Interface + attr_writer :have_readline + + def initialize + @have_readline = false + end + + # Common routine for reporting byebug error messages. + # Derived classes may want to override this to capture output. + def errmsg(*args) + print '*** ' + print(*args) + end + + def format(*args) + if args.is_a?(Array) + new_args = args.first + new_args = new_args % args[1..-1] unless args[1..-1].empty? + else + new_args = args + end + new_args + end + + def escape(msg) + msg.gsub('%', '%%') + end + end + + require_relative 'interfaces/local_interface' + require_relative 'interfaces/script_interface' + require_relative 'interfaces/remote_interface' +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/local_interface.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/local_interface.rb new file mode 100644 index 0000000..42ff0c2 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/local_interface.rb @@ -0,0 +1,88 @@ +module Byebug + class LocalInterface < Interface + attr_accessor :command_queue, :history_length, :history_save, :histfile + attr_accessor :restart_file + + FILE_HISTORY = ".byebug_hist" unless defined?(FILE_HISTORY) + + def initialize() + super + @command_queue = [] + @have_readline = false + @history_save = true + @history_length = ENV["HISTSIZE"] ? ENV["HISTSIZE"].to_i : 256 + @histfile = File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", FILE_HISTORY) + open(@histfile, 'r') do |file| + file.each do |line| + line.chomp! + Readline::HISTORY << line + end + end if File.exist?(@histfile) + @restart_file = nil + end + + def read_command(prompt) + readline(prompt, true) + end + + def confirm(prompt) + readline(prompt, false) + end + + def print(*args) + STDOUT.printf(escape(format(*args))) + end + + def close + end + + # Things to do before quitting + def finalize + if Byebug.respond_to?(:save_history) + Byebug.save_history + end + end + + def readline_support? + @have_readline + end + + private + + begin + require 'readline' + class << Byebug + @have_readline = true + define_method(:save_history) do + iface = self.handler.interface + iface.histfile ||= File.join(ENV["HOME"]||ENV["HOMEPATH"]||".", + FILE_HISTORY) + open(iface.histfile, 'w') do |file| + Readline::HISTORY.to_a.last(iface.history_length).each do |line| + file.puts line unless line.strip.empty? + end if defined?(iface.history_save) and iface.history_save + end rescue nil + end + public :save_history + end + + def readline(prompt, hist) + Readline::readline(prompt, hist) + rescue Interrupt + print "^C\n" + retry + end + rescue LoadError + def readline(prompt, hist) + @histfile = '' + @hist_save = false + STDOUT.print prompt + STDOUT.flush + line = STDIN.gets + exit unless line + line.chomp! + line + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/remote_interface.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/remote_interface.rb new file mode 100644 index 0000000..8e82c3f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/remote_interface.rb @@ -0,0 +1,55 @@ +module Byebug + class RemoteInterface < Interface + attr_accessor :command_queue, :history_length, :history_save, :histfile + attr_accessor :restart_file + + def initialize(socket) + @command_queue = [] + @socket = socket + @history_save = false + @history_length = 256 + @histfile = '' + # Do we read the histfile? + # open(@histfile, 'r') do |file| + # file.each do |line| + # line.chomp! + # Readline::HISTORY << line + # end + # end if File.exist?(@histfile) + @restart_file = nil + end + + def close + @socket.close + rescue Exception + end + + def confirm(prompt) + send_command "CONFIRM #{prompt}" + end + + def finalize + end + + def read_command(prompt) + send_command "PROMPT #{prompt}" + end + + def readline_support? + false + end + + def print(*args) + @socket.printf(escape(format(*args))) + end + + private + + def send_command(msg) + @socket.puts msg + result = @socket.gets + raise IOError unless result + result.chomp + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/script_interface.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/script_interface.rb new file mode 100644 index 0000000..9262007 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/interfaces/script_interface.rb @@ -0,0 +1,45 @@ +module Byebug + class ScriptInterface < Interface + attr_accessor :command_queue, :history_length, :history_save, :histfile + attr_accessor :restart_file + + def initialize(file, out, verbose=false) + super() + @command_queue = [] + @file = file.respond_to?(:gets) ? file : open(file) + @out = out + @verbose = verbose + @history_save = false + @history_length = 256 + @histfile = '' + end + + def finalize + end + + def read_command(prompt) + while result = @file.gets + puts "# #{result}" if @verbose + next if result =~ /^\s*#/ + next if result.strip.empty? + return result.chomp + end + end + + def readline_support? + false + end + + def confirm(prompt) + 'y' + end + + def print(*args) + @out.printf(*args) + end + + def close + @file.close + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/processor.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/processor.rb new file mode 100644 index 0000000..bcf2754 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/processor.rb @@ -0,0 +1,18 @@ +require 'forwardable' +require_relative 'interface' + +module Byebug + + # Should this be a mixin? + class Processor + attr_accessor :interface + + extend Forwardable + def_delegators :@interface, :errmsg, :print + + def initialize(interface) + @interface = interface + end + end + +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/remote.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/remote.rb new file mode 100644 index 0000000..736da4f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/remote.rb @@ -0,0 +1,99 @@ +require 'socket' + +module Byebug + + # Port number used for remote debugging + PORT = 8989 unless defined?(PORT) + + class << self + + # If in remote mode, wait for the remote connection + attr_accessor :wait_connection + + # The actual port that the server is started at + attr_accessor :actual_port + attr_reader :actual_control_port + + # + # Interrupts the current thread + # + def interrupt + current_context.interrupt + end + + # + # Starts a remote byebug + # + def start_server(host = nil, port = PORT) + return if @thread + + self.interface = nil + start + + start_control(host, port == 0 ? 0 : port + 1) + + yield if block_given? + + mutex = Mutex.new + proceed = ConditionVariable.new + + server = TCPServer.new(host, port) + self.actual_port = server.addr[1] + @thread = DebugThread.new do + while (session = server.accept) + self.interface = RemoteInterface.new(session) + if wait_connection + mutex.synchronize do + proceed.signal + end + end + end + end + if wait_connection + mutex.synchronize do + proceed.wait(mutex) + end + end + end + + def start_control(host = nil, ctrl_port = PORT + 1) + return @actual_control_port if @control_thread + server = TCPServer.new(host, ctrl_port) + @actual_control_port = server.addr[1] + @control_thread = Thread.new do + while (session = server.accept) + interface = RemoteInterface.new(session) + ControlCommandProcessor.new(interface).process_commands + end + end + @actual_control_port + end + + # + # Connects to the remote byebug + # + def start_client(host = 'localhost', port = PORT) + interface = Byebug::LocalInterface.new + socket = TCPSocket.new(host, port) + puts "Connected." + + catch(:exit) do + while (line = socket.gets) + case line + when /^PROMPT (.*)$/ + input = interface.read_command($1) + throw :exit unless input + socket.puts input + when /^CONFIRM (.*)$/ + input = interface.confirm($1) + throw :exit unless input + socket.puts input + else + print line + end + end + end + socket.close + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/lib/byebug/version.rb b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/version.rb new file mode 100644 index 0000000..1ae7fb5 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/lib/byebug/version.rb @@ -0,0 +1,3 @@ +module Byebug + VERSION = '2.7.0' +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/breakpoints_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/breakpoints_test.rb new file mode 100644 index 0000000..f1b15a7 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/breakpoints_test.rb @@ -0,0 +1,453 @@ +class BreakpointExample + def self.a(num) + 4 + end + def b + 3 + end +end + +class BreakpointDeepExample + def a + z = 2 + b(z) + end + + def b(num) + v2 = 5 if 1 == num ; [1,2,v2].map { |a| a.to_f } + c + end + + def c + z = 4 + z += 5 + byebug + end +end + +class TestBreakpoints < TestDsl::TestCase + before do + @tst_file = fullpath('breakpoint') + end + + describe 'setting breakpoint in the current file' do + before { enter 'break 1' } + + subject { Byebug.breakpoints.first } + + def check_subject(field, value) + debug_file('breakpoint') { subject.send(field).must_equal value } + end + + it('must have correct pos') { check_subject(:pos, 1) } + it('must have correct source') { check_subject(:source, @tst_file) } + it('must have correct expression') { check_subject(:expr, nil) } + it('must have correct hit count') { check_subject(:hit_count, 0) } + it('must have correct hit value') { check_subject(:hit_value, 0) } + it('must be enabled') { check_subject(:enabled?, true) } + + it('must return right response') do + id = nil + debug_file('breakpoint') { id = subject.id } + check_output_includes "Created breakpoint #{id} at #{@tst_file}:1" + end + end + + describe 'using shortcut for the command' do + before { enter 'b 1' } + it 'must set a breakpoint' do + debug_file('breakpoint') { Byebug.breakpoints.size.must_equal 1 } + end + end + + describe 'setting breakpoint to unexistent line' do + before { enter 'break 100' } + + it 'must not create a breakpoint' do + debug_file('breakpoint') { Byebug.breakpoints.must_be_empty } + end + + it 'must show an error' do + debug_file('breakpoint') + check_error_includes \ + "There are only #{LineCache.size(@tst_file)} lines in file #{@tst_file}" + end + end + + describe 'setting breakpoint to incorrect line' do + before { enter 'break 2' } + + it 'must not create a breakpoint' do + debug_file('breakpoint') { Byebug.breakpoints.must_be_empty } + end + + it 'must show an error' do + debug_file('breakpoint') + check_error_includes \ + "Line 2 is not a stopping point in file #{@tst_file}" + end + end + + describe 'stopping at breakpoint' do + it 'must stop at the correct line' do + enter 'break 5', 'cont' + debug_file('breakpoint') { state.line.must_equal 5 } + end + + it 'must stop at the correct file' do + enter 'break 5', 'cont' + debug_file('breakpoint') { state.file.must_equal @tst_file } + end + + describe 'show a message' do + describe 'with full filename' do + it 'must show a message with full filename' do + enter 'break 5', 'cont' + debug_file('breakpoint') { @id = Byebug.breakpoints.first.id } + check_output_includes "Created breakpoint #{@id} at #{@tst_file}:5" + end + end + + describe 'with basename' do + temporary_change_hash Byebug.settings, :basename, true + + it 'must show a message with basename' do + enter 'break 5', 'cont' + debug_file('breakpoint') { @id = Byebug.breakpoints.first.id } + check_output_includes "Created breakpoint #{@id} at breakpoint.rb:5" + end + end + end + end + + describe 'reloading source on change' do + describe 'autoreload not set' do + temporary_change_hash Byebug.settings, :autoreload, false + + it 'must not reload source' do + id = nil + enter ->{ change_line_in_file(@tst_file, 5, ''); 'break 5' }, + ->{ change_line_in_file(@tst_file, 5, 'BreakpointExample.new.b'); + cont } + debug_file('breakpoint') { id = Byebug.breakpoints.first.id } + check_output_includes "Created breakpoint #{id} at #{@tst_file}:5" + end + end + + describe 'autoreload set' do + it 'must reload source' do + enter \ + ->{change_line_in_file(@tst_file, 5, ''); 'break 5'}, + ->{change_line_in_file(@tst_file, 5, 'BreakpointExample.new.b'); + 'next'} + debug_file 'breakpoint' + check_error_includes \ + "Line 5 is not a stopping point in file #{@tst_file}" + end + end + end + + describe 'set breakpoint in a file' do + describe 'successfully' do + before { enter "break #{__FILE__}:3", 'cont' } + + it 'must stop at the correct line' do + debug_file('breakpoint') { state.line.must_equal 3 } + end + + it 'must stop at the correct file' do + debug_file('breakpoint') { state.file.must_equal __FILE__ } + end + end + + describe 'when setting breakpoint to unexisted file' do + before do + enter 'break asf:324' + debug_file('breakpoint') + end + + it 'must show an error' do + check_error_includes 'No source file named asf' + end + + it 'must ask about setting breakpoint anyway' do + check_output_includes \ + 'Set breakpoint anyway? (y/n)', interface.confirm_queue + end + end + end + + describe 'set breakpoint to a method' do + describe 'set breakpoint to an instance method' do + before { enter 'break BreakpointExample#b', 'cont' } + + it 'must stop at the correct line' do + debug_file('breakpoint') { state.line.must_equal 5 } + end + + it 'must stop at the correct file' do + debug_file('breakpoint') { state.file.must_equal __FILE__ } + end + end + + describe 'set breakpoint to a class method' do + before { enter 'break BreakpointExample.a', 'cont' } + + it 'must stop at the correct line' do + debug_file('breakpoint') { state.line.must_equal 2 } + end + + it 'must stop at the correct file' do + debug_file('breakpoint') { state.file.must_equal __FILE__ } + end + end + + describe 'set breakpoint to unexisted class' do + it 'must show an error' do + enter 'break B.a' + debug_file('breakpoint') + check_error_includes 'Unknown class B.' + end + end + end + + describe 'set breakpoint to an invalid location' do + before { enter 'break foo' } + + it 'must not create a breakpoint' do + debug_file('breakpoint') { Byebug.breakpoints.must_be_empty } + end + + it 'must show an error' do + debug_file('breakpoint') + check_error_includes 'Invalid breakpoint location: foo.' + end + end + + describe 'disabling breakpoints' do + describe 'successfully' do + before { enter 'break 5', 'break 6' } + + describe 'short syntax' do + before { enter ->{ "disable #{Byebug.breakpoints.first.id}" } } + + it 'must have a breakpoint with #enabled? returning false' do + debug_file('breakpoint') { + Byebug.breakpoints.first.enabled?.must_equal false } + end + + it 'must not stop on the disabled breakpoint' do + enter 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + end + end + + describe 'full syntax' do + describe 'with no args' do + before { enter 'disable breakpoints' } + + it 'must have all breakoints with #enabled? returning false' do + debug_file('breakpoint') do + Byebug.breakpoints.first.enabled?.must_equal false + Byebug.breakpoints.last.enabled?.must_equal false + end + end + + it 'must not stop on any disabled breakpoint' do + enter 'cont' + debug_file('breakpoint') + # Obscure assert to check for program termination + state.proceed.must_equal true + end + end + + describe 'with specific breakpoint' do + before do + enter ->{ "disable breakpoints #{Byebug.breakpoints.first.id}" } + end + + it 'must have a breakpoint with #enabled? returning false' do + debug_file('breakpoint') { + Byebug.breakpoints.first.enabled?.must_equal false } + end + end + end + end + + describe 'unsuccesfully' do + it 'must show an error if syntax is incorrect' do + enter 'disable' + debug_file('breakpoint') + check_error_includes '"disable" must be followed by "display", ' \ + '"breakpoints" or breakpoint numbers.' + end + + it 'must show an error if no breakpoints are set' do + enter 'disable 1' + debug_file('breakpoint') + check_error_includes 'No breakpoints have been set.' + end + + it 'must show an error if a number is not provided as an argument' do + enter 'break 5', 'disable foo' + debug_file('breakpoint') + check_output_includes \ + '"disable breakpoints" argument "foo" needs to be a number.' + end + end + end + + describe 'enabling breakpoints' do + describe 'successfully' do + before { enter 'break 5', 'break 6', 'disable breakpoints' } + + describe 'short syntax' do + before { enter ->{ "enable #{Byebug.breakpoints.first.id}" } } + + it 'must have a breakpoint with #enabled? returning true' do + debug_file('breakpoint') { + Byebug.breakpoints.first.enabled?.must_equal true } + end + + it 'must stop on the enabled breakpoint' do + enter 'cont' + debug_file('breakpoint') { state.line.must_equal 5 } + end + end + + describe 'full syntax' do + describe 'with no args' do + before { enter 'enable breakpoints' } + + it 'must have all breakoints with #enabled? returning true' do + debug_file('breakpoint') do + Byebug.breakpoints.first.enabled?.must_equal true + Byebug.breakpoints.last.enabled?.must_equal true + end + end + + it 'must stop on the first breakpoint' do + enter 'cont' + debug_file('breakpoint') { state.line.must_equal 5 } + end + + it 'must stop on the last breakpoint' do + enter 'cont', 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + end + end + + describe 'with specific breakpoint' do + before do + enter ->{ "enable breakpoints #{Byebug.breakpoints.last.id}" } + end + + it 'must have a breakpoint with #enabled? returning true' do + debug_file('breakpoint') { + Byebug.breakpoints.last.enabled?.must_equal true } + end + + it 'must stop only on the enabled breakpoint' do + enter 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + end + end + end + end + + describe 'errors' do + it 'must show an error if syntax is incorrect' do + enter 'enable' + debug_file('breakpoint') + check_error_includes '"enable" must be followed by "display", ' \ + '"breakpoints" or breakpoint numbers.' + end + end + end + + describe 'deleting a breakpoint' do + before { enter 'break 5', ->{"delete #{Byebug.breakpoints.first.id}"}, + 'break 6' } + + it 'must have only one breakpoint' do + debug_file('breakpoint') { Byebug.breakpoints.size.must_equal 1 } + end + + it 'must not stop on the disabled breakpoint' do + enter 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + end + end + + describe 'Conditional breakpoints' do + it 'must stop if the condition is true' do + enter 'break 5 if z == 5', 'break 6', 'cont' + debug_file('breakpoint') { state.line.must_equal 5 } + end + + it 'must skip if the condition is false' do + enter 'break 5 if z == 3', 'break 6', 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + end + + it 'must show an error when conditional syntax is wrong' do + enter 'break 5 ifa z == 3', 'break 6', 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + check_error_includes \ + 'Expecting "if" in breakpoint condition; got: ifa z == 3.' + end + + describe 'enabling with wrong conditional syntax' do + before { enter 'break 5', + ->{"disable #{Byebug.breakpoints.first.id}"}, + ->{"cond #{Byebug.breakpoints.first.id} z -=( 3"}, + ->{"enable #{Byebug.breakpoints.first.id}"} } + + it 'must not enable a breakpoint' do + debug_file('breakpoint') { + Byebug.breakpoints.first.enabled?.must_equal false } + end + + it 'must show an error' do + debug_file('breakpoint') + check_error_includes 'Expression "z -=( 3" syntactically incorrect; ' \ + 'breakpoint remains disabled.' + end + end + + it 'must show an error if no file or line is specified' do + enter 'break ifa z == 3', 'break 6', 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + check_error_includes 'Invalid breakpoint location: ifa z == 3.' + end + + it 'must show an error if expression syntax is invalid' do + enter 'break if z -=) 3', 'break 6', 'cont' + debug_file('breakpoint') { state.line.must_equal 6 } + check_error_includes \ + 'Expression "z -=) 3" syntactically incorrect; breakpoint disabled.' + end + end + + describe 'Stopping through `byebug` keyword' do + describe 'when not the last instruction of a method' do + it 'must stop in the next line' do + debug_file('breakpoint') { state.line.must_equal 4 } + end + end + + describe 'when last instruction of a method' do + it 'must stop right before returning from the frame' do + debug_file('breakpoint_deep') { state.line.must_equal 25 } + end + end + end + + describe 'Help' do + it 'must show info about setting breakpoints when using just "break"' do + enter 'break', 'cont' + debug_file 'breakpoint' + check_output_includes(/b\[reak\] file:line \[if expr\]/) + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/conditions_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/conditions_test.rb new file mode 100644 index 0000000..1034a28 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/conditions_test.rb @@ -0,0 +1,69 @@ +class TestConditions < TestDsl::TestCase + + describe 'setting condition' do + before { enter 'break 3' } + + describe 'successfully' do + before { enter ->{ "cond #{Byebug.breakpoints.first.id} b == 5" }, 'cont'} + + it 'must assign the expression to breakpoint' do + debug_file('conditions') { + Byebug.breakpoints.first.expr.must_equal 'b == 5' } + end + + it 'must stop at the breakpoint if condition is true' do + debug_file('conditions') { state.line.must_equal 3 } + end + + it 'must work with full command name too' do + debug_file('conditions') { state.line.must_equal 3 } + end + end + + describe 'unsuccessfully' do + before { enter 'break 4' } + + it 'must not stop at the breakpoint if condition is false' do + enter ->{ "cond #{Byebug.breakpoints.first.id} b == 3" }, 'cont' + debug_file('conditions') { state.line.must_equal 4 } + end + + it 'must assign expression to breakpoint in spite of incorrect syntax' do + enter ->{ "cond #{Byebug.breakpoints.first.id} b =="}, 'cont' + debug_file('conditions') { + Byebug.breakpoints.first.expr.must_equal 'b ==' } + end + + it 'must ignore the condition if when incorrect syntax' do + enter ->{ "cond #{Byebug.breakpoints.first.id} b ==" }, 'cont' + debug_file('conditions') { state.line.must_equal 4 } + end + end + end + + describe 'removing conditions' do + before { enter 'break 3 if b == 3', 'break 4', + ->{"cond #{Byebug.breakpoints.first.id}"}, 'cont' } + + it 'must remove the condition from the breakpoint' do + debug_file('conditions') { Byebug.breakpoints.first.expr.must_be_nil } + end + + it 'must unconditionally stop on the breakpoint' do + debug_file('conditions') { state.line.must_equal 3 } + end + end + + describe 'errors' do + it 'must show error if there are no breakpoints' do + enter 'cond 1 true' + debug_file('conditions') + check_output_includes 'No breakpoints have been set.' + end + + it 'must not set breakpoint condition if breakpoint id is incorrect' do + enter 'break 3', 'cond 8 b == 3', 'cont' + debug_file('conditions') { state.line.must_equal 3 } + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/continue_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/continue_test.rb new file mode 100644 index 0000000..1c48a00 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/continue_test.rb @@ -0,0 +1,39 @@ +class ContinueExample + def self.a(num) + num + 4 + end +end + +class TestContinue < TestDsl::TestCase + + describe "successful" do + it "must continue up to breakpoint if no line specified" do + enter 'break 4', 'continue' + debug_file('continue') { state.line.must_equal 4 } + end + + it "must work in abbreviated mode too" do + enter 'break 4', 'cont' + debug_file('continue') { state.line.must_equal 4 } + end + + it "must continue up to specified line" do + enter 'cont 4' + debug_file('continue') { state.line.must_equal 4 } + end + end + + describe "unsuccessful" do + it "must ignore the command if specified line is not valid" do + enter 'cont 123' + debug_file('continue') { state.line.must_equal 3 } + end + + it "must show error if specified line is not valid" do + enter 'cont 123' + debug_file 'continue' + check_error_includes \ + "Line 123 is not a stopping point in file \"#{fullpath('continue')}\"" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/debugger_alias_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/debugger_alias_test.rb new file mode 100644 index 0000000..ddcb039 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/debugger_alias_test.rb @@ -0,0 +1,5 @@ +class TestDebuggerAlias < MiniTest::Spec + it 'aliases "debugger" to "byebug"' do + Kernel.method(:debugger).must_equal(Kernel.method(:byebug)) + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/display_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/display_test.rb new file mode 100644 index 0000000..82813a3 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/display_test.rb @@ -0,0 +1,124 @@ +class TestDisplay < TestDsl::TestCase + + it 'must show expressions' do + enter 'break 3', 'cont', 'display d + 1' + debug_file 'display' + check_output_includes '1: ', 'd + 1 = 5' + end + + it 'must work with shortcut' do + enter 'break 3', 'cont', 'disp d + 1' + debug_file 'display' + check_output_includes '1: ', 'd + 1 = 5' + end + + it 'must save displayed expressions' do + enter 'display d + 1' + debug_file('display') { state.display.must_equal [[true, 'd + 1']] } + end + + it 'displays all expressions available' do + enter 'break 3', 'cont', -> do + Byebug.handler.display.concat([[true, 'abc'], [true, 'd']]); 'display' + end + debug_file 'display' + check_output_includes '1: ', 'abc = nil', '2: ', 'd = 4' + end + + describe 'undisplay' do + describe 'undisplay all' do + before do + enter 'break 3', 'cont', -> do + Byebug.handler.display.concat([[true, 'abc'], [true, 'd']]) + 'undisplay' + end, confirm_response, 'display' + end + + describe 'confirmation is successful' do + let(:confirm_response) { 'y' } + + it 'must ask about confirmation' do + debug_file 'display' + check_output_includes \ + 'Clear all expressions? (y/n)', interface.confirm_queue + end + + it 'must set all expressions saved to "false"' do + debug_file('display') { state.display.must_equal [[false, 'abc'], + [false, 'd']] } + end + + it 'must not show any output' do + debug_file 'display' + check_output_doesnt_include '1: ', 'abc = nil', '2: ', 'd = 4' + end + end + + describe 'confirmation is unsuccessful' do + let(:confirm_response) { 'n' } + + it 'must set all expressions saved to "false"' do + debug_file('display') { state.display.must_equal [[true, 'abc'], + [true, 'd']] } + end + + it 'must not show any output' do + debug_file 'display' + check_output_includes '1: ', 'abc = nil', '2: ', 'd = 4' + end + end + end + + describe 'undisplay specific position' do + before do + enter 'break 3', 'cont', -> do + Byebug.handler.display.concat([[true, 'abc'], [true, 'd']]) + 'undisplay 1' + end, 'display' + end + + it 'must set inactive positions' do + debug_file('display') { state.display.must_equal [[nil, 'abc'], + [true, 'd']] } + end + + it 'must display only the active position' do + debug_file 'display' + check_output_includes '2: ', 'd = 4' + end + + it 'must not display the disabled position' do + debug_file 'display' + check_output_doesnt_include '1: ', 'abc' + end + end + end + + describe 'disable' do + it 'must disable a position' do + enter 'display d', 'disable display 1' + debug_file('display') { state.display.must_equal [[false, 'd']] } + end + + it 'must show an error if no displays are set' do + enter 'disable display 1' + debug_file 'display' + check_output_includes \ + 'No display expressions have been set.', interface.error_queue + end + + it 'must show an error if there is no such display position' do + enter 'display d', 'disable display 4' + debug_file 'display' + check_output_includes \ + '"disable display" argument "4" needs to be at most 1.' + end + end + + describe 'enable' do + it 'must enable a position' do + enter 'display d', 'disable display 1', 'enable display 1' + debug_file('display') { state.display.must_equal [[true, 'd']] } + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/edit_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/edit_test.rb new file mode 100644 index 0000000..3781b6f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/edit_test.rb @@ -0,0 +1,47 @@ +class TestEdit < TestDsl::TestCase + + describe 'open configured editor' do + temporary_change_hash ENV, 'EDITOR', 'editr' + + it 'must open current file in current line in configured editor' do + Byebug::Edit.any_instance.expects(:system). + with("editr +2 #{fullpath('edit')}") + enter 'edit' + debug_file 'edit' + end + end + + describe 'open default editor' do + temporary_change_hash ENV, 'EDITOR', nil + + it 'must call "vim" with current line and file if EDITOR env not set' do + Byebug::Edit.any_instance.expects(:system). + with("vim +2 #{fullpath('edit')}") + enter 'edit' + debug_file 'edit' + end + end + + describe 'open configured editor specifying line and file' do + temporary_change_hash ENV, 'EDITOR', 'editr' + + it 'must open specified line in specified file with configured editor' do + Byebug::Edit.any_instance.expects(:system). + with("editr +3 #{fullpath('breakpoint')}") + enter "edit #{fullpath('breakpoint')}:3" + debug_file 'edit' + end + end + + it 'must show an error if there is no such line' do + enter "edit #{fullpath('edit3')}:6" + debug_file 'edit' + check_error_includes "File \"#{fullpath('edit3')}\" is not readable." + end + + it 'must show an error if there is incorrect syntax' do + enter 'edit blabla' + debug_file 'edit' + check_error_includes 'Invalid file[:line] number specification: blabla' + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/eval_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/eval_test.rb new file mode 100644 index 0000000..308d89c --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/eval_test.rb @@ -0,0 +1,103 @@ +class EvalTest + def sum(a,b) + a + b + end + + def inspect + raise "Broken" + end +end + +class TestEval < TestDsl::TestCase + it 'must evaluate an expression' do + enter 'eval 3 + 2' + debug_file 'eval' + check_output_includes '5' + end + + it 'must work with shortcut' do + enter 'e 3 + 2' + debug_file 'eval' + check_output_includes '5' + end + + it 'must work with another syntax' do + enter 'p 3 + 2' + debug_file 'eval' + check_output_includes '5' + end + + it 'must work when inspect raises an exception' do + enter 'c 4', 'p @foo' + debug_file('eval') { state.line.must_equal 4 } + check_output_includes 'RuntimeError Exception: Broken' + end + + describe 'autoeval' do + it 'must be set by default' do + enter '[5,6,7].inject(&:+)' + debug_file 'eval' + check_output_includes '18' + end + + it 'can be turned off and back on' do + enter 'set noautoeval', '[5,6,7].inject(&:+)', + 'set autoeval', '[1,2,3].inject(&:+)' + debug_file 'eval' + check_output_doesnt_include '18' + check_output_includes '6' + end + end + + describe 'stack trace on error' do + describe 'when enabled' do + temporary_change_hash Byebug.settings, :stack_on_error, true + + it 'must show a stack trace' do + enter 'eval 2 / 0' + debug_file 'eval' + check_output_includes(/\s*from \S+:in \`eval\'/) + check_output_doesnt_include 'ZeroDivisionError Exception: divided by 0' + end + end + + describe 'when disabled' do + temporary_change_hash Byebug.settings, :stack_on_error, false + + it 'must only show exception' do + enter 'eval 2 / 0' + debug_file 'eval' + check_output_includes 'ZeroDivisionError Exception: divided by 0' + check_output_doesnt_include(/\S+:\d+:in `eval':divided by 0/) + end + end + end + + describe 'pp' do + it 'must pretty print the expression result' do + enter 'pp {a: \'3\' * 40, b: \'4\' * 30}' + debug_file 'eval' + check_output_includes "{:a=>\"#{'3' * 40}\",\n :b=>\"#{'4' * 30}\"}" + end + end + + describe 'putl' do + temporary_change_hash Byebug.settings, :width, 20 + + it 'must print expression and columnize the result' do + enter 'putl [1, 2, 3, 4, 5, 9, 8, 7, 6]' + debug_file 'eval' + check_output_includes "1 3 5 8 6\n2 4 9 7" + end + end + + describe 'ps' do + temporary_change_hash Byebug.settings, :width, 20 + + it 'must print expression and sort and columnize the result' do + enter 'ps [1, 2, 3, 4, 5, 9, 8, 7, 6]' + debug_file 'eval' + check_output_includes "1 3 5 7 9\n2 4 6 8" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint.rb new file mode 100644 index 0000000..b1a51a7 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint.rb @@ -0,0 +1,6 @@ +y = 3 +# A comment +byebug +z = 5 +BreakpointExample.new.b +BreakpointExample.a(y+z) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint_deep.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint_deep.rb new file mode 100644 index 0000000..bf61656 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/breakpoint_deep.rb @@ -0,0 +1,4 @@ +ex = BreakpointDeepExample.new.a +2.times do + ex += 1 +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/conditions.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/conditions.rb new file mode 100644 index 0000000..86b4675 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/conditions.rb @@ -0,0 +1,4 @@ +byebug +b = 5 +c = b + 5 +c = Object.new diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/continue.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/continue.rb new file mode 100644 index 0000000..6b8ac75 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/continue.rb @@ -0,0 +1,5 @@ +byebug + +b = 5 +c = b + 5 +ContinueExample.a(c) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/display.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/display.rb new file mode 100644 index 0000000..2789133 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/display.rb @@ -0,0 +1,5 @@ +byebug +d = 4 +d = d + 2 +d = d + 3 +d = d + 6 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/edit.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/edit.rb new file mode 100644 index 0000000..9ff7d40 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/edit.rb @@ -0,0 +1,4 @@ +byebug +d = 1 +b = 2 +DummyObject.new(b, d) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/eval.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/eval.rb new file mode 100644 index 0000000..026eb63 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/eval.rb @@ -0,0 +1,4 @@ +byebug + +@foo = EvalTest.new +@foo.sum(1, 2) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/finish.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/finish.rb new file mode 100644 index 0000000..f24b1de --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/finish.rb @@ -0,0 +1,3 @@ +byebug + +FinishExample.new.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/frame.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/frame.rb new file mode 100644 index 0000000..58a680d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/frame.rb @@ -0,0 +1,4 @@ +byebug + +fr_ex = FrameExample.new('f') +fr_ex.a() diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/frame_deep.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/frame_deep.rb new file mode 100644 index 0000000..d3c2578 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/frame_deep.rb @@ -0,0 +1 @@ +FrameDeepExample.new.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/gcd.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/gcd.rb new file mode 100644 index 0000000..c74e02d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/gcd.rb @@ -0,0 +1,15 @@ +# Greatest common divisor of a and b +def gcd a, b + x = [a,b].max + y = [a,b].min + + while y != 0 + r = x % y + x = y + y = r + end + + x +end + +puts gcd ARGV[0].to_i, ARGV[1].to_i diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/hanoi.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/hanoi.rb new file mode 100644 index 0000000..d8313d8 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/hanoi.rb @@ -0,0 +1,34 @@ +# Solves the classic Towers of Hanoi puzzle. +def hanoi(n,a,b,c) + if n-1 > 0 + hanoi(n-1, a, c, b) + end + puts "Move disk %s to %s" % [a, b] + if n-1 > 0 + hanoi(n-1, c, b, a) + end +end + +i_args=ARGV.length +if i_args > 1 + puts "*** Need number of disks or no parameter" + exit 1 +end + +n=3 + +if i_args > 0 + begin + n = ARGV[0].to_i + rescue ValueError, :msg + print "** Expecting an integer, got: %s" % ARGV[0].to_s + exit 2 + end +end + +if n < 1 or n > 100 + puts "*** number of disks should be between 1 and 100" + exit 2 +end + +hanoi(n, :a, :b, :c) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/help.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/help.rb new file mode 100644 index 0000000..782b510 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/help.rb @@ -0,0 +1 @@ +byebug diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/info.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/info.rb new file mode 100644 index 0000000..76d3562 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/info.rb @@ -0,0 +1,6 @@ +byebug + +i = InfoExample.new +i.b +i.c +i.d diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/info2.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/info2.rb new file mode 100644 index 0000000..01e79c3 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/info2.rb @@ -0,0 +1,3 @@ +1 +2 +3 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/interrupt.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/interrupt.rb new file mode 100644 index 0000000..4f7a39c --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/interrupt.rb @@ -0,0 +1,8 @@ +byebug + +ex = InterruptExample.a(7) +2.times do + ex += 1 +end + +InterruptExample.b(ex) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/kill.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/kill.rb new file mode 100644 index 0000000..46e787b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/kill.rb @@ -0,0 +1,2 @@ +byebug +KillExample.kill_me diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/list.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/list.rb new file mode 100644 index 0000000..1b37e53 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/list.rb @@ -0,0 +1,23 @@ +byebug +a = 2 +a = 3 +a = 4 +a = 5 +a = 6 +a = 7 +a = 8 +a = 9 +a = 10 +a = 11 +a = 12 +a = 13 +a = 14 +a = 15 +a = 16 +a = 17 +a = 18 +a = 19 +a = 20 +a = 21 +a = 22 +a = '%23' diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/method.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/method.rb new file mode 100644 index 0000000..f0b8e6d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/method.rb @@ -0,0 +1,4 @@ +byebug + +a = MethodExample.new +a.bla diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/post_mortem.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/post_mortem.rb new file mode 100644 index 0000000..72365f0 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/post_mortem.rb @@ -0,0 +1,4 @@ +byebug + +c = PostMortemExample.new +c.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/primes.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/primes.rb new file mode 100644 index 0000000..15e8440 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/primes.rb @@ -0,0 +1,25 @@ +# Enumerator for primes +class SievePrime + @@odd_primes = [] + def self.next_prime(&block) + candidate = 2 + yield candidate + not_prime = false + candidate += 1 + while true do + @@odd_primes.each do |p| + not_prime = (0 == (candidate % p)) + break if not_prime + end + unless not_prime + @@odd_primes << candidate + yield candidate + end + candidate += 2 + end + end +end +SievePrime.next_prime do |prime| + puts prime + break if prime > 10 +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/quit.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/quit.rb new file mode 100644 index 0000000..7f0d0d8 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/quit.rb @@ -0,0 +1,2 @@ +byebug +DummyObject.new diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/reload.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/reload.rb new file mode 100644 index 0000000..6630c5b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/reload.rb @@ -0,0 +1,6 @@ +byebug +a = 2 +a = 3 +a = 4 +a = 5 +a = 6 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/repl.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/repl.rb new file mode 100644 index 0000000..6630c5b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/repl.rb @@ -0,0 +1,6 @@ +byebug +a = 2 +a = 3 +a = 4 +a = 5 +a = 6 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/restart.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/restart.rb new file mode 100644 index 0000000..dbf892c --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/restart.rb @@ -0,0 +1,6 @@ +byebug + +a = ARGV[0] +b = ARGV[1] +c = ARGV[2] +RestartExample.new.concat_args(a, b, c) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/save.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/save.rb new file mode 100644 index 0000000..da98d84 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/save.rb @@ -0,0 +1,3 @@ +byebug +a = 2 +a = 3 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/set.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/set.rb new file mode 100644 index 0000000..da98d84 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/set.rb @@ -0,0 +1,3 @@ +byebug +a = 2 +a = 3 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/settings.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/settings.rb new file mode 100644 index 0000000..782b510 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/settings.rb @@ -0,0 +1 @@ +byebug diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/show.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/show.rb new file mode 100644 index 0000000..782b510 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/show.rb @@ -0,0 +1 @@ +byebug diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/source.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/source.rb new file mode 100644 index 0000000..da98d84 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/source.rb @@ -0,0 +1,3 @@ +byebug +a = 2 +a = 3 diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping.rb new file mode 100644 index 0000000..c1b1097 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping.rb @@ -0,0 +1,8 @@ +byebug + +ex = SteppingExample.a(7) +2.times do + ex += 1 +end + +SteppingExample.b(ex) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_c_method.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_c_method.rb new file mode 100644 index 0000000..33f7f2b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_c_method.rb @@ -0,0 +1,3 @@ +byebug + +SteppingRaiseFromCMethodExample.new.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_ruby_method.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_ruby_method.rb new file mode 100644 index 0000000..f725938 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/stepping_raise_from_ruby_method.rb @@ -0,0 +1,3 @@ +byebug + +SteppingRaiseFromRubyMethodExample.new.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/test-triangle.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/test-triangle.rb new file mode 100644 index 0000000..620b499 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/test-triangle.rb @@ -0,0 +1,14 @@ +require 'minitest/autorun' +require_relative 'triangle.rb' + +class TestTri < MiniTest::Unit::TestCase + def test_basic + byebug + solutions = [] + 0.upto(5) do |i| + solutions << triangle(i) + end + assert_equal([0, 1, 3, 6, 10, 15], solutions, + "Testing the first 5 triangle numbers") + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/thread.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/thread.rb new file mode 100644 index 0000000..4bc233e --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/thread.rb @@ -0,0 +1,5 @@ +byebug + +t = ThreadExample.new +t.launch +t.kill diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/tmate.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/tmate.rb new file mode 100644 index 0000000..54926a4 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/tmate.rb @@ -0,0 +1,10 @@ +byebug +class TmateExample + def a + b + end + def b + 3 + end +end +TmateExample.new.a diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/trace.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/trace.rb new file mode 100644 index 0000000..839945d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/trace.rb @@ -0,0 +1,8 @@ +$bla = 2 +byebug +$bla = 3 +$bla = 4 +$bla = 5 +$bla = 6 +$bla = 7 +$bla = (0 == (7 % $bla)) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/tri3.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/tri3.rb new file mode 100644 index 0000000..5b3481f --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/tri3.rb @@ -0,0 +1,6 @@ +def triangle(n) + (0..n).inject do |sum, i| + sum +=i + end +end +puts triangle(3) diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/triangle.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/triangle.rb new file mode 100644 index 0000000..2e64933 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/triangle.rb @@ -0,0 +1,13 @@ +# Compute the n'th triangle number, the hard way: triangle(n) == (n*(n+1))/2 +def triangle(n) + tri = 0 + 0.upto(n) do |i| + tri += i + end + tri +end + +if __FILE__ == $0 + t = triangle(3) + puts t +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/examples/variables.rb b/vendor/bundle/gems/byebug-2.7.0/test/examples/variables.rb new file mode 100644 index 0000000..5e13f7b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/examples/variables.rb @@ -0,0 +1,4 @@ +byebug + +v = VariablesExample.new +v.run diff --git a/vendor/bundle/gems/byebug-2.7.0/test/finish_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/finish_test.rb new file mode 100644 index 0000000..b598362 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/finish_test.rb @@ -0,0 +1,53 @@ +class FinishExample + def a + b + end + def b + c + 2 + end + def c + d + 3 + end + def d + 5 + end +end + +class TestFinish < TestDsl::TestCase + before { enter "break #{__FILE__}:14", 'cont' } + + it 'must stop at the next frame by default' do + enter 'finish' + debug_file('finish') { state.line.must_equal 11 } + end + + it 'must stop at the #0 frame by default' do + enter 'finish 0' + debug_file('finish') { state.line.must_equal 11 } + end + + it 'must stop at the specified frame' do + enter 'finish 1' + debug_file('finish') { state.line.must_equal 7 } + end + + it 'must stop at the next frame if the current frame was changed' do + enter 'up', 'finish' + debug_file('finish') { state.line.must_equal 7 } + end + + describe 'not a number is specified for frame' do + before { enter 'finish foo' } + + it 'must show an error' do + debug_file('finish') + check_output_includes '"finish" argument "foo" needs to be a number.' + end + + it 'must be on the same line' do + debug_file('finish') { state.line.must_equal 14 } + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/frame_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/frame_test.rb new file mode 100644 index 0000000..fb89f8b --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/frame_test.rb @@ -0,0 +1,228 @@ +class FrameExample + def initialize(f) + @f = f + end + + def a + b + end + + def b + c + 2 + end + + def c + d('a') + 3 + end + + def d(e) + 5 + end +end + +class FrameDeepExample + def a + z = 1 + z += b + end + def b + z = 2 + z += c + end + def c + z = 3 + byebug + z += d('a') + end + def d(e) + 4 + end +end + +class TestFrame < TestDsl::TestCase + describe 'when byebug started at the beginning' do + before do + @tst_file = fullpath('frame') + enter "break #{__FILE__}:21", 'cont' + end + + it 'must go up' do + enter 'up' + debug_file('frame') { state.line.must_equal 16 } + end + + it 'must go up by specific number of frames' do + enter 'up 2' + debug_file('frame') { state.line.must_equal 11 } + end + + it 'must go down' do + enter 'up', 'down' + debug_file('frame') { state.line.must_equal 21 } + end + + it 'must go down by specific number of frames' do + enter 'up 3', 'down 2' + debug_file('frame') { state.line.must_equal 16 } + end + + it 'must set frame' do + enter 'frame 2' + debug_file('frame') { state.line.must_equal 11 } + end + + it 'must print current stack frame when without arguments' do + enter 'up', 'frame' + debug_file('frame') + check_output_includes(/#1 FrameExample\.c\s+at #{__FILE__}:16/) + end + + it 'must set frame to the first one' do + enter 'up', 'frame 0' + debug_file('frame') { state.line.must_equal 21 } + end + + it 'must set frame to the last one' do + enter 'frame -1' + debug_file('frame') { File.basename(state.file).must_equal 'test_helper.rb' } + end + + it 'must not set frame if the frame number is too low' do + enter 'down' + debug_file('frame') { state.line.must_equal 21 } + check_output_includes \ + "Can't navigate beyond the newest frame", interface.error_queue + end + + it 'must not set frame if the frame number is too high' do + enter 'up 100' + debug_file('frame') { state.line.must_equal 21 } + check_output_includes \ + "Can't navigate beyond the oldest frame", interface.error_queue + end + + describe 'fullpath' do + describe 'when set' do + temporary_change_hash Byebug.settings, :fullpath, true + + it 'must display current backtrace with fullpaths' do + enter 'where' + debug_file 'frame' + check_output_includes( + /--> #0 FrameExample\.d\(e#String\)\s+at #{__FILE__}:21/, + /#1 FrameExample\.c\s+at #{__FILE__}:16/, + /#2 FrameExample\.b\s+at #{__FILE__}:11/) + end + end + + describe 'when unset' do + temporary_change_hash Byebug.settings, :fullpath, false + + it 'must display current backtrace with shortpaths' do + enter 'where' + debug_file 'frame' + check_output_includes( + /--> #0 FrameExample\.d\(e#String\)\s+at #{shortpath(__FILE__)}:21/, + /#1 FrameExample\.c\s+at #{shortpath(__FILE__)}:16/, + /#2 FrameExample\.b\s+at #{shortpath(__FILE__)}:11/, + /#3 FrameExample\.a\s+at #{shortpath(__FILE__)}:7/) + end + end + end + + describe 'callstyle' do + describe 'long' do + temporary_change_hash Byebug.settings, :callstyle, :long + + it 'displays current backtrace with callstyle "long"' do + enter 'where' + debug_file 'frame' + check_output_includes( + /--> #0 FrameExample\.d\(e#String\)\s+at #{__FILE__}:21/, + /#1 FrameExample\.c\s+at #{__FILE__}:16/, + /#2 FrameExample\.b\s+at #{__FILE__}:11/, + /#3 FrameExample\.a\s+at #{__FILE__}:7/) + end + end + + describe 'short' do + temporary_change_hash Byebug.settings, :callstyle, :short + + it 'displays current backtrace with callstyle "short"' do + enter 'where' + debug_file 'frame' + check_output_includes(/--> #0 d\(e\)\s+at #{__FILE__}:21/, + /#1 c\s+at #{__FILE__}:16/, + /#2 b\s+at #{__FILE__}:11/, + /#3 a\s+at #{__FILE__}:7/) + end + end + end + end + + describe 'when byebug is started deep in the callstack' do + before { enter "break #{__FILE__}:40", 'cont' } + + it 'must print backtrace' do + enter 'where' + debug_file 'frame_deep' + check_output_includes( + /--> #0 FrameDeepExample\.d\(e#String\)\s+at #{__FILE__}:40/, + /#1 FrameDeepExample\.c\s+at #{__FILE__}:37/, + /#2 FrameDeepExample\.b\s+at #{__FILE__}:32/) + end + + it 'must go up' do + enter 'up' + debug_file('frame_deep') { state.line.must_equal 37 } + end + + it 'must go down' do + enter 'up', 'down' + debug_file('frame_deep') { state.line.must_equal 40 } + end + + it 'must set frame' do + enter 'frame 2' + debug_file('frame_deep') { state.line.must_equal 32 } + end + + it 'must eval properly when scaling the stack' do + enter 'p z', 'up', 'p z', 'up', 'p z' + debug_file('frame_deep') + check_output_includes 'nil', '3', '2' + end + end + + describe 'c-frames' do + it 'must mark c-frames when printing the stack' do + enter "break #{__FILE__}:3", 'cont', 'where' + enter 'where' + debug_file 'frame' + check_output_includes( + /--> #0 FrameExample.initialize\(f#String\)\s+at #{__FILE__}:3/, + /ͱ-- #1 Class.new\(\*args\)\s+at #{fullpath('frame')}:3/, + /#2 \s+at #{fullpath('frame')}:3/) + end + + it '"up" skips c-frames' do + enter "break #{__FILE__}:7", 'cont', 'up', 'eval fr_ex.class.to_s' + debug_file 'frame' + check_output_includes '"FrameExample"' + end + + it '"down" skips c-frames' do + enter "break #{__FILE__}:7", 'cont', 'up', 'down', 'eval @f' + debug_file 'frame' + check_output_includes '"f"' + end + + it 'must not jump straigh to c-frames' do + enter "break #{__FILE__}:3", 'cont', 'frame 1' + debug_file 'frame' + check_output_includes "Can't navigate to c-frame", interface.error_queue + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/help_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/help_test.rb new file mode 100644 index 0000000..ee95eec --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/help_test.rb @@ -0,0 +1,50 @@ +class TestHelp < TestDsl::TestCase + include Columnize + + let(:available_commands) { + Byebug::Command.commands.map(&:names).flatten.uniq.sort } + + describe 'when typed alone' do + temporary_change_hash Byebug.settings, :width, 50 + + it 'must show self help when typed alone' do + enter 'help' + debug_file 'help' + check_output_includes \ + 'Type "help " for help on a specific command', + 'Available commands:', columnize(available_commands, 50) + end + + it 'must work when shortcut used' do + enter 'h' + debug_file 'help' + check_output_includes \ + 'Type "help " for help on a specific command' + end + end + + describe 'when typed with a command' do + it 'must show an error if an undefined command is specified' do + enter 'help foobar' + debug_file 'help' + check_error_includes 'Undefined command: "foobar". Try "help".' + end + + it "must show a command's help" do + enter 'help break' + debug_file 'help' + check_output_includes \ + "b[reak] file:line [if expr]\n" \ + "b[reak] class(.|#)method [if expr]\n\n" \ + "Set breakpoint to some position, (optionally) if expr == true\n" + end + end + + describe 'when typed with command and subcommand' do + it "must show subcommand's help" do + enter 'help info breakpoints' + debug_file 'help' + check_output_includes "Status of user-settable breakpoints.\n" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/info_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/info_test.rb new file mode 100644 index 0000000..eb59e98 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/info_test.rb @@ -0,0 +1,308 @@ +class InfoExample + def initialize + @foo = "bar" + @bla = "blabla" + end + + def a(y, z) + w = "1" * 30 + x = 2 + w + x.to_s + y + z + @foo + end + + def c + a = BasicObject.new + a + end + + def b + a('a', 'b') + e = "%.2f" + e + end + + def d + raise "bang" + rescue + end + +end + +class TestInfo < TestDsl::TestCase + include Columnize + + describe 'Args info' do + it 'must show info about all args' do + enter "break #{__FILE__}:10", 'cont', 'info args' + debug_file 'info' + check_output_includes 'y = "a"', 'z = "b"' + end + end + + describe 'Breakpoints info' do + it 'must show info about all breakpoints' do + enter 'break 4', 'break 5 if y == z', 'info breakpoints' + debug_file 'info' + check_output_includes 'Num Enb What', + /\d+ +y at #{fullpath('info')}:4/, + /\d+ +y at #{fullpath('info')}:5 if y == z/ + end + + it 'must show info about specific breakpoint' do + enter 'break 4', 'break 5', + ->{ "info breakpoints #{Byebug.breakpoints.first.id}" } + debug_file 'info' + check_output_includes 'Num Enb What', /\d+ +y at #{fullpath('info')}:4/ + check_output_doesnt_include(/\d+ +y at #{fullpath('info')}:5/) + end + + it 'must show an error if no breakpoints are found' do + enter 'info breakpoints' + debug_file 'info' + check_output_includes 'No breakpoints.' + end + + it 'must show an error if no breakpoints are found' do + enter 'break 4', 'info breakpoints 123' + debug_file 'info' + check_error_includes 'No breakpoints found among list given.' + end + + it 'must show hit count' do + enter 'break 5', 'cont', 'info breakpoints' + debug_file 'info' + check_output_includes( + /\d+ +y at #{fullpath('info')}:5/, 'breakpoint already hit 1 time') + end + end + + describe 'Display info' do + it 'must show all display expressions' do + enter 'display 3 + 3', 'display a + b', 'info display' + debug_file 'info' + check_output_includes "Auto-display expressions now in effect:\n" \ + 'Num Enb Expression', + '1: y 3 + 3', + '2: y a + b' + end + + it 'must show a message if there are no display expressions created' do + enter 'info display' + debug_file 'info' + check_output_includes 'There are no auto-display expressions now.' + end + end + + describe 'Files info' do + let(:files) { SCRIPT_LINES__.keys.uniq.sort } + + it 'must show all files read in' do + enter 'info files' + debug_file 'info' + check_output_includes files.map { |f| "File #{f}" } + end + + it 'must show all files read in using "info file" too' do + enter 'info file' + debug_file 'info' + check_output_includes files.map { |f| "File #{f}" } + end + + it 'must show explicitly loaded files' do + enter 'info files stat' + debug_file 'info' + check_output_includes "File #{fullpath('info')}", + LineCache.stat(fullpath('info')).mtime.to_s + end + end + + describe 'File info' do + let(:file) { fullpath('info') } + let(:filename) { "File #{file}" } + let(:lines) { "#{LineCache.size(file)} lines" } + let(:mtime) { LineCache.stat(file).mtime.to_s } + let(:sha1) { LineCache.sha1(file) } + let(:breakpoint_line_numbers) { + columnize(LineCache.trace_line_numbers(file).to_a.sort, + Byebug.settings[:width]) } + + it 'must show basic info about the file' do + enter "info file #{file} basic" + debug_file 'info' + check_output_includes filename, lines + check_output_doesnt_include breakpoint_line_numbers, mtime, sha1 + end + + it 'must show number of lines' do + enter "info file #{file} lines" + debug_file 'info' + check_output_includes filename, lines + check_output_doesnt_include breakpoint_line_numbers, mtime, sha1 + end + + it 'must show mtime of the file' do + enter "info file #{file} mtime" + debug_file 'info' + check_output_includes filename, mtime + check_output_doesnt_include lines, breakpoint_line_numbers, sha1 + end + + it 'must show sha1 of the file' do + enter "info file #{file} sha1" + debug_file 'info' + check_output_includes filename, sha1 + check_output_doesnt_include lines, breakpoint_line_numbers, mtime + end + + it 'must show breakpoints in the file' do + enter 'break 4', 'break 5', "info file #{file} breakpoints" + debug_file 'info' + check_output_includes(/Created breakpoint \d+ at #{file}:4/, + /Created breakpoint \d+ at #{file}:5/, + filename, + 'breakpoint line numbers:', breakpoint_line_numbers) + check_output_doesnt_include lines, mtime, sha1 + end + + it 'must show all info about the file' do + enter "info file #{file} all" + debug_file 'info' + check_output_includes \ + filename, lines, breakpoint_line_numbers, mtime, sha1 + end + + it 'must not show any info if the parameter is invalid' do + enter "info file #{file} blabla" + debug_file 'info' + check_error_includes 'Invalid parameter blabla' + end + end + + describe 'Instance variables info' do + it 'must show instance variables' do + enter "break #{__FILE__}:10", 'cont', 'info instance_variables' + debug_file 'info' + check_output_includes '@bla = "blabla"', '@foo = "bar"' + end + end + + describe 'Line info' do + it 'must show the current line' do + enter "break #{__FILE__}:10", 'cont', 'info line' + debug_file 'info' + check_output_includes "Line 10 of \"#{__FILE__}\"" + end + end + + describe 'Locals info' do + temporary_change_hash Byebug.settings, :width, 28 + + it 'must show the current local variables' do + enter "break #{__FILE__}:10", 'cont', 'info locals' + debug_file 'info' + check_output_includes 'w = "11111111111111111111...', 'x = 2' + end + + it 'must fail if local variable doesn\'t respond to #to_s or to #inspect' do + enter "break #{__FILE__}:15", 'cont', 'info locals' + debug_file 'info' + check_output_includes 'a = *Error in evaluation*' + end + end + + describe 'Program info' do + it 'must show the initial stop reason' do + enter 'info program' + debug_file 'info' + check_output_includes \ + 'It stopped after stepping, next\'ing or initial start.' + end + + it 'must show the step stop reason' do + enter 'step', 'info program' + debug_file 'info' + check_output_includes \ + 'Program stopped.', + 'It stopped after stepping, next\'ing or initial start.' + end + + it 'must show the breakpoint stop reason' do + enter 'break 4', 'cont', 'info program' + debug_file 'info' + check_output_includes 'Program stopped.', 'It stopped at a breakpoint.' + end + + it 'must show the catchpoint stop reason' do + enter 'catch Exception', 'cont', 'info program' + debug_file 'info' + check_output_includes 'Program stopped.', 'It stopped at a catchpoint.' + end + + it 'must show the unknown stop reason' do + enter 'break 5', 'cont', + ->{ context.stubs(:stop_reason).returns('blabla'); 'info program' } + debug_file 'info' + check_output_includes 'Program stopped.', 'unknown reason: blabla' + end + + it 'must show an error if the program is crashed' do + skip('TODO') + end + end + + describe 'Stack info' do + it 'must show stack info' do + enter 'set fullpath', "break #{__FILE__}:8", 'cont', 'info stack' + debug_file 'info' + check_output_includes( + /--> #0 InfoExample.a\(y\#String, z\#String\)\s+at #{__FILE__}:8/, + /#1 InfoExample.b\s+at #{__FILE__}:19/, + /#2 \s+at #{fullpath('info')}:4/) + end + end + + describe 'Global Variables info' do + it 'must show global variables' do + enter 'info global_variables' + debug_file 'info' + check_output_includes "$$ = #{Process.pid}" + end + end + + describe 'Variables info' do + temporary_change_hash Byebug.settings, :width, 30 + + it 'must show all variables' do + enter "break #{__FILE__}:10", 'cont', 'info variables' + debug_file 'info' + check_output_includes(/self = # 5: a = 5', '6: a = 6', + '7: a = 7', '8: a = 8', '9: a = 9', '10: a = 10' + end + + it 'must list forward after second call' do + enter 'break 5', 'cont', 'list' + debug_file 'list' + check_output_includes "[11, 20] in #{fullpath('list')}", '11: a = 11', + '12: a = 12', '13: a = 13', '14: a = 14', '15: a = 15', '16: a = 16', + '17: a = 17', '18: a = 18', '19: a = 19', '20: a = 20' + end + end + + describe 'list backwards' do + temporary_change_hash Byebug.settings, :autolist, 0 + + it 'must show surrounding lines with the first call' do + enter 'break 15', 'cont', 'list -' + debug_file 'list' + check_output_includes "[10, 19] in #{fullpath('list')}", '10: a = 10', + '11: a = 11', '12: a = 12', '13: a = 13', '14: a = 14', '=> 15: a = 15', + '16: a = 16', '17: a = 17', '18: a = 18', '19: a = 19' + end + + it 'must list backward after second call' do + enter 'break 15', 'cont', 'list -', 'list -' + debug_file 'list' + check_output_includes "[1, 10] in #{fullpath('list')}", '1: byebug', + '2: a = 2', '3: a = 3', '4: a = 4', '5: a = 5', '6: a = 6', '7: a = 7', + '8: a = 8', '9: a = 9', '10: a = 10' + end + end + + describe 'list surrounding' do + temporary_change_hash Byebug.settings, :autolist, 0 + + it 'must show the surrounding lines with =' do + enter 'break 5', 'cont', 'list =' + debug_file 'list' + check_output_includes "[1, 10] in #{fullpath('list')}", '1: byebug', + '2: a = 2', '3: a = 3', '4: a = 4', '=> 5: a = 5', '6: a = 6', + '7: a = 7', '8: a = 8', '9: a = 9', '10: a = 10' + end + end + + describe 'specific range' do + it 'must show with mm-nn' do + enter 'list 4-6' + debug_file 'list' + check_output_includes \ + "[4, 6] in #{fullpath('list')}", '4: a = 4', '5: a = 5', '6: a = 6' + end + + it 'must show with mm,nn' do + enter 'list 4,6' + debug_file 'list' + check_output_includes \ + "[4, 6] in #{fullpath('list')}", '4: a = 4', '5: a = 5', '6: a = 6' + end + + it 'must show nothing if there is no such lines' do + enter 'list 44,44' + debug_file 'list' + check_error_includes 'Invalid line range' + check_output_doesnt_include "[44, 44] in #{fullpath('list')}" + check_output_doesnt_include(/^44 \S/) + end + + it 'must show nothing if range is incorrect' do + enter 'list 5,4' + debug_file 'list' + check_output_includes "[5, 4] in #{fullpath('list')}" + end + end + + describe 'arround specific line' do + it 'must show surroundings with mm-' do + enter 'list 14-' + debug_file 'list' + check_output_includes "[9, 18] in #{fullpath('list')}", '9: a = 9', + '10: a = 10', '11: a = 11', '12: a = 12', '13: a = 13', '14: a = 14', + '15: a = 15', '16: a = 16', '17: a = 17', '18: a = 18' + end + + it 'must show surroundings with mm,' do + enter 'list 14,' + debug_file 'list' + check_output_includes "[9, 18] in #{fullpath('list')}", '9: a = 9', + '10: a = 10', '11: a = 11', '12: a = 12', '13: a = 13', '14: a = 14', + '15: a = 15', '16: a = 16', '17: a = 17', '18: a = 18' + end + end + + describe 'reload source' do + after { change_line_in_file(fullpath('list'), 4, 'a = 4') } + + describe 'when autoreload is false' do + temporary_change_hash Byebug.settings, :autoreload, false + + it 'must not reload listing with file changes' do + enter -> { change_line_in_file fullpath('list'), 4, 'a = 100' ; + 'list 4-4' } + debug_file 'list' + check_output_includes '4: a = 4' + end + end + + describe 'when autoreload is true' do + it 'must reload listing with file changes' do + enter -> { change_line_in_file fullpath('list'), 4, 'a = 100' ; + 'list 4-4' } + debug_file 'list' + check_output_includes '4: a = 100' + end + end + end + + it 'must show an error when there is no such file' do + enter -> { state.file = 'blabla'; 'list 4-4' } + debug_file 'list' + check_error_includes 'No sourcefile available for blabla' + end + + it 'must correctly print lines containing % sign' do + enter 'list 23' + debug_file 'list' + check_output_includes "23: a = '%23'" + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/method_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/method_test.rb new file mode 100644 index 0000000..cfb561d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/method_test.rb @@ -0,0 +1,78 @@ +class MethodExample + def initialize + @a = 'b' + @c = 'd' + end + def self.foo + "asdf" + end + def bla + "asdf" + end +end + +class TestMethod < TestDsl::TestCase + temporary_change_hash Byebug.settings, :autolist, 0 + + describe 'show instance method of a class' do + before { enter 'break 4', 'cont' } + + it 'must show using full command name' do + enter 'method MethodExample' + debug_file 'method' + check_output_includes(/bla/) + check_output_doesnt_include(/foo/) + end + + it 'must show using shortcut' do + enter 'm MethodExample' + debug_file 'method' + check_output_includes(/bla/) + end + + it 'must show an error if specified object is not a class or module' do + enter 'm a' + debug_file 'method' + check_output_includes 'Should be Class/Module: a' + end + end + + describe 'show methods of an object' do + before { enter 'break 4', 'cont' } + + it 'must show using full command name' do + enter 'method instance a' + debug_file 'method' + check_output_includes(/bla/) + check_output_doesnt_include(/foo/) + end + + it 'must show using shortcut' do + enter 'm i a' + debug_file 'method' + check_output_includes(/bla/) + end + end + + describe 'show signature of a method' do + it 'must work' do + skip('TODO, can\'t install ruby-internal gem') + end + end + + describe 'show instance variables of an object' do + before { enter 'break 4', 'cont' } + + it 'must show using full name command' do + enter 'method iv a' + debug_file 'method' + check_output_includes '@a = "b"', '@c = "d"' + end + + it 'must show using shortcut' do + enter 'm iv a' + debug_file 'method' + check_output_includes '@a = "b"', '@c = "d"' + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/post_mortem_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/post_mortem_test.rb new file mode 100644 index 0000000..c6a2aeb --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/post_mortem_test.rb @@ -0,0 +1,253 @@ +class PostMortemExample + def a + z = 4 + raise 'blabla' + x = 6 + x + z + end +end + +class TestPostMortem < TestDsl::TestCase + + describe 'Features' do + before { enter 'set post_mortem', 'cont' } + + it 'must enter into post-mortem mode' do + debug_file('post_mortem', rescue: true) do + Byebug.post_mortem?.must_equal true + end + end + + it 'must stop at the correct line' do + debug_file('post_mortem', rescue: true) { assert_equal 4, state.line } + end + end + + describe 'Unavailable commands' do + temporary_change_hash Byebug.settings, :autoeval, false + + describe 'step' do + it 'must not work in post-mortem mode' do + enter 'set post_mortem', 'cont', 'step' + debug_file 'post_mortem', rescue: true + check_error_includes 'Unknown command: "step". Try "help".' + end + end + + describe 'next' do + it 'must not work in post-mortem mode' do + enter 'set post_mortem', 'cont', 'next' + debug_file 'post_mortem', rescue: true + check_error_includes 'Unknown command: "next". Try "help".' + end + end + + describe 'finish' do + it 'must not work in post-mortem mode' do + enter 'set post_mortem', 'cont', 'finish' + debug_file 'post_mortem', rescue: true + check_error_includes 'Unknown command: "finish". Try "help".' + end + end + + describe 'break' do + it 'must not be able to set breakpoints in post-mortem mode' do + enter 'set post_mortem', 'cont', "break #{__FILE__}:6" + debug_file 'post_mortem', rescue: true + check_error_includes "Unknown command: \"break #{__FILE__}:6\". " \ + 'Try "help".' + end + end + + describe 'condition' do + it 'must not be able to set conditions in post-mortem mode' do + enter "break #{__FILE__}:6", 'set post_mortem', 'cont', + ->{ "cond #{Byebug.breakpoints.last.id} true" } + debug_file 'post_mortem', rescue: true + check_error_includes \ + "Unknown command: \"cond #{Byebug.breakpoints.last.id} true\". " \ + "Try \"help\"." + end + end + + describe 'display' do + it 'must be not able to set display expressions in post-mortem mode' do + enter 'set post_mortem', 'cont', 'display 2 + 2' + debug_file 'post_mortem', rescue: true + check_error_includes 'Unknown command: "display 2 + 2". Try "help".' + end + end + + describe 'reload' do + it 'must work in post-mortem mode' do + enter 'set post_mortem', 'cont', 'reload' + debug_file 'post_mortem', rescue: true + check_error_includes 'Unknown command: "reload". Try "help".' + end + end + + + end + + describe 'Available commands' do + describe 'restart' do + it 'must work in post-mortem mode' do + must_restart + enter 'cont', 'restart' + debug_file 'post_mortem', rescue: true + end + end + + describe 'frame' do + it 'must work in post-mortem mode' do + enter 'cont', 'frame' + debug_file('post_mortem', rescue: true) { state.line.must_equal 4 } + check_output_includes(/--> #0 PostMortemExample\.a\s+at #{__FILE__}:4/) + end + end + + describe 'exit' do + it 'must work in post-mortem mode' do + Byebug::QuitCommand.any_instance.expects(:exit!) + enter 'cont', 'exit!' + debug_file 'post_mortem', rescue: true + end + end + + describe 'edit' do + temporary_change_hash ENV, 'EDITOR', 'editr' + + it 'must work in post-mortem mode' do + Byebug::Edit.any_instance. + expects(:system).with("editr +2 #{fullpath('edit')}") + enter 'cont', "edit #{fullpath('edit')}:2", 'cont' + debug_file 'post_mortem', rescue: true + end + end + + describe 'info' do + it 'must work in post-mortem mode' do + enter 'cont', 'info line' + debug_file 'post_mortem', rescue: true + check_output_includes "Line 4 of \"#{__FILE__}\"" + end + end + + describe 'irb' do + let(:irb) { stub(context: ->{}) } + + it 'must work in post-mortem mode' do + skip "Don't know why this is failing now..." + irb.stubs(:eval_input).throws(:IRB_EXIT, :cont) + enter 'cont', 'break 11', 'irb' + debug_file('post_mortem', rescue: true) { state.line.must_equal 11 } + end + end + + describe 'source' do + let(:filename) { 'source_example.txt' } + + before { File.open(filename, 'w') { |f| f.puts 'frame' } } + + it 'must work in post-mortem mode' do + enter 'cont', "so #{filename}" + debug_file('post_mortem', rescue: true) + check_output_includes(/--> #0 PostMortemExample\.a\s+at #{__FILE__}:4/) + end + end + + describe 'help' do + it 'must work in post-mortem mode' do + enter 'cont', 'help' + debug_file 'post_mortem', rescue: true + check_output_includes 'Available commands:' + end + end + + describe 'var' do + it 'must work in post-mortem mode' do + enter 'cont', 'var local' + debug_file 'post_mortem', rescue: true + check_output_includes 'x => nil', 'z => 4' + end + end + + describe 'list' do + it 'must work in post-mortem mode' do + enter 'cont' + debug_file 'post_mortem', rescue: true + check_output_includes "[1, 10] in #{__FILE__}" + end + end + + describe 'method' do + it 'must work in post-mortem mode' do + enter 'cont', 'm i self' + debug_file 'post_mortem', rescue: true + check_output_includes(/to_s/) + end + end + + describe 'kill' do + it 'must work in post-mortem mode' do + Process.expects(:kill).with('USR1', Process.pid) + enter 'cont', 'kill USR1' + debug_file 'post_mortem', rescue: true + end + end + + describe 'eval' do + it 'must work in post-mortem mode' do + enter 'cont', 'eval 2 + 2' + debug_file 'post_mortem', rescue: true + check_output_includes '4' + end + end + + describe 'set' do + temporary_change_hash Byebug.settings, :autolist, 0 + + it 'must work in post-mortem mode' do + enter 'cont', 'set autolist on' + debug_file 'post_mortem', rescue: true + check_output_includes 'autolist is on.' + end + end + + describe 'save' do + let(:file_name) { 'save_output.txt' } + let(:file_contents) { File.read(file_name) } + after { File.delete(file_name) } + + it 'must work in post-mortem mode' do + enter 'cont', "save #{file_name}" + debug_file 'post_mortem', rescue: true + file_contents.must_include 'set autoirb off' + end + end + + describe 'show' do + it 'must work in post-mortem mode' do + enter 'cont', 'show autolist' + debug_file 'post_mortem', rescue: true + check_output_includes 'autolist is on.' + end + end + + describe 'trace' do + it 'must work in post-mortem mode' do + enter 'cont', 'trace on' + debug_file 'post_mortem', rescue: true + check_output_includes 'line tracing is on.' + end + end + + describe 'thread' do + it "must work in post-mortem mode" do + enter 'cont', 'thread list' + debug_file 'post_mortem', rescue: true + check_output_includes(/\+ \d+ # do + change_line_in_file(fullpath('reload'), 4, 'a = 100') + 'reload' + end, 'l 4-4' + debug_file 'reload' + check_output_includes '4: a = 100' + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/repl_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/repl_test.rb new file mode 100644 index 0000000..313fc39 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/repl_test.rb @@ -0,0 +1,65 @@ +class TestRepl < TestDsl::TestCase + + describe 'Irb Command' do + before do + interface.stubs(:kind_of?).with(Byebug::LocalInterface).returns(true) + IRB::Irb.stubs(:new).returns(irb) + end + + let(:irb) { stub(context: ->{}) } + + it 'must support next command' do + irb.stubs(:eval_input).throws(:IRB_EXIT, :next) + enter 'irb' + debug_file('repl') { state.line.must_equal 3 } + end + + it 'must support step command' do + irb.stubs(:eval_input).throws(:IRB_EXIT, :step) + enter 'irb' + debug_file('repl') { state.line.must_equal 3 } + end + + it 'must support cont command' do + irb.stubs(:eval_input).throws(:IRB_EXIT, :cont) + enter 'break 4', 'irb' + debug_file('repl') { state.line.must_equal 4 } + end + + describe 'autoirb' do + it 'must call irb automatically after breakpoint' do + irb.expects(:eval_input) + enter 'set autoirb', 'break 4', 'cont', 'set noautoirb' + debug_file 'repl' + end + end + end + + @has_pry = false + describe 'Pry command' do + before do + interface.stubs(:kind_of?).with(Byebug::LocalInterface).returns(true) + Byebug::PryCommand.any_instance.expects(:pry) + end + + it 'must support step command' do + skip 'TODO' + end + + it 'must support cont command' do + skip 'TODO' + end + + describe 'autopry' do + it 'must call pry automatically after breakpoint' do + skip 'TODO' + end + end + + describe 'post-mortem' do + it 'must work in post-mortem mode' do + skip 'TODO' + end + end + end if @has_pry +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/restart_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/restart_test.rb new file mode 100644 index 0000000..aa5108a --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/restart_test.rb @@ -0,0 +1,142 @@ +class RestartExample + def concat_args(a, b, c) + a.to_s + b.to_s + c.to_s + end +end + +class TestRestart < TestDsl::TestCase + describe 'usual restarting' do + temporary_change_const Byebug, 'BYEBUG_SCRIPT', 'byebug_script' + + it 'must be restarted with arguments' do + Byebug::RestartCommand.any_instance.expects(:exec). + with("#{Byebug::BYEBUG_SCRIPT} #{Byebug::PROG_SCRIPT} 1 2 3") + enter 'restart 1 2 3' + debug_file 'restart' + end + + describe 'when arguments have spaces' do + temporary_change_hash Byebug.settings, :argv, ['argv1', 'argv 2'] + + it 'must be correctly escaped' do + Byebug::RestartCommand.any_instance.expects(:exec).with \ + "#{Byebug::BYEBUG_SCRIPT} #{Byebug::PROG_SCRIPT} argv1 argv\\ 2" + enter 'restart' + debug_file 'restart' + end + end + + describe 'when arguments specified by set command' do + temporary_change_hash Byebug.settings, :argv, [] + + it 'must specify arguments by "set" command' do + Byebug::RestartCommand.any_instance.expects(:exec). + with("#{Byebug::BYEBUG_SCRIPT} #{Byebug::PROG_SCRIPT} 1 2 3") + enter 'set args 1 2 3', 'restart' + debug_file 'restart' + end + end + end + + describe 'messaging' do + before { enter 'restart' } + + describe 'reexecing' do + temporary_change_const Byebug, 'BYEBUG_SCRIPT', 'byebug_script' + + describe 'with set args' do + temporary_change_hash Byebug.settings, :argv, ['argv'] + + it 'must restart and show a message about reexecing' do + must_restart + debug_file 'restart' + check_output_includes \ + "Re exec'ing:\n" \ + "\t#{Byebug::BYEBUG_SCRIPT} #{Byebug::PROG_SCRIPT} argv" + end + end + end + + describe 'no script specified' do + temporary_change_const Byebug, 'PROG_SCRIPT', :__undefined__ + + describe 'and no $0 used' do + temporary_change_const Byebug, 'DEFAULT_START_SETTINGS', + { init: false, post_mortem: false, tracing: nil } + + it 'must not restart and show error messages instead' do + must_restart.never + debug_file 'restart' + check_output_includes 'Don\'t know name of debugged program', + interface.error_queue + end + end + + describe 'but initialized from $0' do + it 'must use prog_script from $0' do + old_prog_name = $0 + $0 = 'prog-0' + debug_file 'restart' + check_output_includes 'Ruby program prog-0 doesn\'t exist', + interface.error_queue + $0 = old_prog_name + end + end + end + + describe 'no script at the specified path' do + temporary_change_const Byebug, 'PROG_SCRIPT', 'blabla' + + describe 'and no restart params set' do + temporary_change_const Byebug, 'DEFAULT_START_SETTINGS', + init: false, post_mortem: false, tracing: nil + + it 'must not restart' do + must_restart.never + debug_file 'restart' + end + + it 'must show an error message' do + debug_file 'restart' + check_output_includes 'Ruby program blabla doesn\'t exist', + interface.error_queue + end + end + end + + describe 'byebug runner script is not specified' do + before { must_restart } + + it 'must restart anyway' do + debug_file 'restart' + end + + it 'must show a warning message' do + debug_file 'restart' + check_output_includes 'Byebug was not called from the outset...' + end + + it 'must show a warning message when prog script is not executable' do + debug_file 'restart' + check_output_includes "Ruby program #{Byebug::PROG_SCRIPT} not " \ + "executable... We'll add a call to Ruby." + end + end + + describe 'when can\'t change the dir to INITIAL_DIR' do + temporary_change_const Byebug, 'INITIAL_DIR', '/unexistent/path' + + it 'must restart anyway' do + must_restart + debug_file 'restart' + end + + it 'must show an error message ' do + must_restart + debug_file 'restart' + check_output_includes \ + 'Failed to change initial directory /unexistent/path' + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/save_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/save_test.rb new file mode 100644 index 0000000..e10a85d --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/save_test.rb @@ -0,0 +1,74 @@ +class TestSave < TestDsl::TestCase + + describe 'successful saving' do + let(:file_name) { 'save_output.txt' } + let(:file_contents) { File.read(file_name) } + before do + enter 'break 2', 'break 3 if true', 'catch NoMethodError', + 'display 2 + 3', 'display 5 + 6', "save #{file_name}" + debug_file 'save' + end + after do + File.delete(file_name) + end + + it 'must save usual breakpoints' do + file_contents.must_include "break #{fullpath('save')}:2" + end + + it 'must save conditinal breakpoints' do + file_contents.must_include "break #{fullpath('save')}:3 if true" + end + + it 'must save catchpoints' do + file_contents.must_include 'catch NoMethodError' + end + + it 'must save displays' do + file_contents.must_include 'display 2 + 3' + end + + describe 'saving settings' do + it 'must save autoeval' do + file_contents.must_include 'set autoeval on' + end + + it 'must save basename' do + file_contents.must_include 'set basename off' + end + + it 'must save testing' do + file_contents.must_include 'set testing on' + end + + it 'must save autolist' do + file_contents.must_include 'set autolist on' + end + + it 'must save autoirb' do + file_contents.must_include 'set autoirb off' + end + end + + it 'must show a message about successful saving' do + check_output_includes "Saved to '#{file_name}'" + end + end + + describe 'without filename' do + let(:file_contents) { File.read(interface.restart_file) } + after { FileUtils.rm(interface.restart_file) } + + it 'must fabricate a filename if not provided' do + enter 'save' + debug_file 'save' + file_contents.must_include 'set autoirb' + end + + it 'must show a message where the file is saved' do + enter 'save' + debug_file 'save' + check_output_includes "Saved to '#{interface.restart_file}'" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/set_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/set_test.rb new file mode 100644 index 0000000..607bfee --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/set_test.rb @@ -0,0 +1,188 @@ +class TestSet < TestDsl::TestCase + + describe 'setting to on' do + temporary_change_hash Byebug.settings, :autolist, 0 + + it 'must set a setting to on' do + enter 'set autolist on' + debug_file 'set' + Byebug.settings[:autolist].must_equal 1 + end + + it 'must set a setting to on by 1' do + enter 'set autolist 1' + debug_file 'set' + Byebug.settings[:autolist].must_equal 1 + end + + it 'must set a setting to on by default' do + enter 'set autolist' + debug_file 'set' + Byebug.settings[:autolist].must_equal 1 + end + + it 'must set a setting using shortcut' do + enter 'set autol' + debug_file 'set' + Byebug.settings[:autolist].must_equal 1 + end + end + + describe 'setting to off' do + temporary_change_hash Byebug.settings, :autolist, 1 + + it 'must set a setting to off' do + enter 'set autolist off' + debug_file 'set' + Byebug.settings[:autolist].must_equal 0 + end + + it 'must set a setting to off by 0' do + enter 'set autolist 0' + debug_file 'set' + Byebug.settings[:autolist].must_equal 0 + end + + it 'must set a setting to off by "no" prefix' do + enter 'set noautolist' + debug_file 'set' + Byebug.settings[:autolist].must_equal 0 + end + + it 'must set a setting to off by "no" prefix and shortcut' do + enter 'set noautol' + debug_file 'set' + Byebug.settings[:autolist].must_equal 0 + end + end + + describe 'messages' do + temporary_change_hash Byebug.settings, :autolist, 0 + + it 'must show a message after setting' do + enter 'set autolist on' + debug_file 'set' + check_output_includes 'autolist is on.' + end + end + + describe 'testing' do + describe 'state' do + describe 'when setting "testing" to on' do + temporary_change_hash Byebug.settings, :testing, false + + it 'must get set' do + enter 'set testing', 'break 3', 'cont' + debug_file('set') { + state.must_be_kind_of Byebug::CommandProcessor::State } + end + end + + describe 'when setting "testing" to off' do + temporary_change_hash Byebug.settings, :testing, true + + it 'must get unset' do + enter 'set notesting', 'break 3', 'cont' + debug_file('set') { state.must_be_nil } + end + end + end + end + + describe 'history' do + describe 'save' do + it 'must set history save to on' do + enter 'set history save on' + debug_file 'set' + interface.history_save.must_equal true + end + + it 'must set history save to on when no param' do + enter 'set history save' + debug_file 'set' + interface.history_save.must_equal true + end + + it 'must show a message' do + enter 'set history save on' + debug_file 'set' + check_output_includes 'Saving of history save is on.' + end + + it 'must set history save to off' do + enter 'set history save off' + debug_file 'set' + interface.history_save.must_equal false + end + end + + describe 'size' do + it 'must set history size' do + enter 'set history size 250' + debug_file 'set' + interface.history_length.must_equal 250 + end + + it 'must show a message' do + enter 'set history size 250' + debug_file 'set' + check_output_includes 'Byebug history size is 250' + end + + it 'must show an error message if no size provided' do + enter 'set history size' + debug_file 'set' + check_output_includes 'You need to specify the history size' + end + end + + describe 'filename' do + let(:filename) { + File.join(ENV['HOME']||ENV['HOMEPATH']||'.', '.byebug-hist') } + + it 'must set history filename' do + enter 'set history filename .byebug-hist' + debug_file 'set' + interface.histfile.must_equal filename + end + + it 'must show a message' do + enter 'set history filename .byebug-hist' + debug_file 'set' + check_output_includes "The command history file is \"#{filename}\"" + end + + it 'must show an error message if no filenmae provided' do + enter 'set history filename' + debug_file 'set' + check_output_includes 'You need to specify a filename' + end + + end + + it 'must show an error message if used wrong subcommand' do + enter 'set history bla 2' + debug_file 'set' + check_output_includes \ + 'Invalid history parameter bla. Should be "filename", "save" or "size"' + end + end + + describe 'width' do + temporary_change_hash Byebug.settings, :width, 20 + + it 'must get correctly set' do + enter 'set width 10' + debug_file('set') + Byebug.settings[:width].must_equal 10 + end + end + + describe 'Help' do + it 'must show help when typing just "set"' do + enter 'set', 'cont' + debug_file 'set' + check_output_includes(/List of "set" subcommands:/) + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/show_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/show_test.rb new file mode 100644 index 0000000..29652a7 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/show_test.rb @@ -0,0 +1,265 @@ +class TestShow < TestDsl::TestCase + describe 'args' do + temporary_change_hash Byebug.settings, :argv, %w{foo bar} + + describe 'default behaviour' do + it 'must show args' do + enter 'show args' + debug_file 'show' + check_output_includes 'Argument list to give program being debugged ' \ + 'when it is started is "foo bar".' + end + end + + describe 'when BYEBUG_SCRIPT is defined' do + temporary_change_const Byebug, 'BYEBUG_SCRIPT', 'bla' + + it 'must not show the first arg' do + enter 'show args' + debug_file 'show' + check_output_includes 'Argument list to give program being debugged ' \ + 'when it is started is "bar".' + end + end + end + + describe 'autolist' do + it 'must show default value' do + enter 'show autolist' + debug_file 'show' + check_output_includes 'autolist is on.' + end + end + + describe 'autoeval' do + it 'must show default value' do + enter 'show autoeval' + debug_file 'show' + check_output_includes 'autoeval is on.' + end + end + + describe 'autoreload' do + it 'must show default value' do + enter 'show autoreload' + debug_file 'show' + check_output_includes 'autoreload is on.' + end + end + + describe 'autoirb' do + before { Byebug::IRBCommand.any_instance.stubs(:execute) } + + it 'must show default value' do + enter 'show autoirb' + debug_file 'show' + check_output_includes 'autoirb is off.' + end + end + + describe 'basename' do + it 'must show default value' do + enter 'show basename' + debug_file 'show' + check_output_includes 'basename is off.' + end + end + + describe 'callstyle' do + it 'must show default value' do + enter 'show callstyle' + debug_file 'show' + check_output_includes 'Frame call-display style is long.' + end + end + + describe 'forcestep' do + it 'must show default value' do + enter 'show forcestep' + debug_file 'show' + check_output_includes 'force-stepping is off.' + end + end + + describe 'fullpath' do + it 'must show default value' do + enter 'show fullpath' + debug_file 'show' + check_output_includes 'Displaying frame\'s full file names is on.' + end + end + + describe 'linetrace' do + it 'must show default value' do + enter 'show linetrace' + debug_file 'show' + check_output_includes 'line tracing is off.' + end + end + + describe 'linetrace_plus' do + it 'must show default value' do + enter 'show linetrace_plus' + debug_file 'show' + check_output_includes 'line tracing style is different consecutive lines.' + end + end + + describe 'listsize' do + it 'must show listsize' do + enter 'show listsize' + debug_file 'show' + check_output_includes 'Number of source lines to list is 10.' + end + end + + describe 'stack_on_error' do + it 'must show stack_on_error' do + enter 'show stack_on_error' + debug_file 'show' + check_output_includes 'Displaying stack trace is off.' + end + end + + describe 'version' do + it 'must show version' do + enter 'show version' + debug_file 'show' + check_output_includes "Byebug #{Byebug::VERSION}" + end + end + + describe 'width' do + let(:cols) { `stty size`.scan(/\d+/)[1].to_i } + + it 'must show default width' do + enter 'show width' + debug_file 'show' + check_output_includes "width is #{cols}." + end + end + + describe 'unknown command' do + it 'must show a message' do + enter 'show bla' + debug_file 'show' + check_output_includes 'Unknown show command bla' + end + end + + describe 'history' do + describe 'without arguments' do + before do + interface.histfile = 'hist_file.txt' + interface.history_save = true + interface.history_length = 25 + enter 'show history' + debug_file 'show' + end + + it 'must show history file' do + check_output_includes( + /filename: The command history file is "hist_file\.txt"/) + end + + it 'must show history save setting' do + check_output_includes(/save: Saving of history save is on\./) + end + + it 'must show history length' do + check_output_includes(/size: Byebug history size is 25/) + end + end + + describe 'with "filename" argument' do + it 'must show history filename' do + interface.histfile = 'hist_file.txt' + enter 'show history filename' + debug_file 'show' + check_output_includes 'The command history file is "hist_file.txt"' + end + + it 'must show history save setting' do + interface.history_save = true + enter 'show history save' + debug_file 'show' + check_output_includes 'Saving of history save is on.' + end + + it 'must show history length' do + interface.history_length = 30 + enter 'show history size' + debug_file 'show' + check_output_includes 'Byebug history size is 30' + end + end + end + + describe 'commands' do + describe 'no readline support' do + before { interface.readline_support = false } + + it 'must not show records from readline' do + enter 'show commands' + debug_file 'show' + check_output_includes 'No readline support' + end + end + + describe 'readline support' do + before { interface.readline_support = true } + + describe 'show records' do + temporary_change_const Readline, 'HISTORY', %w{aaa bbb ccc ddd eee fff} + + it 'must show records from readline history' do + enter 'show commands' + debug_file 'show' + check_output_includes(/1 aaa/) + check_output_includes(/6 fff/) + end + end + + describe 'max records' do + temporary_change_const Readline, 'HISTORY', %w{aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn} + + it 'must show last 10 records from readline history' do + enter 'show commands' + debug_file 'show' + check_output_doesnt_include(/3 ddd/) + check_output_includes(/4 eee/) + check_output_includes(/13 nnn/) + end + end + + describe 'with specified positions' do + temporary_change_const Readline, 'HISTORY', %w{aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn} + + it 'must show records within boundaries' do + # Really don't know why it substracts 4, and shows starting from position 6 + enter 'show commands 10' + debug_file 'show' + check_output_doesnt_include(/5 fff/) + check_output_includes(/6 ggg/) + check_output_includes(/13 nnn/) + end + + it 'must adjust first line if it is < 0' do + enter 'show commands 3' + debug_file 'show' + check_output_includes(/1 bbb/) + check_output_includes(/8 iii/) + check_output_doesnt_include(/9 jjj/) + end + end + end + end + + describe 'Help' do + it 'must show help when typing just "show"' do + enter 'show', 'cont' + debug_file 'show' + check_output_includes(/List of "show" subcommands:/) + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/source_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/source_test.rb new file mode 100644 index 0000000..0e9b1b4 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/source_test.rb @@ -0,0 +1,39 @@ +class TestSource < TestDsl::TestCase + let(:filename) { 'source_example.txt' } + + before { File.open(filename, 'w') do |f| + f.puts 'break 2' + f.puts 'break 3 if true' + end } + + after { FileUtils.rm(filename) } + + it 'must run commands from file' do + enter "source #{filename}" + debug_file 'source' do + Byebug.breakpoints[0].pos.must_equal 2 + Byebug.breakpoints[1].pos.must_equal 3 + Byebug.breakpoints[1].expr.must_equal 'true' + end + end + + it 'must be able to use shortcut' do + enter "so #{filename}" + debug_file('source') { Byebug.breakpoints[0].pos.must_equal 2 } + end + + it 'must show an error if file is not found' do + enter 'source blabla' + debug_file 'source' + check_error_includes(/File ".*blabla" not found/) + end + + describe 'Help' do + it 'must show help when used without arguments' do + enter 'source' + debug_file 'source' + check_output_includes \ + "source FILE\texecutes a file containing byebug commands" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/stepping_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/stepping_test.rb new file mode 100644 index 0000000..e42e9bc --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/stepping_test.rb @@ -0,0 +1,184 @@ +class SteppingExample + def self.a(num) + num += 2 + b(num) + end + + def self.b(num) + v2 = 5 if 1 == num ; [1, 2, v2].map { |a| a.to_f } + c(num) + end + + def self.c(num) + num += 4 + num + end +end + +class SteppingRaiseFromRubyMethodExample + def a + b + rescue + 1 + end + + def b + c + end + + def c + raise 'bang' + end +end + +class SteppingRaiseFromCMethodExample + def a + b + rescue NameError + 1 + end + + def b + c + end + + def c + d + end +end + +class TestStepping < TestDsl::TestCase + + describe 'Next Command' do + + describe 'method call behaviour' do + before { enter "break #{__FILE__}:8", 'cont' } + + it 'must leave on the same line by default' do + enter 'next' + debug_file('stepping') { state.line.must_equal 8 } + end + + it 'must go to the next line if forced by "plus" sign' do + enter 'next+' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must leave on the same line if forced by "minus" sign' do + enter 'next-' + debug_file('stepping') { state.line.must_equal 8 } + end + + describe 'when forcestep is set' do + temporary_change_hash Byebug.settings, :forcestep, true + + it 'must go to the next line' do + enter 'next' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must go to the next line (by shortcut)' do + enter 'n' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must go the specified number of lines forward by default' do + enter 'next 2' + debug_file('stepping') { state.line.must_equal 4 } + end + + it 'must inform when not staying in the same frame' do + enter 'next 2' + debug_file('stepping') + check_output_includes \ + 'Next went up a frame because previous frame finished' + end + + + it 'must ignore it if "minus" is specified' do + enter 'next-' + debug_file('stepping') { state.line.must_equal 8 } + end + end + end + + describe 'block behaviour' do + before { enter 'break 4', 'cont' } + + it 'must step over blocks' do + enter 'next' + debug_file('stepping') { state.line.must_equal 8 } + end + end + + describe 'raise/rescue behaviour' do + describe 'from c method' do + before { enter "break #{__FILE__}:36", 'cont' } + + it 'must step over rescue' do + enter 'next' + debug_file('stepping_raise_from_c_method') { state.line.must_equal 38 } + end + end + + describe 'from ruby method' do + before { enter "break #{__FILE__}:20", 'cont' } + + it 'must step over rescue' do + enter 'next' + debug_file('stepping_raise_from_ruby_method') { state.line.must_equal 22 } + end + end + end + end + + describe 'Step Command' do + + describe 'method call behaviour' do + before { enter "break #{__FILE__}:8", 'cont' } + + it 'must leave on the same line if forced by a setting' do + enter 'step' + debug_file('stepping') { state.line.must_equal 8 } + end + + it 'must go to the step line if forced to do that by "plus" sign' do + enter 'step+' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must leave on the same line if forced to do that by "minus" sign' do + enter 'step-' + debug_file('stepping') { state.line.must_equal 8 } + end + + describe 'when forcestep is set' do + temporary_change_hash Byebug.settings, :forcestep, true + + it 'must go to the step line if forced by a setting' do + enter 'step' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must go to the next line if forced by a setting (by shortcut)' do + enter 's' + debug_file('stepping') { state.line.must_equal 9 } + end + + it 'must go the specified number of lines forward by default' do + enter 'step 2' + debug_file('stepping') { state.line.must_equal 13 } + end + end + end + + describe 'block behaviour' do + before { enter 'break 4', 'cont' } + + it 'must step into blocks' do + enter 'step' + debug_file('stepping') { state.line.must_equal 5 } + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/support/breakpoint.rb b/vendor/bundle/gems/byebug-2.7.0/test/support/breakpoint.rb new file mode 100644 index 0000000..3bf8370 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/support/breakpoint.rb @@ -0,0 +1,13 @@ +module Byebug + + class Breakpoint + + def inspect + values = %w{id pos source expr hit_condition hit_count hit_value enabled?}.map do |field| + "#{field}: #{send(field)}" + end.join(", ") + "#" + end + + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/support/matchers.rb b/vendor/bundle/gems/byebug-2.7.0/test/support/matchers.rb new file mode 100644 index 0000000..64f6494 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/support/matchers.rb @@ -0,0 +1,68 @@ +module MiniTest::Assertions + + # This matcher checks that given collection is included into the original + # collection and in correct order. It accepts both strings and regexps. + # + # Examples: + # assert_includes_in_order(%w{1 2 3 4 5}, %w{1 3 5}) # => pass + # assert_includes_in_order(%w{1 2 3 4 5}, %w{1 5 3}) # => fail + # assert_includes_in_order(w{1 2 3 4 5}, ["1", /\d+/, "5"]) # => pass + # assert_includes_in_order(w{1 2 3 4 5}, ["1", /\[a-z]+/, "5"]) # => fail + # + def assert_includes_in_order(given_collection, original_collection, msg = nil) + msg = message(msg) do + "Expected #{mu_pp(original_collection)} " \ + "to include #{mu_pp(given_collection)} in order" + end + assert includes_in_order_result(original_collection, given_collection), msg + end + + def refute_includes_in_order(given_collection, original_collection, msg = nil) + msg = message(msg) do + "Expected #{mu_pp(original_collection)} " \ + "to not include #{mu_pp(given_collection)} in order" + end + refute includes_in_order_result(original_collection, given_collection), msg + end + + + private + + def includes_in_order_result(original_collection, given_collection) + result = true + given_collection.each do |given_item| + result &&= case given_item + when String + index = original_collection.index(given_item) + if index + original_collection = original_collection[(index + 1)..-1] + true + else + false + end + when Regexp + index = nil + original_collection.each_with_index do |original_item, i| + if original_item =~ given_item + index = i + break + end + end + if index + original_collection = original_collection[(index + 1)..-1] + true + else + false + end + else + false + end + end + result + end +end + +module MiniTest::Expectations + infect_an_assertion :assert_includes_in_order, :must_include_in_order + infect_an_assertion :refute_includes_in_order, :wont_include_in_order +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/support/test_dsl.rb b/vendor/bundle/gems/byebug-2.7.0/test/support/test_dsl.rb new file mode 100644 index 0000000..a4da015 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/support/test_dsl.rb @@ -0,0 +1,189 @@ +module TestDsl + + class TestCase < MiniTest::Spec + include TestDsl + + def setup + Byebug.handler = Byebug::CommandProcessor.new(TestInterface.new) + Byebug.tracing = false + Byebug.breakpoints.clear if Byebug.breakpoints + end + + def self.temporary_change_hash hash, key, value + before do + @old_hashes ||= {} + @old_hashes.merge!({ hash => { key => hash[key] } }) do |k, v1, v2| + v1.merge(v2) + end + hash[key] = value + end + + after do + hash[key] = @old_hashes[hash][key] + end + end + + def self.temporary_change_const klass, const, value + before do + @old_consts ||= {} + old_value = klass.const_defined?(const) ? + klass.const_get(const) : :__undefined__ + @old_consts.merge!({ klass => { const => old_value } }) do |k, v1, v2| + v1.merge(v2) + end + klass.send :remove_const, const if klass.const_defined?(const) + klass.const_set const, value unless value == :__undefined__ + end + + after do + klass.send :remove_const, const if klass.const_defined?(const) + klass.const_set const, @old_consts[klass][const] unless + @old_consts[klass][const] == :__undefined__ + end + end + end + + # + # Expand fullpath of a given example file + # + def fullpath(filename) + (Pathname.new(__FILE__) + "../../examples/#{filename}.rb").cleanpath.to_s + end + + # + # Shorten a fullpath + # + def shortpath(fullpath) + separator = File::ALT_SEPARATOR || File::SEPARATOR + "...#{separator}" + fullpath.split(separator)[-3..-1].join(separator) + end + + # + # Adds commands to the input queue, so they will be later retrieved by + # Processor, i.e., it emulates user's input. + # + # If a command is a Proc object, it will be executed before being retrieved by + # Processor. May be handy when you need build a command depending on the + # current context/state. + # + # Usage: + # enter 'b 12' + # enter 'b 12', 'cont' + # enter ['b 12', 'cont'] + # enter 'b 12', ->{"disable #{breakpoint.id}"}, 'cont' + # + def enter(*messages) + messages = messages.first.is_a?(Array) ? messages.first : messages + interface.input_queue.concat(messages) + end + + # + # Runs byebug with the provided basename for a file. + # + # You also can specify a block, which will be executed when Processor extracts + # all the commands from the input queue. You can use that for making asserts + # on the current test. If you specified the block and it never was executed, + # the test will fail. + # + # Usage: + # debug_file '/path/to/ex1.rb' + # + # enter 'b 4', 'cont' + # debug_file('/path/to/ex2.rb') { state.line.must_equal 4 } + # + def debug_file(filename, options = {}, &block) + is_test_block_called = false + exception = nil + Byebug.stubs(:run_init_script) + if block + interface.test_block = lambda do + is_test_block_called = true + # We need to store exception and reraise it after completing debugging, + # because Byebug will swallow any exceptions, so e.g. our failed + # assertions will be ignored + begin + block.call + rescue Exception => e + exception = e + end + end + end + begin + load fullpath(filename) + rescue Exception => e + if options[:rescue] + interface.test_block.call if interface.test_block + else + raise e + end + end + + flunk "Test block was provided, but not called" if block && !is_test_block_called + raise exception if exception + end + + # + # Checks the output of byebug. + # + # By default it checks output queue of the current interface, but you can + # check again any queue by providing it as a second argument. + # + # Usage: + # enter 'break 4', 'cont' + # debug 'ex1' + # check_output "Breakpoint 1 at #{fullpath('ex1')}:4" + # + def check_output(check_method, *args) + queue = args.last.is_a?(String) || args.last.is_a?(Regexp) ? + interface.output_queue : args.pop + queue_messages = queue.map(&:strip) + messages = Array(args).map { |msg| msg.is_a?(String) ? msg.strip : msg } + queue_messages.send(check_method, messages) + end + + def check_error_includes(*args) + check_output :must_include_in_order, *args, interface.error_queue + end + + def check_output_includes(*args) + check_output :must_include_in_order, *args + end + + def check_output_doesnt_include(*args) + check_output :wont_include_in_order, *args + end + + def interface + Byebug.handler.interface + end + + def state + Thread.current.thread_variable_get('state') + end + + def context + state.context + end + + def force_set_const(klass, const, value) + force_unset_const(klass, const) + klass.const_set(const, value) + end + + def force_unset_const(klass, const) + klass.send(:remove_const, const) if klass.const_defined?(const) + end + + def change_line_in_file(file, line, new_line_content) + old_content = File.read(file) + new_content = old_content.split("\n") + .tap { |c| c[line - 1] = new_line_content } + .join("\n") + "\n" + File.open(file, 'w') { |f| f.write(new_content) } + end + + def must_restart + Byebug::RestartCommand.any_instance.unstub(:exec) + Byebug::RestartCommand.any_instance.expects(:exec) + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/support/test_interface.rb b/vendor/bundle/gems/byebug-2.7.0/test/support/test_interface.rb new file mode 100644 index 0000000..fe04a26 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/support/test_interface.rb @@ -0,0 +1,59 @@ +class TestInterface < Byebug::Interface + attr_reader :input_queue, :output_queue, :error_queue, :confirm_queue + + attr_accessor :command_queue, :histfile, :history_length, :history_save + attr_accessor :readline_support, :restart_file, :test_block + + def initialize + @input_queue = [] + @output_queue = [] + @error_queue = [] + @confirm_queue = [] + @command_queue = [] + @readline_support = false + end + + def errmsg(*args) + @error_queue << format(*args) + end + + def read_command(*args) + if @input_queue.empty? + if test_block + test_block.call + self.test_block = nil + end + else + result = @input_queue.shift + result.is_a?(Proc) ? result.call : result + end + end + + def print(*args) + @output_queue << format(*args) + end + + def confirm(message) + @confirm_queue << message + read_command message + end + + def readline_support? + @readline_support + end + + def finalize + end + + def close + end + + def inspect + [ + "input_queue: #{input_queue.inspect}", + "output_queue: #{output_queue.inspect}", + "error_queue: #{error_queue.inspect}", + "confirm_queue: #{confirm_queue.inspect}" + ].join("\n") + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/test_helper.rb b/vendor/bundle/gems/byebug-2.7.0/test/test_helper.rb new file mode 100644 index 0000000..8919fa1 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/test_helper.rb @@ -0,0 +1,46 @@ +if ENV['CI'] + require 'coveralls' + Coveralls.wear! do + add_filter 'test' + end +end + +require 'minitest' +require 'minitest/spec' +require 'pathname' +require 'mocha/mini_test' +require 'byebug' + +Dir.glob(File.expand_path("../support/*.rb", __FILE__)).each { |f| require f } + +Byebug.settings[:testing] = true + +class DummyObject + def initialize(*args) + end +end + +# Init globals to avoid warnings +$bla = nil +$binding = binding # this is from irb... + +# Load the test files from the command line. +argv = ARGV.select do |argument| + case argument + when /^-/ then + argument + when /\*/ then + Dir.glob('test/*_test.rb').each do |file| + require File.expand_path file + end + false + else + require File.expand_path argument + false + end +end + +ARGV.replace argv + +# Run the tests +Minitest.run diff --git a/vendor/bundle/gems/byebug-2.7.0/test/thread_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/thread_test.rb new file mode 100644 index 0000000..3cd4a00 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/thread_test.rb @@ -0,0 +1,138 @@ +class ThreadExample + def initialize + Thread.main[:should_break] = false + end + + def launch + @t1 = Thread.new do + while true + break if Thread.main[:should_break] + sleep 0.02 + end + end + + @t2 = Thread.new do + while true + sleep 0.02 + end + end + + @t1.join + Thread.main[:should_break] + end + + def kill + @t2.kill + end +end + +class TestThread < TestDsl::TestCase + let(:release) { 'eval Thread.main[:should_break] = true' } + + describe 'list' do + it 'must show current thread by "plus" sign' do + thnum = nil + enter "break #{__FILE__}:7", 'cont', 'thread list', release + debug_file('thread') { thnum = Byebug.contexts.first.thnum } + check_output_includes(/\+ #{thnum} #\t#{__FILE__}:7/) + end + + it 'must work with shortcut' do + thnum = nil + enter "break #{__FILE__}:7", 'cont', 'th list', release + debug_file('thread') { thnum = Byebug.contexts.first.thnum } + check_output_includes(/\+ #{thnum} #\t#{__FILE__}:7/) + end + + it 'must show 3 available threads' do + enter "break #{__FILE__}:20", 'cont', 'thread list', release + debug_file 'thread' + check_output_includes(/(\+)?\d+ #/, + /(\+)?\d+ #/, + /(\+)?\d+ #/) + end + end + + describe 'stop' do + it 'must mark thread as suspended' do + thnum = nil + enter "break #{__FILE__}:20", 'cont', + ->{ "thread stop #{Byebug.contexts.last.thnum}" }, release + debug_file('thread') { thnum = Byebug.contexts.last.thnum } + check_output_includes(/\$ #{thnum} #{ "thread stop #{Byebug.contexts.last.thnum}" }, release + debug_file('thread') + check_output_doesnt_include(/Tracing: #{__FILE__}:15/, + /Tracing: #{__FILE__}:16/) + end + + it 'must show error message if thread number is not specified' do + enter "break #{__FILE__}:7", 'cont', 'thread stop', release + debug_file 'thread' + check_error_includes '"thread stop" needs a thread number' + end + + it 'must show error message when trying to stop current thread' do + enter "break #{__FILE__}:7", 'cont', + ->{"thread stop #{Byebug.contexts.first.thnum}"}, release + debug_file 'thread' + check_error_includes "It's the current thread" + end + end + + describe 'resume' do + it 'must mark remove thread from the suspended state' do + thnum = nil + enter "break #{__FILE__}:20", 'cont', + -> { thnum = Byebug.contexts.last.thnum ; "thread stop #{thnum}" }, + -> { "thread resume #{thnum}" }, release + debug_file('thread') { Byebug.contexts.last.suspended?.must_equal false } + check_output_includes(/\$ #{thnum} #{ "thread resume #{Byebug.contexts.first.thnum}" }, release + debug_file 'thread' + check_error_includes "It's the current thread" + end + + it 'must show error message if it is not stopped' do + enter "break #{__FILE__}:20", 'cont', + ->{ "thread resume #{Byebug.contexts.last.thnum}" }, release + debug_file 'thread' + check_error_includes 'Already running' + end + end + + describe 'switch' do + it 'must switch to another thread' do + enter "break #{__FILE__}:20", 'cont', + ->{ "thread switch #{Byebug.contexts.last.thnum}" }, release + debug_file('thread') { assert_equal state.line, 15 } + end + + it 'must show error message if thread number is not specified' do + enter "break #{__FILE__}:7", 'cont', 'thread switch', release + debug_file 'thread' + check_error_includes '"thread switch" needs a thread number' + end + + it 'must show error message when trying to switch current thread' do + enter "break #{__FILE__}:7", 'cont', + ->{ "thread switch #{Byebug.contexts.first.thnum}" }, release + debug_file 'thread' + check_error_includes "It's the current thread" + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/trace_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/trace_test.rb new file mode 100644 index 0000000..71bbfa4 --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/trace_test.rb @@ -0,0 +1,105 @@ +class TestTrace < TestDsl::TestCase + before do + untrace_var(:$bla) if defined?($bla) + end + + describe 'tracing' do + + describe 'enabling' do + it 'must trace execution by setting trace to on' do + enter 'trace on', 'cont 7', 'trace off' + debug_file 'trace' + check_output_includes 'line tracing is on.', + "Tracing: #{fullpath('trace')}:4 $bla = 4", + "Tracing: #{fullpath('trace')}:7 $bla = 7" + end + + it 'must be able to use a shortcut' do + enter 'tr on', 'cont 7', 'trace off' + debug_file 'trace' + check_output_includes 'line tracing is on.', + "Tracing: #{fullpath('trace')}:4 $bla = 4", + "Tracing: #{fullpath('trace')}:7 $bla = 7" + end + + it 'must correctly print lines containing % sign' do + enter 'cont 7', 'trace on', 'next', 'trace off' + debug_file 'trace' + check_output_includes \ + "Tracing: #{fullpath('trace')}:8 $bla = (0 == (7 % $bla))" + end + + describe 'when basename set' do + temporary_change_hash Byebug.settings, :basename, true + + it 'must correctly print file lines' do + enter 'tr on', 'cont 7', 'trace off' + debug_file 'trace' + check_output_includes \ + "Tracing: #{File.basename(fullpath('trace'))}:7 $bla = 7" + end + end + end + + it 'must show an error message if given subcommand is incorrect' do + enter 'trace bla' + debug_file 'trace' + check_error_includes \ + 'expecting "on", "off", "var" or "variable"; got: "bla"' + end + + describe 'disabling' do + it 'must stop tracing by setting trace to off' do + enter 'trace on', 'next', 'trace off' + debug_file 'trace' + check_output_includes "Tracing: #{fullpath('trace')}:4 $bla = 4" + check_output_doesnt_include "Tracing: #{fullpath('trace')}:5 $bla = 5" + end + + it 'must show a message when turned off' do + enter 'trace off' + debug_file 'trace' + check_output_includes 'line tracing is off.' + end + end + end + + describe 'tracing global variables' do + it 'must track global variable' do + enter 'trace variable bla' + debug_file 'trace' + check_output_includes "traced global variable 'bla' has value '3'", + "traced global variable 'bla' has value '7'" + end + + it 'must be able to use a shortcut' do + enter 'trace var bla' + debug_file 'trace' + check_output_includes "traced global variable 'bla' has value '3'" + end + + it 'must track global variable with stop' do + enter 'trace variable bla stop', 'break 7', 'cont' + debug_file('trace') { state.line.must_equal 4 } + end + + it 'must track global variable with nostop' do + enter 'trace variable bla nostop', 'break 7', 'cont' + debug_file('trace') { state.line.must_equal 7 } + end + + describe 'errors' do + it 'must show an error message if there is no such global variable' do + enter 'trace variable foo' + debug_file 'trace' + check_error_includes "'foo' is not a global variable." + end + + it 'must show an error message if subcommand is invalid' do + enter 'trace variable bla foo' + debug_file 'trace' + check_error_includes 'expecting "stop" or "nostop"; got "foo"' + end + end + end +end diff --git a/vendor/bundle/gems/byebug-2.7.0/test/variables_test.rb b/vendor/bundle/gems/byebug-2.7.0/test/variables_test.rb new file mode 100644 index 0000000..48841fc --- /dev/null +++ b/vendor/bundle/gems/byebug-2.7.0/test/variables_test.rb @@ -0,0 +1,127 @@ +class VariablesExample + SOMECONST = 'foo' unless defined?(SOMECONST) + + def initialize + @inst_a = 1 + @inst_b = 2 + @inst_c = "1" * 40 + @inst_d = BasicObject.new + @@class_c = 3 + end + + def run + a = 4 + b = [1, 2, 3].map do |i| + a * i + end + b + end +end + +class TestVariables < TestDsl::TestCase + describe 'class variables' do + before { enter "break #{__FILE__}:17", 'cont' } + + it 'must show variables' do + enter 'var class' + debug_file 'variables' + check_output_includes '@@class_c = 3' + end + + it 'must be able to use shortcut' do + enter 'v cl' + debug_file 'variables' + check_output_includes '@@class_c = 3' + end + end + + describe 'constants' do + it 'must show constants' do + enter 'break 4', 'cont', 'var const VariablesExample' + debug_file 'variables' + check_output_includes 'SOMECONST => "foo"' + end + + it 'must be able to use shortcut' do + enter 'break 4', 'cont', 'v co VariablesExample' + debug_file 'variables' + check_output_includes 'SOMECONST => "foo"' + end + + it 'must show error message if given object is not a class or a module' do + enter 'break 4', 'cont', 'var const v' + debug_file 'variables' + check_output_includes 'Should be Class/Module: v' + end + end + + describe 'globals' do + it 'must show global variables' do + enter 'break 4', 'cont', 'var global' + debug_file 'variables' + check_output_includes '$VERBOSE = true' + end + + it 'must be able to use shortcut' do + enter 'break 4', 'cont', 'v g' + debug_file 'variables' + check_output_includes '$VERBOSE = true' + end + end + + describe 'instance variables' do + it 'must show instance variables of the given object' do + enter 'break 4', 'cont', 'var instance v' + debug_file 'variables' + check_output_includes '@inst_a = 1', '@inst_b = 2' + end + + it 'must show instance variables of self' do + enter "break #{__FILE__}:9", 'cont', 'var instance' + debug_file 'variables' + check_output_includes '@inst_a = 1', '@inst_b = 2' + end + + it 'must show instance variables' do + enter 'break 4', 'cont', 'var instance v' + debug_file 'variables' + check_output_includes '@inst_a = 1', '@inst_b = 2' + end + + it 'must be able to use shortcut' do + enter 'break 4', 'cont', 'v ins v' + debug_file 'variables' + check_output_includes '@inst_a = 1', '@inst_b = 2' + end + + describe 'when width is too small' do + temporary_change_hash Byebug.settings, :width, 20 + + it 'must cut long variable values according it' do + enter 'break 4', 'cont', 'var instance v' + debug_file 'variables' + check_output_includes '@inst_c = "1111111111111111...' + end + end + + it 'must show error if value doesn\'t have #to_s/#inspect methods' do + enter 'break 4', 'cont', 'var instance v' + debug_file 'variables' + check_output_includes '@inst_d = *Error in evaluation*' + end + end + + describe 'local variables' do + it 'must show local variables' do + enter "break #{__FILE__}:15", 'cont', 'var local' + debug_file 'variables' + check_output_includes 'a => 4', 'b => nil', 'i => 1' + end + end + + describe 'test for "var ct" command' do + it 'must work' do + skip('can\'t install ruby-internal gem') + end + end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/README_INDEX.rdoc b/vendor/bundle/gems/coderay-1.1.0/README_INDEX.rdoc new file mode 100644 index 0000000..7332653 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/README_INDEX.rdoc @@ -0,0 +1,123 @@ += CodeRay + +Tired of blue'n'gray? Try the original version of this documentation on +coderay.rubychan.de[http://coderay.rubychan.de/doc/] :-) + +== About + +CodeRay is a Ruby library for syntax highlighting. + +You put your code in, and you get it back colored; Keywords, strings, +floats, comments - all in different colors. And with line numbers. + +*Syntax* *Highlighting*... +* makes code easier to read and maintain +* lets you detect syntax errors faster +* helps you to understand the syntax of a language +* looks nice +* is what everybody wants to have on their website +* solves all your problems and makes the girls run after you + + +== Installation + + % gem install coderay + + +=== Dependencies + +CodeRay needs Ruby 1.8.7+ or 1.9.2+. It also runs on Rubinius and JRuby. + + +== Example Usage + + require 'coderay' + + html = CodeRay.scan("puts 'Hello, world!'", :ruby).div(:line_numbers => :table) + + +== Documentation + +See CodeRay. + + +== Credits + +=== Special Thanks to + +* licenser (Heinz N. Gies) for ending my QBasic career, inventing the Coder + project and the input/output plugin system. + CodeRay would not exist without him. +* bovi (Daniel Bovensiepen) for helping me out on various occasions. + +=== Thanks to + +* Caleb Clausen for writing RubyLexer (see + http://rubyforge.org/projects/rubylexer) and lots of very interesting mail + traffic +* birkenfeld (Georg Brandl) and mitsuhiku (Arnim Ronacher) for PyKleur, now pygments. + You guys rock! +* Jamis Buck for writing Syntax (see http://rubyforge.org/projects/syntax) + I got some useful ideas from it. +* Doug Kearns and everyone else who worked on ruby.vim - it not only helped me + coding CodeRay, but also gave me a wonderful target to reach for the Ruby + scanner. +* everyone who uses CodeBB on http://www.rubyforen.de and http://www.python-forum.de +* iGEL, magichisoka, manveru, WoNáDo and everyone I forgot from rubyforen.de +* Dethix from ruby-mine.de +* zickzackw +* Dookie (who is no longer with us...) and Leonidas from http://www.python-forum.de +* Andreas Schwarz for finding out that CaseIgnoringWordList was not case + ignoring! Such things really make you write tests. +* closure for the first version of the Scheme scanner. +* Stefan Walk for the first version of the JavaScript and PHP scanners. +* Josh Goebel for another version of the JavaScript scanner, a SQL and a Diff scanner. +* Jonathan Younger for pointing out the licence confusion caused by wrong LICENSE file. +* Jeremy Hinegardner for finding the shebang-on-empty-file bug in FileType. +* Charles Oliver Nutter and Yehuda Katz for helping me benchmark CodeRay on JRuby. +* Andreas Neuhaus for pointing out a markup bug in coderay/for_redcloth. +* 0xf30fc7 for the FileType patch concerning Delphi file extensions. +* The folks at redmine.org - thank you for using and fixing CodeRay! +* Keith Pitt for his SQL scanners +* Rob Aldred for the terminal encoder +* Trans for pointing out $DEBUG dependencies +* Flameeyes for finding that Term::ANSIColor was obsolete +* matz and all Ruby gods and gurus +* The inventors of: the computer, the internet, the true color display, HTML & + CSS, VIM, Ruby, pizza, microwaves, guitars, scouting, programming, anime, + manga, coke and green ice tea. + +Where would we be without all those people? + +=== Created using + +* Ruby[http://ruby-lang.org/] +* Chihiro (my Sony VAIO laptop); Henrietta (my old MacBook); + Triella, born Rico (my new MacBook); as well as + Seras and Hikari (my PCs) +* RDE[http://homepage2.nifty.com/sakazuki/rde_e.html], + VIM[http://vim.org] and TextMate[http://macromates.com] +* Subversion[http://subversion.tigris.org/] +* Redmine[http://redmine.org/] +* Firefox[http://www.mozilla.org/products/firefox/], + Firebug[http://getfirebug.com/], Safari[http://www.apple.com/safari/], and + Thunderbird[http://www.mozilla.org/products/thunderbird/] +* RubyGems[http://docs.rubygems.org/] and Rake[http://rake.rubyforge.org/] +* TortoiseSVN[http://tortoisesvn.tigris.org/] using Apache via + XAMPP[http://www.apachefriends.org/en/xampp.html] +* RDoc (though I'm quite unsatisfied with it) +* Microsoft Windows (yes, I confess!) and MacOS X +* GNUWin32, MinGW and some other tools to make the shell under windows a bit + less useless +* Term::ANSIColor[http://term-ansicolor.rubyforge.org/] +* PLEAC[http://pleac.sourceforge.net/] code examples +* Github +* Travis CI (http://travis-ci.org/rubychan/github) + +=== Free + +* As you can see, CodeRay was created under heavy use of *free* software. +* So CodeRay is also *free*. +* If you use CodeRay to create software, think about making this software + *free*, too. +* Thanks :) diff --git a/vendor/bundle/gems/coderay-1.1.0/Rakefile b/vendor/bundle/gems/coderay-1.1.0/Rakefile new file mode 100644 index 0000000..c9b1e8a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/Rakefile @@ -0,0 +1,37 @@ +require 'bundler/gem_tasks' + +$:.unshift File.dirname(__FILE__) unless $:.include? '.' + +ROOT = '.' +LIB_ROOT = File.join ROOT, 'lib' + +task :default => :test + +if File.directory? 'rake_tasks' + + # load rake tasks from subfolder + for task_file in Dir['rake_tasks/*.rake'].sort + load task_file + end + +else + + # fallback tasks when rake_tasks folder is not present (eg. in the distribution package) + desc 'Run CodeRay tests (basic)' + task :test do + ruby './test/functional/suite.rb' + ruby './test/functional/for_redcloth.rb' + end + + gem 'rdoc' if defined? gem + require 'rdoc/task' + desc 'Generate documentation for CodeRay' + Rake::RDocTask.new :doc do |rd| + rd.title = 'CodeRay Documentation' + rd.main = 'README_INDEX.rdoc' + rd.rdoc_files.add Dir['lib'] + rd.rdoc_files.add rd.main + rd.rdoc_dir = 'doc' + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/bin/coderay b/vendor/bundle/gems/coderay-1.1.0/bin/coderay new file mode 100755 index 0000000..889ae72 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/bin/coderay @@ -0,0 +1,215 @@ +#!/usr/bin/env ruby +require 'coderay' + +$options, args = ARGV.partition { |arg| arg[/^-[hv]$|--\w+/] } +subcommand = args.first if /^\w/ === args.first +subcommand = nil if subcommand && File.exist?(subcommand) +args.delete subcommand + +def option? *options + !($options & options).empty? +end + +def tty? + $stdout.tty? || option?('--tty') +end + +def version + puts <<-USAGE +CodeRay #{CodeRay::VERSION} + USAGE +end + +def help + puts <<-HELP +This is CodeRay #{CodeRay::VERSION}, a syntax highlighting tool for selected languages. + +usage: + coderay [-language] [input] [-format] [output] + +defaults: + language detect from input file name or shebang; fall back to plain text + input STDIN + format detect from output file name or use terminal; fall back to HTML + output STDOUT + +common: + coderay file.rb # highlight file to terminal + coderay file.rb > file.html # highlight file to HTML page + coderay file.rb -div > file.html # highlight file to HTML snippet + +configure output: + coderay file.py output.json # output tokens as JSON + coderay file.py -loc # count lines of code in Python file + +configure input: + coderay -python file # specify the input language + coderay -ruby # take input from STDIN + +more: + coderay stylesheet [style] # print CSS stylesheet + HELP +end + +def commands + puts <<-COMMANDS + general: + highlight code highlighting (default command, optional) + stylesheet print the CSS stylesheet with the given name (aliases: style, css) + + about: + list [of] list all available plugins (or just the scanners|encoders|styles|filetypes) + commands print this list + help show some help + version print CodeRay version + COMMANDS +end + +def print_list_of plugin_host + plugins = plugin_host.all_plugins.map do |plugin| + info = " #{plugin.plugin_id}: #{plugin.title}" + + aliases = (plugin.aliases - [:default]).map { |key| "-#{key}" }.sort_by { |key| key.size } + if plugin.respond_to?(:file_extension) || !aliases.empty? + additional_info = [] + additional_info << aliases.join(', ') unless aliases.empty? + info << " (#{additional_info.join('; ')})" + end + + info << ' <-- default' if plugin.aliases.include? :default + + info + end + puts plugins.sort +end + +if option? '-v', '--version' + version +end + +if option? '-h', '--help' + help +end + +case subcommand +when 'highlight', nil + if ARGV.empty? + version + help + else + signature = args.map { |arg| arg[/^-/] ? '-' : 'f' }.join + names = args.map { |arg| arg.sub(/^-/, '') } + case signature + when /^$/ + exit + when /^ff?$/ + input_file, output_file, = *names + when /^f-f?$/ + input_file, output_format, output_file, = *names + when /^-ff?$/ + input_lang, input_file, output_file, = *names + when /^-f-f?$/ + input_lang, input_file, output_format, output_file, = *names + when /^--?f?$/ + input_lang, output_format, output_file, = *names + else + $stdout = $stderr + help + puts + puts "Unknown parameter order: #{args.join ' '}, expected: [-language] [input] [-format] [output]" + exit 1 + end + + if input_file + input_lang ||= CodeRay::FileType.fetch input_file, :text, true + end + + if output_file + output_format ||= CodeRay::FileType[output_file] || :plain + else + output_format ||= :terminal + end + + output_format = :page if output_format.to_s == 'html' + + if input_file + input = File.read input_file + else + input = $stdin.read + end + + begin + file = + if output_file + File.open output_file, 'w' + else + $stdout + end + CodeRay.encode(input, input_lang, output_format, :out => file) + file.puts + rescue CodeRay::PluginHost::PluginNotFound => boom + $stdout = $stderr + if boom.message[/CodeRay::(\w+)s could not load plugin :?(.*?): /] + puts "I don't know the #$1 \"#$2\"." + else + puts boom.message + end + # puts "I don't know this plugin: #{boom.message[/Could not load plugin (.*?): /, 1]}." + rescue CodeRay::Scanners::Scanner::ScanError + # this is sometimes raised by pagers; ignore + # FIXME: rescue Errno::EPIPE + ensure + file.close if output_file + end + end +when 'li', 'list' + arg = args.first && args.first.downcase + if [nil, 's', 'sc', 'scanner', 'scanners'].include? arg + puts 'input languages (Scanners):' + print_list_of CodeRay::Scanners + end + + if [nil, 'e', 'en', 'enc', 'encoder', 'encoders'].include? arg + puts 'output formats (Encoders):' + print_list_of CodeRay::Encoders + end + + if [nil, 'st', 'style', 'styles'].include? arg + puts 'CSS themes for HTML output (Styles):' + print_list_of CodeRay::Styles + end + + if [nil, 'f', 'ft', 'file', 'filetype', 'filetypes'].include? arg + puts 'recognized file types:' + + filetypes = Hash.new { |h, k| h[k] = [] } + CodeRay::FileType::TypeFromExt.inject filetypes do |types, (ext, type)| + types[type.to_s] << ".#{ext}" + types + end + CodeRay::FileType::TypeFromName.inject filetypes do |types, (name, type)| + types[type.to_s] << name + types + end + + filetypes.sort.each do |type, exts| + puts " #{type}: #{exts.sort_by { |ext| ext.size }.join(', ')}" + end + end +when 'stylesheet', 'style', 'css' + puts CodeRay::Encoders[:html]::CSS.new(args.first || :default).stylesheet +when 'commands' + commands +when 'help' + help +else + $stdout = $stderr + help + puts + if subcommand[/\A\w+\z/] + puts "Unknown command: #{subcommand}" + else + puts "File not found: #{subcommand}" + end + exit 1 +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay.rb new file mode 100644 index 0000000..f759ed6 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay.rb @@ -0,0 +1,284 @@ +# encoding: utf-8 +# Encoding.default_internal = 'UTF-8' + +# = CodeRay Library +# +# CodeRay is a Ruby library for syntax highlighting. +# +# I try to make CodeRay easy to use and intuitive, but at the same time fully +# featured, complete, fast and efficient. +# +# See README. +# +# It consists mainly of +# * the main engine: CodeRay (Scanners::Scanner, Tokens, Encoders::Encoder) +# * the plugin system: PluginHost, Plugin +# * the scanners in CodeRay::Scanners +# * the encoders in CodeRay::Encoders +# * the styles in CodeRay::Styles +# +# Here's a fancy graphic to light up this gray docu: +# +# http://cycnus.de/raindark/coderay/scheme.png +# +# == Documentation +# +# See CodeRay, Encoders, Scanners, Tokens. +# +# == Usage +# +# Remember you need RubyGems to use CodeRay, unless you have it in your load +# path. Run Ruby with -rubygems option if required. +# +# === Highlight Ruby code in a string as html +# +# require 'coderay' +# print CodeRay.scan('puts "Hello, world!"', :ruby).html +# +# # prints something like this: +# puts "Hello, world!" +# +# +# === Highlight C code from a file in a html div +# +# require 'coderay' +# print CodeRay.scan(File.read('ruby.h'), :c).div +# print CodeRay.scan_file('ruby.h').html.div +# +# You can include this div in your page. The used CSS styles can be printed with +# +# % coderay_stylesheet +# +# === Highlight without typing too much +# +# If you are one of the hasty (or lazy, or extremely curious) people, just run this file: +# +# % ruby -rubygems /path/to/coderay/coderay.rb > example.html +# +# and look at the file it created in your browser. +# +# = CodeRay Module +# +# The CodeRay module provides convenience methods for the engine. +# +# * The +lang+ and +format+ arguments select Scanner and Encoder to use. These are +# simply lower-case symbols, like :python or :html. +# * All methods take an optional hash as last parameter, +options+, that is send to +# the Encoder / Scanner. +# * Input and language are always sorted in this order: +code+, +lang+. +# (This is in alphabetical order, if you need a mnemonic ;) +# +# You should be able to highlight everything you want just using these methods; +# so there is no need to dive into CodeRay's deep class hierarchy. +# +# The examples in the demo directory demonstrate common cases using this interface. +# +# = Basic Access Ways +# +# Read this to get a general view what CodeRay provides. +# +# == Scanning +# +# Scanning means analysing an input string, splitting it up into Tokens. +# Each Token knows about what type it is: string, comment, class name, etc. +# +# Each +lang+ (language) has its own Scanner; for example, :ruby code is +# handled by CodeRay::Scanners::Ruby. +# +# CodeRay.scan:: Scan a string in a given language into Tokens. +# This is the most common method to use. +# CodeRay.scan_file:: Scan a file and guess the language using FileType. +# +# The Tokens object you get from these methods can encode itself; see Tokens. +# +# == Encoding +# +# Encoding means compiling Tokens into an output. This can be colored HTML or +# LaTeX, a textual statistic or just the number of non-whitespace tokens. +# +# Each Encoder provides output in a specific +format+, so you select Encoders via +# formats like :html or :statistic. +# +# CodeRay.encode:: Scan and encode a string in a given language. +# CodeRay.encode_tokens:: Encode the given tokens. +# CodeRay.encode_file:: Scan a file, guess the language using FileType and encode it. +# +# == All-in-One Encoding +# +# CodeRay.encode:: Highlight a string with a given input and output format. +# +# == Instanciating +# +# You can use an Encoder instance to highlight multiple inputs. This way, the setup +# for this Encoder must only be done once. +# +# CodeRay.encoder:: Create an Encoder instance with format and options. +# CodeRay.scanner:: Create an Scanner instance for lang, with '' as default code. +# +# To make use of CodeRay.scanner, use CodeRay::Scanner::code=. +# +# The scanning methods provide more flexibility; we recommend to use these. +# +# == Reusing Scanners and Encoders +# +# If you want to re-use scanners and encoders (because that is faster), see +# CodeRay::Duo for the most convenient (and recommended) interface. +module CodeRay + + $CODERAY_DEBUG ||= false + + CODERAY_PATH = File.expand_path('../coderay', __FILE__) + + # Assuming the path is a subpath of lib/coderay/ + def self.coderay_path *path + File.join CODERAY_PATH, *path + end + + require 'coderay/version' + + # helpers + autoload :FileType, coderay_path('helpers', 'file_type') + + # Tokens + autoload :Tokens, coderay_path('tokens') + autoload :TokensProxy, coderay_path('tokens_proxy') + autoload :TokenKinds, coderay_path('token_kinds') + + # Plugin system + autoload :PluginHost, coderay_path('helpers', 'plugin') + autoload :Plugin, coderay_path('helpers', 'plugin') + + # Plugins + autoload :Scanners, coderay_path('scanner') + autoload :Encoders, coderay_path('encoder') + autoload :Styles, coderay_path('style') + + # convenience access and reusable Encoder/Scanner pair + autoload :Duo, coderay_path('duo') + + class << self + + # Scans the given +code+ (a String) with the Scanner for +lang+. + # + # This is a simple way to use CodeRay. Example: + # require 'coderay' + # page = CodeRay.scan("puts 'Hello, world!'", :ruby).html + # + # See also demo/demo_simple. + def scan code, lang, options = {}, &block + TokensProxy.new code, lang, options, block + end + + # Scans +filename+ (a path to a code file) with the Scanner for +lang+. + # + # If +lang+ is :auto or omitted, the CodeRay::FileType module is used to + # determine it. If it cannot find out what type it is, it uses + # CodeRay::Scanners::Text. + # + # Calls CodeRay.scan. + # + # Example: + # require 'coderay' + # page = CodeRay.scan_file('some_c_code.c').html + def scan_file filename, lang = :auto, options = {}, &block + lang = FileType.fetch filename, :text, true if lang == :auto + code = File.read filename + scan code, lang, options, &block + end + + # Encode a string. + # + # This scans +code+ with the the Scanner for +lang+ and then + # encodes it with the Encoder for +format+. + # +options+ will be passed to the Encoder. + # + # See CodeRay::Encoder.encode. + def encode code, lang, format, options = {} + encoder(format, options).encode code, lang, options + end + + # Encode pre-scanned Tokens. + # Use this together with CodeRay.scan: + # + # require 'coderay' + # + # # Highlight a short Ruby code example in a HTML span + # tokens = CodeRay.scan '1 + 2', :ruby + # puts CodeRay.encode_tokens(tokens, :span) + # + def encode_tokens tokens, format, options = {} + encoder(format, options).encode_tokens tokens, options + end + + # Encodes +filename+ (a path to a code file) with the Scanner for +lang+. + # + # See CodeRay.scan_file. + # Notice that the second argument is the output +format+, not the input language. + # + # Example: + # require 'coderay' + # page = CodeRay.encode_file 'some_c_code.c', :html + def encode_file filename, format, options = {} + tokens = scan_file filename, :auto, get_scanner_options(options) + encode_tokens tokens, format, options + end + + # Highlight a string into a HTML
. + # + # CSS styles use classes, so you have to include a stylesheet + # in your output. + # + # See encode. + def highlight code, lang, options = { :css => :class }, format = :div + encode code, lang, format, options + end + + # Highlight a file into a HTML
. + # + # CSS styles use classes, so you have to include a stylesheet + # in your output. + # + # See encode. + def highlight_file filename, options = { :css => :class }, format = :div + encode_file filename, format, options + end + + # Finds the Encoder class for +format+ and creates an instance, passing + # +options+ to it. + # + # Example: + # require 'coderay' + # + # stats = CodeRay.encoder(:statistic) + # stats.encode("puts 17 + 4\n", :ruby) + # + # puts '%d out of %d tokens have the kind :integer.' % [ + # stats.type_stats[:integer].count, + # stats.real_token_count + # ] + # #-> 2 out of 4 tokens have the kind :integer. + def encoder format, options = {} + Encoders[format].new options + end + + # Finds the Scanner class for +lang+ and creates an instance, passing + # +options+ to it. + # + # See Scanner.new. + def scanner lang, options = {}, &block + Scanners[lang].new '', options, &block + end + + # Extract the options for the scanner from the +options+ hash. + # + # Returns an empty Hash if :scanner_options is not set. + # + # This is used if a method like CodeRay.encode has to provide options + # for Encoder _and_ scanner. + def get_scanner_options options + options.fetch :scanner_options, {} + end + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/duo.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/duo.rb new file mode 100644 index 0000000..cb3f8ee --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/duo.rb @@ -0,0 +1,81 @@ +module CodeRay + + # = Duo + # + # A Duo is a convenient way to use CodeRay. You just create a Duo, + # giving it a lang (language of the input code) and a format (desired + # output format), and call Duo#highlight with the code. + # + # Duo makes it easy to re-use both scanner and encoder for a repetitive + # task. It also provides a very easy interface syntax: + # + # require 'coderay' + # CodeRay::Duo[:python, :div].highlight 'import this' + # + # Until you want to do uncommon things with CodeRay, I recommend to use + # this method, since it takes care of everything. + class Duo + + attr_accessor :lang, :format, :options + + # Create a new Duo, holding a lang and a format to highlight code. + # + # simple: + # CodeRay::Duo[:ruby, :html].highlight 'bla 42' + # + # with options: + # CodeRay::Duo[:ruby, :html, :hint => :debug].highlight '????::??' + # + # alternative syntax without options: + # CodeRay::Duo[:ruby => :statistic].encode 'class << self; end' + # + # alternative syntax with options: + # CodeRay::Duo[{ :ruby => :statistic }, :do => :something].encode 'abc' + # + # The options are forwarded to scanner and encoder + # (see CodeRay.get_scanner_options). + def initialize lang = nil, format = nil, options = {} + if format.nil? && lang.is_a?(Hash) && lang.size == 1 + @lang = lang.keys.first + @format = lang[@lang] + else + @lang = lang + @format = format + end + @options = options + end + + class << self + # To allow calls like Duo[:ruby, :html].highlight. + alias [] new + end + + # The scanner of the duo. Only created once. + def scanner + @scanner ||= CodeRay.scanner @lang, CodeRay.get_scanner_options(@options) + end + + # The encoder of the duo. Only created once. + def encoder + @encoder ||= CodeRay.encoder @format, @options + end + + # Tokenize and highlight the code using +scanner+ and +encoder+. + def encode code, options = {} + options = @options.merge options + encoder.encode(code, @lang, options) + end + alias highlight encode + + # Allows to use Duo like a proc object: + # + # CodeRay::Duo[:python => :yaml].call(code) + # + # or, in Ruby 1.9 and later: + # + # CodeRay::Duo[:python => :yaml].(code) + alias call encode + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoder.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoder.rb new file mode 100644 index 0000000..d2d6c7e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoder.rb @@ -0,0 +1,201 @@ +module CodeRay + + # This module holds the Encoder class and its subclasses. + # For example, the HTML encoder is named CodeRay::Encoders::HTML + # can be found in coderay/encoders/html. + # + # Encoders also provides methods and constants for the register + # mechanism and the [] method that returns the Encoder class + # belonging to the given format. + module Encoders + + extend PluginHost + plugin_path File.dirname(__FILE__), 'encoders' + + # = Encoder + # + # The Encoder base class. Together with Scanner and + # Tokens, it forms the highlighting triad. + # + # Encoder instances take a Tokens object and do something with it. + # + # The most common Encoder is surely the HTML encoder + # (CodeRay::Encoders::HTML). It highlights the code in a colorful + # html page. + # If you want the highlighted code in a div or a span instead, + # use its subclasses Div and Span. + class Encoder + extend Plugin + plugin_host Encoders + + class << self + + # If FILE_EXTENSION isn't defined, this method returns the + # downcase class name instead. + def const_missing sym + if sym == :FILE_EXTENSION + (defined?(@plugin_id) && @plugin_id || name[/\w+$/].downcase).to_s + else + super + end + end + + # The default file extension for output file of this encoder class. + def file_extension + self::FILE_EXTENSION + end + + end + + # Subclasses are to store their default options in this constant. + DEFAULT_OPTIONS = { } + + # The options you gave the Encoder at creating. + attr_accessor :options, :scanner + + # Creates a new Encoder. + # +options+ is saved and used for all encode operations, as long + # as you don't overwrite it there by passing additional options. + # + # Encoder objects provide three encode methods: + # - encode simply takes a +code+ string and a +lang+ + # - encode_tokens expects a +tokens+ object instead + # + # Each method has an optional +options+ parameter. These are + # added to the options you passed at creation. + def initialize options = {} + @options = self.class::DEFAULT_OPTIONS.merge options + @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN = false + end + + # Encode a Tokens object. + def encode_tokens tokens, options = {} + options = @options.merge options + @scanner = tokens.scanner if tokens.respond_to? :scanner + setup options + compile tokens, options + finish options + end + + # Encode the given +code+ using the Scanner for +lang+. + def encode code, lang, options = {} + options = @options.merge options + @scanner = Scanners[lang].new code, CodeRay.get_scanner_options(options).update(:tokens => self) + setup options + @scanner.tokenize + finish options + end + + # You can use highlight instead of encode, if that seems + # more clear to you. + alias highlight encode + + # The default file extension for this encoder. + def file_extension + self.class.file_extension + end + + def << token + unless @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN + warn 'Using old Tokens#<< interface.' + @@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN = true + end + self.token(*token) + end + + # Called with +content+ and +kind+ of the currently scanned token. + # For simple scanners, it's enougth to implement this method. + # + # By default, it calls text_token, begin_group, end_group, begin_line, + # or end_line, depending on the +content+. + def token content, kind + case content + when String + text_token content, kind + when :begin_group + begin_group kind + when :end_group + end_group kind + when :begin_line + begin_line kind + when :end_line + end_line kind + else + raise ArgumentError, 'Unknown token content type: %p, kind = %p' % [content, kind] + end + end + + # Called for each text token ([text, kind]), where text is a String. + def text_token text, kind + @out << text + end + + # Starts a token group with the given +kind+. + def begin_group kind + end + + # Ends a token group with the given +kind+. + def end_group kind + end + + # Starts a new line token group with the given +kind+. + def begin_line kind + end + + # Ends a new line token group with the given +kind+. + def end_line kind + end + + protected + + # Called with merged options before encoding starts. + # Sets @out to an empty string. + # + # See the HTML Encoder for an example of option caching. + def setup options + @out = get_output(options) + end + + def get_output options + options[:out] || '' + end + + # Append data.to_s to the output. Returns the argument. + def output data + @out << data.to_s + data + end + + # Called with merged options after encoding starts. + # The return value is the result of encoding, typically @out. + def finish options + @out + end + + # Do the encoding. + # + # The already created +tokens+ object must be used; it must be a + # Tokens object. + def compile tokens, options = {} + content = nil + for item in tokens + if item.is_a? Array + raise ArgumentError, 'Two-element array tokens are no longer supported.' + end + if content + token content, item + content = nil + else + content = item + end + end + raise 'odd number list for Tokens' if content + end + + alias tokens compile + public :tokens + + end + + end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/_map.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/_map.rb new file mode 100644 index 0000000..4cca196 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/_map.rb @@ -0,0 +1,17 @@ +module CodeRay +module Encoders + + map \ + :loc => :lines_of_code, + :plain => :text, + :plaintext => :text, + :remove_comments => :comment_filter, + :stats => :statistic, + :term => :terminal, + :tty => :terminal, + :yml => :yaml + + # No default because Tokens#nonsense should raise NoMethodError. + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/comment_filter.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/comment_filter.rb new file mode 100644 index 0000000..28336b3 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/comment_filter.rb @@ -0,0 +1,25 @@ +module CodeRay +module Encoders + + load :token_kind_filter + + # A simple Filter that removes all tokens of the :comment kind. + # + # Alias: +remove_comments+ + # + # Usage: + # CodeRay.scan('print # foo', :ruby).comment_filter.text + # #-> "print " + # + # See also: TokenKindFilter, LinesOfCode + class CommentFilter < TokenKindFilter + + register_for :comment_filter + + DEFAULT_OPTIONS = superclass::DEFAULT_OPTIONS.merge \ + :exclude => [:comment, :docstring] + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/count.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/count.rb new file mode 100644 index 0000000..98a427e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/count.rb @@ -0,0 +1,39 @@ +module CodeRay +module Encoders + + # Returns the number of tokens. + # + # Text and block tokens are counted. + class Count < Encoder + + register_for :count + + protected + + def setup options + super + + @count = 0 + end + + def finish options + output @count + end + + public + + def text_token text, kind + @count += 1 + end + + def begin_group kind + @count += 1 + end + alias end_group begin_group + alias begin_line begin_group + alias end_line begin_group + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug.rb new file mode 100644 index 0000000..f4db330 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug.rb @@ -0,0 +1,49 @@ +module CodeRay +module Encoders + + # = Debug Encoder + # + # Fast encoder producing simple debug output. + # + # It is readable and diff-able and is used for testing. + # + # You cannot fully restore the tokens information from the + # output, because consecutive :space tokens are merged. + # + # See also: Scanners::Debug + class Debug < Encoder + + register_for :debug + + FILE_EXTENSION = 'raydebug' + + def text_token text, kind + if kind == :space + @out << text + else + text = text.gsub('\\', '\\\\\\\\') if text.index('\\') + text = text.gsub(')', '\\\\)') if text.index(')') + @out << "#{kind}(#{text})" + end + end + + def begin_group kind + @out << "#{kind}<" + end + + def end_group kind + @out << '>' + end + + def begin_line kind + @out << "#{kind}[" + end + + def end_line kind + @out << ']' + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug_lint.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug_lint.rb new file mode 100644 index 0000000..a4eba2c --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/debug_lint.rb @@ -0,0 +1,63 @@ +module CodeRay +module Encoders + + load :lint + + # = Debug Lint Encoder + # + # Debug encoder with additional checks for: + # + # - empty tokens + # - incorrect nesting + # + # It will raise an InvalidTokenStream exception when any of the above occurs. + # + # See also: Encoders::Debug + class DebugLint < Debug + + register_for :debug_lint + + def text_token text, kind + raise Lint::EmptyToken, 'empty token for %p' % [kind] if text.empty? + raise Lint::UnknownTokenKind, 'unknown token kind %p (text was %p)' % [kind, text] unless TokenKinds.has_key? kind + super + end + + def begin_group kind + @opened << kind + super + end + + def end_group kind + raise Lint::IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_group)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind + @opened.pop + super + end + + def begin_line kind + @opened << kind + super + end + + def end_line kind + raise Lint::IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_line)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind + @opened.pop + super + end + + protected + + def setup options + super + @opened = [] + end + + def finish options + raise 'Some tokens still open at end of token stream: %p' % [@opened] unless @opened.empty? + super + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/div.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/div.rb new file mode 100644 index 0000000..efd9435 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/div.rb @@ -0,0 +1,23 @@ +module CodeRay +module Encoders + + load :html + + # Wraps HTML output into a DIV element, using inline styles by default. + # + # See Encoders::HTML for available options. + class Div < HTML + + FILE_EXTENSION = 'div.html' + + register_for :div + + DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \ + :css => :style, + :wrap => :div, + :line_numbers => false + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/filter.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/filter.rb new file mode 100644 index 0000000..e7f34d6 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/filter.rb @@ -0,0 +1,58 @@ +module CodeRay +module Encoders + + # A Filter encoder has another Tokens instance as output. + # It can be subclass to select, remove, or modify tokens in the stream. + # + # Subclasses of Filter are called "Filters" and can be chained. + # + # == Options + # + # === :tokens + # + # The Tokens object which will receive the output. + # + # Default: Tokens.new + # + # See also: TokenKindFilter + class Filter < Encoder + + register_for :filter + + protected + def setup options + super + + @tokens = options[:tokens] || Tokens.new + end + + def finish options + output @tokens + end + + public + + def text_token text, kind # :nodoc: + @tokens.text_token text, kind + end + + def begin_group kind # :nodoc: + @tokens.begin_group kind + end + + def begin_line kind # :nodoc: + @tokens.begin_line kind + end + + def end_group kind # :nodoc: + @tokens.end_group kind + end + + def end_line kind # :nodoc: + @tokens.end_line kind + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html.rb new file mode 100644 index 0000000..d2ebb5a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html.rb @@ -0,0 +1,332 @@ +require 'set' + +module CodeRay +module Encoders + + # = HTML Encoder + # + # This is CodeRay's most important highlighter: + # It provides save, fast XHTML generation and CSS support. + # + # == Usage + # + # require 'coderay' + # puts CodeRay.scan('Some /code/', :ruby).html #-> a HTML page + # puts CodeRay.scan('Some /code/', :ruby).html(:wrap => :span) + # #-> Some /code/ + # puts CodeRay.scan('Some /code/', :ruby).span #-> the same + # + # puts CodeRay.scan('Some code', :ruby).html( + # :wrap => nil, + # :line_numbers => :inline, + # :css => :style + # ) + # + # == Options + # + # === :tab_width + # Convert \t characters to +n+ spaces (a number.) + # + # Default: 8 + # + # === :css + # How to include the styles; can be :class or :style. + # + # Default: :class + # + # === :wrap + # Wrap in :page, :div, :span or nil. + # + # You can also use Encoders::Div and Encoders::Span. + # + # Default: nil + # + # === :title + # + # The title of the HTML page (works only when :wrap is set to :page.) + # + # Default: 'CodeRay output' + # + # === :break_lines + # + # Split multiline blocks at line breaks. + # Forced to true if :line_numbers option is set to :inline. + # + # Default: false + # + # === :line_numbers + # Include line numbers in :table, :inline, or nil (no line numbers) + # + # Default: nil + # + # === :line_number_anchors + # Adds anchors and links to the line numbers. Can be false (off), true (on), + # or a prefix string that will be prepended to the anchor name. + # + # The prefix must consist only of letters, digits, and underscores. + # + # Default: true, default prefix name: "line" + # + # === :line_number_start + # Where to start with line number counting. + # + # Default: 1 + # + # === :bold_every + # Make every +n+-th number appear bold. + # + # Default: 10 + # + # === :highlight_lines + # + # Highlights certain line numbers. + # Can be any Enumerable, typically just an Array or Range, of numbers. + # + # Bolding is deactivated when :highlight_lines is set. It only makes sense + # in combination with :line_numbers. + # + # Default: nil + # + # === :hint + # Include some information into the output using the title attribute. + # Can be :info (show token kind on mouse-over), :info_long (with full path) + # or :debug (via inspect). + # + # Default: false + class HTML < Encoder + + register_for :html + + FILE_EXTENSION = 'snippet.html' + + DEFAULT_OPTIONS = { + :tab_width => 8, + + :css => :class, + :style => :alpha, + :wrap => nil, + :title => 'CodeRay output', + + :break_lines => false, + + :line_numbers => nil, + :line_number_anchors => 'n', + :line_number_start => 1, + :bold_every => 10, + :highlight_lines => nil, + + :hint => false, + } + + autoload :Output, CodeRay.coderay_path('encoders', 'html', 'output') + autoload :CSS, CodeRay.coderay_path('encoders', 'html', 'css') + autoload :Numbering, CodeRay.coderay_path('encoders', 'html', 'numbering') + + attr_reader :css + + protected + + def self.make_html_escape_hash + { + '&' => '&', + '"' => '"', + '>' => '>', + '<' => '<', + # "\t" => will be set to ' ' * options[:tab_width] during setup + }.tap do |hash| + # Escape ASCII control codes except \x9 == \t and \xA == \n. + (Array(0x00..0x8) + Array(0xB..0x1F)).each { |invalid| hash[invalid.chr] = ' ' } + end + end + + HTML_ESCAPE = make_html_escape_hash + HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1F]/ + + TOKEN_KIND_TO_INFO = Hash.new do |h, kind| + h[kind] = kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize } + end + + TRANSPARENT_TOKEN_KINDS = Set[ + :delimiter, :modifier, :content, :escape, :inline_delimiter, + ] + + # Generate a hint about the given +kinds+ in a +hint+ style. + # + # +hint+ may be :info, :info_long or :debug. + def self.token_path_to_hint hint, kinds + kinds = Array kinds + title = + case hint + when :info + kinds = kinds[1..-1] if TRANSPARENT_TOKEN_KINDS.include? kinds.first + TOKEN_KIND_TO_INFO[kinds.first] + when :info_long + kinds.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/') + when :debug + kinds.inspect + end + title ? " title=\"#{title}\"" : '' + end + + def setup options + super + + check_options! options + + if options[:wrap] || options[:line_numbers] + @real_out = @out + @out = '' + end + + @break_lines = (options[:break_lines] == true) + + @HTML_ESCAPE = HTML_ESCAPE.merge("\t" => ' ' * options[:tab_width]) + + @opened = [] + @last_opened = nil + @css = CSS.new options[:style] + + @span_for_kinds = make_span_for_kinds(options[:css], options[:hint]) + + @set_last_opened = options[:hint] || options[:css] == :style + end + + def finish options + unless @opened.empty? + @out << '' while @opened.pop + @last_opened = nil + end + + if @out.respond_to? :to_str + @out.extend Output + @out.css = @css + if options[:line_numbers] + Numbering.number! @out, options[:line_numbers], options + end + @out.wrap! options[:wrap] + @out.apply_title! options[:title] + end + + if defined?(@real_out) && @real_out + @real_out << @out + @out = @real_out + end + + super + end + + public + + def text_token text, kind + style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind] + + text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] } if text =~ /#{HTML_ESCAPE_PATTERN}/o + text = break_lines(text, style) if @break_lines && (style || @opened.size > 0) && text.index("\n") + + if style + @out << style << text << '' + else + @out << text + end + end + + # token groups, eg. strings + def begin_group kind + @out << (@span_for_kinds[@last_opened ? [kind, *@opened] : kind] || '') + @opened << kind + @last_opened = kind if @set_last_opened + end + + def end_group kind + check_group_nesting 'token group', kind if $CODERAY_DEBUG + close_span + end + + # whole lines to be highlighted, eg. a deleted line in a diff + def begin_line kind + if style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind] + if style['class="'] + @out << style.sub('class="', 'class="line ') + else + @out << style.sub('>', ' class="line">') + end + else + @out << '' + end + @opened << kind + @last_opened = kind if @options[:css] == :style + end + + def end_line kind + check_group_nesting 'line', kind if $CODERAY_DEBUG + close_span + end + + protected + + def check_options! options + unless [false, nil, :debug, :info, :info_long].include? options[:hint] + raise ArgumentError, "Unknown value %p for :hint; expected :info, :info_long, :debug, false, or nil." % [options[:hint]] + end + + unless [:class, :style].include? options[:css] + raise ArgumentError, 'Unknown value %p for :css.' % [options[:css]] + end + + options[:break_lines] = true if options[:line_numbers] == :inline + end + + def css_class_for_kinds kinds + TokenKinds[kinds.is_a?(Symbol) ? kinds : kinds.first] + end + + def style_for_kinds kinds + css_classes = kinds.is_a?(Array) ? kinds.map { |c| TokenKinds[c] } : [TokenKinds[kinds]] + @css.get_style_for_css_classes css_classes + end + + def make_span_for_kinds method, hint + Hash.new do |h, kinds| + begin + css_class = css_class_for_kinds(kinds) + title = HTML.token_path_to_hint hint, kinds if hint + + if css_class || title + if method == :style + style = style_for_kinds(kinds) + "" + else + "" + end + end + end.tap do |span| + h.clear if h.size >= 100 + h[kinds] = span + end + end + end + + def check_group_nesting name, kind + if @opened.empty? || @opened.last != kind + warn "Malformed token stream: Trying to close a #{name} (%p) that is not open. Open are: %p." % [kind, @opened[1..-1]] + end + end + + def break_lines text, style + reopen = '' + @opened.each_with_index do |kind, index| + reopen << (@span_for_kinds[index > 0 ? [kind, *@opened[0...index]] : kind] || '') + end + text.gsub("\n", "#{'' * @opened.size}#{'' if style}\n#{reopen}#{style}") + end + + def close_span + if @opened.pop + @out << '' + @last_opened = @opened.last if @last_opened + end + end + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/css.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/css.rb new file mode 100644 index 0000000..164d7f8 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/css.rb @@ -0,0 +1,65 @@ +module CodeRay +module Encoders + + class HTML + class CSS # :nodoc: + + attr :stylesheet + + def CSS.load_stylesheet style = nil + CodeRay::Styles[style] + end + + def initialize style = :default + @styles = Hash.new + style = CSS.load_stylesheet style + @stylesheet = [ + style::CSS_MAIN_STYLES, + style::TOKEN_COLORS.gsub(/^(?!$)/, '.CodeRay ') + ].join("\n") + parse style::TOKEN_COLORS + end + + def get_style_for_css_classes css_classes + cl = @styles[css_classes.first] + return '' unless cl + style = '' + 1.upto css_classes.size do |offset| + break if style = cl[css_classes[offset .. -1]] + end + # warn 'Style not found: %p' % [styles] if style.empty? + return style + end + + private + + CSS_CLASS_PATTERN = / + ( # $1 = selectors + (?: + (?: \s* \. [-\w]+ )+ + \s* ,? + )+ + ) + \s* \{ \s* + ( [^\}]+ )? # $2 = style + \s* \} \s* + | + ( [^\n]+ ) # $3 = error + /mx + def parse stylesheet + stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error| + raise "CSS parse error: '#{error.inspect}' not recognized" if error + for selector in selectors.split(',') + classes = selector.scan(/[-\w]+/) + cl = classes.pop + @styles[cl] ||= Hash.new + @styles[cl][classes] = style.to_s.strip.delete(' ').chomp(';') + end + end + end + + end + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/numbering.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/numbering.rb new file mode 100644 index 0000000..a1b9c04 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/numbering.rb @@ -0,0 +1,108 @@ +module CodeRay +module Encoders + + class HTML + + module Numbering # :nodoc: + + def self.number! output, mode = :table, options = {} + return self unless mode + + options = DEFAULT_OPTIONS.merge options + + start = options[:line_number_start] + unless start.is_a? Integer + raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start + end + + anchor_prefix = options[:line_number_anchors] + anchor_prefix = 'line' if anchor_prefix == true + anchor_prefix = anchor_prefix.to_s[/[\w-]+/] if anchor_prefix + anchoring = + if anchor_prefix + proc do |line| + line = line.to_s + anchor = anchor_prefix + line + "#{line}" + end + else + :to_s.to_proc + end + + bold_every = options[:bold_every] + highlight_lines = options[:highlight_lines] + bolding = + if bold_every == false && highlight_lines == nil + anchoring + elsif highlight_lines.is_a? Enumerable + highlight_lines = highlight_lines.to_set + proc do |line| + if highlight_lines.include? line + "#{anchoring[line]}" # highlighted line numbers in bold + else + anchoring[line] + end + end + elsif bold_every.is_a? Integer + raise ArgumentError, ":bolding can't be 0." if bold_every == 0 + proc do |line| + if line % bold_every == 0 + "#{anchoring[line]}" # every bold_every-th number in bold + else + anchoring[line] + end + end + else + raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every + end + + if position_of_last_newline = output.rindex(RUBY_VERSION >= '1.9' ? /\n/ : ?\n) + after_last_newline = output[position_of_last_newline + 1 .. -1] + ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/] + + if ends_with_newline + line_count = output.count("\n") + else + line_count = output.count("\n") + 1 + end + else + line_count = 1 + end + + case mode + when :inline + max_width = (start + line_count).to_s.size + line_number = start + output.gsub!(/^.*$\n?/) do |line| + line_number_text = bolding.call line_number + indent = ' ' * (max_width - line_number.to_s.size) + line_number += 1 + "#{indent}#{line_number_text}#{line}" + end + + when :table + line_numbers = (start ... start + line_count).map(&bolding).join("\n") + line_numbers << "\n" + line_numbers_table_template = Output::TABLE.apply('LINE_NUMBERS', line_numbers) + + output.gsub!(/<\/div>\n/, '
') + output.wrap_in! line_numbers_table_template + output.wrapped_in = :div + + when :list + raise NotImplementedError, 'The :list option is no longer available. Use :table.' + + else + raise ArgumentError, 'Unknown value %p for mode: expected one of %p' % + [mode, [:table, :inline]] + end + + output + end + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/output.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/output.rb new file mode 100644 index 0000000..de6f6ea --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/html/output.rb @@ -0,0 +1,166 @@ +module CodeRay +module Encoders + + class HTML + + # This module is included in the output String of the HTML Encoder. + # + # It provides methods like wrap, div, page etc. + # + # Remember to use #clone instead of #dup to keep the modules the object was + # extended with. + # + # TODO: Rewrite this without monkey patching. + module Output + + attr_accessor :css + + class << self + + # Raises an exception if an object that doesn't respond to to_str is extended by Output, + # to prevent users from misuse. Use Module#remove_method to disable. + def extended o # :nodoc: + warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str + end + + def make_stylesheet css, in_tag = false # :nodoc: + sheet = css.stylesheet + sheet = <<-'CSS' if in_tag + + CSS + sheet + end + + def page_template_for_css css # :nodoc: + sheet = make_stylesheet css + PAGE.apply 'CSS', sheet + end + + end + + def wrapped_in? element + wrapped_in == element + end + + def wrapped_in + @wrapped_in ||= nil + end + attr_writer :wrapped_in + + def wrap_in! template + Template.wrap! self, template, 'CONTENT' + self + end + + def apply_title! title + self.sub!(/()(<\/title>)/) { $1 + title + $2 } + self + end + + def wrap! element, *args + return self if not element or element == wrapped_in + case element + when :div + raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil + wrap_in! DIV + when :span + raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? nil + wrap_in! SPAN + when :page + wrap! :div if wrapped_in? nil + raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div + wrap_in! Output.page_template_for_css(@css) + if args.first.is_a?(Hash) && title = args.first[:title] + apply_title! title + end + self + when nil + return self + else + raise "Unknown value %p for :wrap" % element + end + @wrapped_in = element + self + end + + def stylesheet in_tag = false + Output.make_stylesheet @css, in_tag + end + +#-- don't include the templates in docu + + class Template < String # :nodoc: + + def self.wrap! str, template, target + target = Regexp.new(Regexp.escape("<%#{target}%>")) + if template =~ target + str[0,0] = $` + str << $' + else + raise "Template target <%%%p%%> not found" % target + end + end + + def apply target, replacement + target = Regexp.new(Regexp.escape("<%#{target}%>")) + if self =~ target + Template.new($` + replacement + $') + else + raise "Template target <%%%p%%> not found" % target + end + end + + end + + SPAN = Template.new '<span class="CodeRay"><%CONTENT%></span>' + + DIV = Template.new <<-DIV +<div class="CodeRay"> + <div class="code"><pre><%CONTENT%></pre></div> +</div> + DIV + + TABLE = Template.new <<-TABLE +<table class="CodeRay"><tr> + <td class="line-numbers"><pre><%LINE_NUMBERS%></pre></td> + <td class="code"><pre><%CONTENT%></pre></td> +</tr></table> + TABLE + + PAGE = Template.new <<-PAGE +<!DOCTYPE html> +<html> +<head> + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <title> + + + + +<%CONTENT%> + + + PAGE + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/json.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/json.rb new file mode 100644 index 0000000..a9e40dc --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/json.rb @@ -0,0 +1,83 @@ +module CodeRay +module Encoders + + # A simple JSON Encoder. + # + # Example: + # CodeRay.scan('puts "Hello world!"', :ruby).json + # yields + # [ + # {"type"=>"text", "text"=>"puts", "kind"=>"ident"}, + # {"type"=>"text", "text"=>" ", "kind"=>"space"}, + # {"type"=>"block", "action"=>"open", "kind"=>"string"}, + # {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"}, + # {"type"=>"text", "text"=>"Hello world!", "kind"=>"content"}, + # {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"}, + # {"type"=>"block", "action"=>"close", "kind"=>"string"}, + # ] + class JSON < Encoder + + begin + require 'json' + rescue LoadError + begin + require 'rubygems' unless defined? Gem + gem 'json' + require 'json' + rescue LoadError + $stderr.puts "The JSON encoder needs the JSON library.\n" \ + "Please gem install json." + raise + end + end + + register_for :json + FILE_EXTENSION = 'json' + + protected + def setup options + super + + @first = true + @out << '[' + end + + def finish options + @out << ']' + end + + def append data + if @first + @first = false + else + @out << ',' + end + + @out << data.to_json + end + + public + def text_token text, kind + append :type => 'text', :text => text, :kind => kind + end + + def begin_group kind + append :type => 'block', :action => 'open', :kind => kind + end + + def end_group kind + append :type => 'block', :action => 'close', :kind => kind + end + + def begin_line kind + append :type => 'block', :action => 'begin_line', :kind => kind + end + + def end_line kind + append :type => 'block', :action => 'end_line', :kind => kind + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lines_of_code.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lines_of_code.rb new file mode 100644 index 0000000..5f8422f --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lines_of_code.rb @@ -0,0 +1,45 @@ +module CodeRay +module Encoders + + # Counts the LoC (Lines of Code). Returns an Integer >= 0. + # + # Alias: +loc+ + # + # Everything that is not comment, markup, doctype/shebang, or an empty line, + # is considered to be code. + # + # For example, + # * HTML files not containing JavaScript have 0 LoC + # * in a Java class without comments, LoC is the number of non-empty lines + # + # A Scanner class should define the token kinds that are not code in the + # KINDS_NOT_LOC constant, which defaults to [:comment, :doctype]. + class LinesOfCode < TokenKindFilter + + register_for :lines_of_code + + NON_EMPTY_LINE = /^\s*\S.*$/ + + protected + + def setup options + if scanner + kinds_not_loc = scanner.class::KINDS_NOT_LOC + else + warn "Tokens have no associated scanner, counting all nonempty lines." if $VERBOSE + kinds_not_loc = CodeRay::Scanners::Scanner::KINDS_NOT_LOC + end + + options[:exclude] = kinds_not_loc + + super options + end + + def finish options + output @tokens.text.scan(NON_EMPTY_LINE).size + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lint.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lint.rb new file mode 100644 index 0000000..88c8bd1 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/lint.rb @@ -0,0 +1,59 @@ +module CodeRay +module Encoders + + # = Lint Encoder + # + # Checks for: + # + # - empty tokens + # - incorrect nesting + # + # It will raise an InvalidTokenStream exception when any of the above occurs. + # + # See also: Encoders::DebugLint + class Lint < Debug + + register_for :lint + + InvalidTokenStream = Class.new StandardError + EmptyToken = Class.new InvalidTokenStream + UnknownTokenKind = Class.new InvalidTokenStream + IncorrectTokenGroupNesting = Class.new InvalidTokenStream + + def text_token text, kind + raise EmptyToken, 'empty token for %p' % [kind] if text.empty? + raise UnknownTokenKind, 'unknown token kind %p (text was %p)' % [kind, text] unless TokenKinds.has_key? kind + end + + def begin_group kind + @opened << kind + end + + def end_group kind + raise IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_group)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind + @opened.pop + end + + def begin_line kind + @opened << kind + end + + def end_line kind + raise IncorrectTokenGroupNesting, 'We are inside %s, not %p (end_line)' % [@opened.reverse.map(&:inspect).join(' < '), kind] if @opened.last != kind + @opened.pop + end + + protected + + def setup options + @opened = [] + end + + def finish options + raise 'Some tokens still open at end of token stream: %p' % [@opened] unless @opened.empty? + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/null.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/null.rb new file mode 100644 index 0000000..73ba47d --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/null.rb @@ -0,0 +1,18 @@ +module CodeRay +module Encoders + + # = Null Encoder + # + # Does nothing and returns an empty string. + class Null < Encoder + + register_for :null + + def text_token text, kind + # do nothing + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/page.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/page.rb new file mode 100644 index 0000000..800e73f --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/page.rb @@ -0,0 +1,24 @@ +module CodeRay +module Encoders + + load :html + + # Wraps the output into a HTML page, using CSS classes and + # line numbers in the table format by default. + # + # See Encoders::HTML for available options. + class Page < HTML + + FILE_EXTENSION = 'html' + + register_for :page + + DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \ + :css => :class, + :wrap => :page, + :line_numbers => :table + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/span.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/span.rb new file mode 100644 index 0000000..da705bd --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/span.rb @@ -0,0 +1,23 @@ +module CodeRay +module Encoders + + load :html + + # Wraps HTML output into a SPAN element, using inline styles by default. + # + # See Encoders::HTML for available options. + class Span < HTML + + FILE_EXTENSION = 'span.html' + + register_for :span + + DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \ + :css => :style, + :wrap => :span, + :line_numbers => false + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/statistic.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/statistic.rb new file mode 100644 index 0000000..b2f8b83 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/statistic.rb @@ -0,0 +1,95 @@ +module CodeRay +module Encoders + + # Makes a statistic for the given tokens. + # + # Alias: +stats+ + class Statistic < Encoder + + register_for :statistic + + attr_reader :type_stats, :real_token_count # :nodoc: + + TypeStats = Struct.new :count, :size # :nodoc: + + protected + + def setup options + super + + @type_stats = Hash.new { |h, k| h[k] = TypeStats.new 0, 0 } + @real_token_count = 0 + end + + STATS = <<-STATS # :nodoc: + +Code Statistics + +Tokens %8d + Non-Whitespace %8d +Bytes Total %8d + +Token Types (%d): + type count ratio size (average) +------------------------------------------------------------- +%s + STATS + + TOKEN_TYPES_ROW = <<-TKR # :nodoc: + %-20s %8d %6.2f %% %5.1f + TKR + + def finish options + all = @type_stats['TOTAL'] + all_count, all_size = all.count, all.size + @type_stats.each do |type, stat| + stat.size /= stat.count.to_f + end + types_stats = @type_stats.sort_by { |k, v| [-v.count, k.to_s] }.map do |k, v| + TOKEN_TYPES_ROW % [k, v.count, 100.0 * v.count / all_count, v.size] + end.join + @out << STATS % [ + all_count, @real_token_count, all_size, + @type_stats.delete_if { |k, v| k.is_a? String }.size, + types_stats + ] + + super + end + + public + + def text_token text, kind + @real_token_count += 1 unless kind == :space + @type_stats[kind].count += 1 + @type_stats[kind].size += text.size + @type_stats['TOTAL'].size += text.size + @type_stats['TOTAL'].count += 1 + end + + def begin_group kind + block_token ':begin_group', kind + end + + def end_group kind + block_token ':end_group', kind + end + + def begin_line kind + block_token ':begin_line', kind + end + + def end_line kind + block_token ':end_line', kind + end + + def block_token action, kind + @type_stats['TOTAL'].count += 1 + @type_stats[action].count += 1 + @type_stats[kind].count += 1 + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/terminal.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/terminal.rb new file mode 100644 index 0000000..c7ae014 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/terminal.rb @@ -0,0 +1,195 @@ +module CodeRay + module Encoders + + # Outputs code highlighted for a color terminal. + # + # Note: This encoder is in beta. It currently doesn't use the Styles. + # + # Alias: +term+ + # + # == Authors & License + # + # By Rob Aldred (http://robaldred.co.uk) + # + # Based on idea by Nathan Weizenbaum (http://nex-3.com) + # + # MIT License (http://www.opensource.org/licenses/mit-license.php) + class Terminal < Encoder + + register_for :terminal + + TOKEN_COLORS = { + :debug => "\e[1;37;44m", + + :annotation => "\e[34m", + :attribute_name => "\e[35m", + :attribute_value => "\e[31m", + :binary => { + :self => "\e[31m", + :char => "\e[1;31m", + :delimiter => "\e[1;31m", + }, + :char => { + :self => "\e[35m", + :delimiter => "\e[1;35m" + }, + :class => "\e[1;35;4m", + :class_variable => "\e[36m", + :color => "\e[32m", + :comment => { + :self => "\e[1;30m", + :char => "\e[37m", + :delimiter => "\e[37m", + }, + :constant => "\e[1;34;4m", + :decorator => "\e[35m", + :definition => "\e[1;33m", + :directive => "\e[33m", + :docstring => "\e[31m", + :doctype => "\e[1;34m", + :done => "\e[1;30;2m", + :entity => "\e[31m", + :error => "\e[1;37;41m", + :exception => "\e[1;31m", + :float => "\e[1;35m", + :function => "\e[1;34m", + :global_variable => "\e[1;32m", + :hex => "\e[1;36m", + :id => "\e[1;34m", + :include => "\e[31m", + :integer => "\e[1;34m", + :imaginary => "\e[1;34m", + :important => "\e[1;31m", + :key => { + :self => "\e[35m", + :char => "\e[1;35m", + :delimiter => "\e[1;35m", + }, + :keyword => "\e[32m", + :label => "\e[1;33m", + :local_variable => "\e[33m", + :namespace => "\e[1;35m", + :octal => "\e[1;34m", + :predefined => "\e[36m", + :predefined_constant => "\e[1;36m", + :predefined_type => "\e[1;32m", + :preprocessor => "\e[1;36m", + :pseudo_class => "\e[1;34m", + :regexp => { + :self => "\e[35m", + :delimiter => "\e[1;35m", + :modifier => "\e[35m", + :char => "\e[1;35m", + }, + :reserved => "\e[32m", + :shell => { + :self => "\e[33m", + :char => "\e[1;33m", + :delimiter => "\e[1;33m", + :escape => "\e[1;33m", + }, + :string => { + :self => "\e[31m", + :modifier => "\e[1;31m", + :char => "\e[1;35m", + :delimiter => "\e[1;31m", + :escape => "\e[1;31m", + }, + :symbol => { + :self => "\e[33m", + :delimiter => "\e[1;33m", + }, + :tag => "\e[32m", + :type => "\e[1;34m", + :value => "\e[36m", + :variable => "\e[34m", + + :insert => { + :self => "\e[42m", + :insert => "\e[1;32;42m", + :eyecatcher => "\e[102m", + }, + :delete => { + :self => "\e[41m", + :delete => "\e[1;31;41m", + :eyecatcher => "\e[101m", + }, + :change => { + :self => "\e[44m", + :change => "\e[37;44m", + }, + :head => { + :self => "\e[45m", + :filename => "\e[37;45m" + }, + } + + TOKEN_COLORS[:keyword] = TOKEN_COLORS[:reserved] + TOKEN_COLORS[:method] = TOKEN_COLORS[:function] + TOKEN_COLORS[:escape] = TOKEN_COLORS[:delimiter] + + protected + + def setup(options) + super + @opened = [] + @color_scopes = [TOKEN_COLORS] + end + + public + + def text_token text, kind + if color = @color_scopes.last[kind] + color = color[:self] if color.is_a? Hash + + @out << color + @out << (text.index("\n") ? text.gsub("\n", "\e[0m\n" + color) : text) + @out << "\e[0m" + if outer_color = @color_scopes.last[:self] + @out << outer_color + end + else + @out << text + end + end + + def begin_group kind + @opened << kind + @out << open_token(kind) + end + alias begin_line begin_group + + def end_group kind + if @opened.pop + @color_scopes.pop + @out << "\e[0m" + if outer_color = @color_scopes.last[:self] + @out << outer_color + end + end + end + + def end_line kind + @out << (@line_filler ||= "\t" * 100) + end_group kind + end + + private + + def open_token kind + if color = @color_scopes.last[kind] + if color.is_a? Hash + @color_scopes << color + color[:self] + else + @color_scopes << @color_scopes.last + color + end + else + @color_scopes << @color_scopes.last + '' + end + end + end + end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/text.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/text.rb new file mode 100644 index 0000000..15c66f9 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/text.rb @@ -0,0 +1,46 @@ +module CodeRay +module Encoders + + # Concats the tokens into a single string, resulting in the original + # code string if no tokens were removed. + # + # Alias: +plain+, +plaintext+ + # + # == Options + # + # === :separator + # A separator string to join the tokens. + # + # Default: empty String + class Text < Encoder + + register_for :text + + FILE_EXTENSION = 'txt' + + DEFAULT_OPTIONS = { + :separator => nil + } + + def text_token text, kind + super + + if @first + @first = false + else + @out << @sep + end if @sep + end + + protected + def setup options + super + + @first = true + @sep = options[:separator] + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/token_kind_filter.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/token_kind_filter.rb new file mode 100644 index 0000000..4773ea3 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/token_kind_filter.rb @@ -0,0 +1,111 @@ +module CodeRay +module Encoders + + load :filter + + # A Filter that selects tokens based on their token kind. + # + # == Options + # + # === :exclude + # + # One or many symbols (in an Array) which shall be excluded. + # + # Default: [] + # + # === :include + # + # One or many symbols (in an array) which shall be included. + # + # Default: :all, which means all tokens are included. + # + # Exclusion wins over inclusion. + # + # See also: CommentFilter + class TokenKindFilter < Filter + + register_for :token_kind_filter + + DEFAULT_OPTIONS = { + :exclude => [], + :include => :all + } + + protected + def setup options + super + + @group_excluded = false + @exclude = options[:exclude] + @exclude = Array(@exclude) unless @exclude == :all + @include = options[:include] + @include = Array(@include) unless @include == :all + end + + def include_text_token? text, kind + include_group? kind + end + + def include_group? kind + (@include == :all || @include.include?(kind)) && + !(@exclude == :all || @exclude.include?(kind)) + end + + public + + # Add the token to the output stream if +kind+ matches the conditions. + def text_token text, kind + super if !@group_excluded && include_text_token?(text, kind) + end + + # Add the token group to the output stream if +kind+ matches the + # conditions. + # + # If it does not, all tokens inside the group are excluded from the + # stream, even if their kinds match. + def begin_group kind + if @group_excluded + @group_excluded += 1 + elsif include_group? kind + super + else + @group_excluded = 1 + end + end + + # See +begin_group+. + def begin_line kind + if @group_excluded + @group_excluded += 1 + elsif include_group? kind + super + else + @group_excluded = 1 + end + end + + # Take care of re-enabling the delegation of tokens to the output stream + # if an exluded group has ended. + def end_group kind + if @group_excluded + @group_excluded -= 1 + @group_excluded = false if @group_excluded.zero? + else + super + end + end + + # See +end_group+. + def end_line kind + if @group_excluded + @group_excluded -= 1 + @group_excluded = false if @group_excluded.zero? + else + super + end + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/xml.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/xml.rb new file mode 100644 index 0000000..3d306a6 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/xml.rb @@ -0,0 +1,72 @@ +module CodeRay +module Encoders + + # = XML Encoder + # + # Uses REXML. Very slow. + class XML < Encoder + + register_for :xml + + FILE_EXTENSION = 'xml' + + autoload :REXML, 'rexml/document' + + DEFAULT_OPTIONS = { + :tab_width => 8, + :pretty => -1, + :transitive => false, + } + + protected + def setup options + super + + @doc = REXML::Document.new + @doc << REXML::XMLDecl.new + @tab_width = options[:tab_width] + @root = @node = @doc.add_element('coderay-tokens') + end + + def finish options + @doc.write @out, options[:pretty], options[:transitive], true + + super + end + + public + def text_token text, kind + if kind == :space + token = @node + else + token = @node.add_element kind.to_s + end + text.scan(/(\x20+)|(\t+)|(\n)|[^\x20\t\n]+/) do |space, tab, nl| + case + when space + token << REXML::Text.new(space, true) + when tab + token << REXML::Text.new(tab, true) + when nl + token << REXML::Text.new(nl, true) + else + token << REXML::Text.new($&) + end + end + end + + def begin_group kind + @node = @node.add_element kind.to_s + end + + def end_group kind + if @node == @root + raise 'no token to close!' + end + @node = @node.parent + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/yaml.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/yaml.rb new file mode 100644 index 0000000..ba6e715 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/encoders/yaml.rb @@ -0,0 +1,50 @@ +autoload :YAML, 'yaml' + +module CodeRay +module Encoders + + # = YAML Encoder + # + # Slow. + class YAML < Encoder + + register_for :yaml + + FILE_EXTENSION = 'yaml' + + protected + def setup options + super + + @data = [] + end + + def finish options + output ::YAML.dump(@data) + end + + public + def text_token text, kind + @data << [text, kind] + end + + def begin_group kind + @data << [:begin_group, kind] + end + + def end_group kind + @data << [:end_group, kind] + end + + def begin_line kind + @data << [:begin_line, kind] + end + + def end_line kind + @data << [:end_line, kind] + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/for_redcloth.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/for_redcloth.rb new file mode 100644 index 0000000..f9df32b --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/for_redcloth.rb @@ -0,0 +1,95 @@ +module CodeRay + + # A little hack to enable CodeRay highlighting in RedCloth. + # + # Usage: + # require 'coderay' + # require 'coderay/for_redcloth' + # RedCloth.new('@[ruby]puts "Hello, World!"@').to_html + # + # Make sure you have RedCloth 4.0.3 activated, for example by calling + # require 'rubygems' + # before RedCloth is loaded and before calling CodeRay.for_redcloth. + module ForRedCloth + + def self.install + gem 'RedCloth', '>= 4.0.3' if defined? gem + require 'redcloth' + unless RedCloth::VERSION.to_s >= '4.0.3' + if defined? gem + raise 'CodeRay.for_redcloth needs RedCloth version 4.0.3 or later. ' + + "You have #{RedCloth::VERSION}. Please gem install RedCloth." + else + $".delete 'redcloth.rb' # sorry, but it works + require 'rubygems' + return install # retry + end + end + unless RedCloth::VERSION.to_s >= '4.2.2' + warn 'CodeRay.for_redcloth works best with RedCloth version 4.2.2 or later.' + end + RedCloth::TextileDoc.send :include, ForRedCloth::TextileDoc + RedCloth::Formatters::HTML.module_eval do + def unescape(html) # :nodoc: + replacements = { + '&' => '&', + '"' => '"', + '>' => '>', + '<' => '<', + } + html.gsub(/&(?:amp|quot|[gl]t);/) { |entity| replacements[entity] } + end + undef code, bc_open, bc_close, escape_pre + def code(opts) # :nodoc: + opts[:block] = true + if !opts[:lang] && RedCloth::VERSION.to_s >= '4.2.0' + # simulating pre-4.2 behavior + if opts[:text].sub!(/\A\[(\w+)\]/, '') + if CodeRay::Scanners[$1].lang == :text + opts[:text] = $& + opts[:text] + else + opts[:lang] = $1 + end + end + end + if opts[:lang] && !filter_coderay + require 'coderay' + @in_bc ||= nil + format = @in_bc ? :div : :span + opts[:text] = unescape(opts[:text]) unless @in_bc + highlighted_code = CodeRay.encode opts[:text], opts[:lang], format + highlighted_code.sub!(/\A<(span|div)/) { |m| m + pba(@in_bc || opts) } + highlighted_code + else + "#{opts[:text]}" + end + end + def bc_open(opts) # :nodoc: + opts[:block] = true + @in_bc = opts + opts[:lang] ? '' : "" + end + def bc_close(opts) # :nodoc: + opts = @in_bc + @in_bc = nil + opts[:lang] ? '' : "\n" + end + def escape_pre(text) # :nodoc: + if @in_bc ||= nil + text + else + html_esc(text, :html_escape_preformatted) + end + end + end + end + + module TextileDoc # :nodoc: + attr_accessor :filter_coderay + end + + end + +end + +CodeRay::ForRedCloth.install \ No newline at end of file diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/file_type.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/file_type.rb new file mode 100644 index 0000000..7de34d5 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/file_type.rb @@ -0,0 +1,151 @@ +module CodeRay + + # = FileType + # + # A simple filetype recognizer. + # + # == Usage + # + # # determine the type of the given + # lang = FileType[file_name] + # + # # return :text if the file type is unknown + # lang = FileType.fetch file_name, :text + # + # # try the shebang line, too + # lang = FileType.fetch file_name, :text, true + module FileType + + UnknownFileType = Class.new Exception + + class << self + + # Try to determine the file type of the file. + # + # +filename+ is a relative or absolute path to a file. + # + # The file itself is only accessed when +read_shebang+ is set to true. + # That means you can get filetypes from files that don't exist. + def [] filename, read_shebang = false + name = File.basename filename + ext = File.extname(name).sub(/^\./, '') # from last dot, delete the leading dot + ext2 = filename.to_s[/\.(.*)/, 1] # from first dot + + type = + TypeFromExt[ext] || + TypeFromExt[ext.downcase] || + (TypeFromExt[ext2] if ext2) || + (TypeFromExt[ext2.downcase] if ext2) || + TypeFromName[name] || + TypeFromName[name.downcase] + type ||= type_from_shebang(filename) if read_shebang + + type + end + + # This works like Hash#fetch. + # + # If the filetype cannot be found, the +default+ value + # is returned. + def fetch filename, default = nil, read_shebang = false + if default && block_given? + warn 'Block supersedes default value argument; use either.' + end + + if type = self[filename, read_shebang] + type + else + return yield if block_given? + return default if default + raise UnknownFileType, 'Could not determine type of %p.' % filename + end + end + + protected + + def type_from_shebang filename + return unless File.exist? filename + File.open filename, 'r' do |f| + if first_line = f.gets + if type = first_line[TypeFromShebang] + type.to_sym + end + end + end + end + + end + + TypeFromExt = { + 'c' => :c, + 'cfc' => :xml, + 'cfm' => :xml, + 'clj' => :clojure, + 'css' => :css, + 'diff' => :diff, + 'dpr' => :delphi, + 'erb' => :erb, + 'gemspec' => :ruby, + 'go' => :go, + 'groovy' => :groovy, + 'gvy' => :groovy, + 'h' => :c, + 'haml' => :haml, + 'htm' => :html, + 'html' => :html, + 'html.erb' => :erb, + 'java' => :java, + 'js' => :java_script, + 'json' => :json, + 'lua' => :lua, + 'mab' => :ruby, + 'pas' => :delphi, + 'patch' => :diff, + 'phtml' => :php, + 'php' => :php, + 'php3' => :php, + 'php4' => :php, + 'php5' => :php, + 'prawn' => :ruby, + 'py' => :python, + 'py3' => :python, + 'pyw' => :python, + 'rake' => :ruby, + 'raydebug' => :raydebug, + 'rb' => :ruby, + 'rbw' => :ruby, + 'rhtml' => :erb, + 'rjs' => :ruby, + 'rpdf' => :ruby, + 'ru' => :ruby, # config.ru + 'rxml' => :ruby, + 'sass' => :sass, + 'sql' => :sql, + 'taskpaper' => :taskpaper, + 'template' => :json, # AWS CloudFormation template + 'tmproj' => :xml, + 'xaml' => :xml, + 'xhtml' => :html, + 'xml' => :xml, + 'yaml' => :yaml, + 'yml' => :yaml, + } + for cpp_alias in %w[cc cpp cp cxx c++ C hh hpp h++ cu] + TypeFromExt[cpp_alias] = :cpp + end + + TypeFromShebang = /\b(?:ruby|perl|python|sh)\b/ + + TypeFromName = { + 'Capfile' => :ruby, + 'Rakefile' => :ruby, + 'Rantfile' => :ruby, + 'Gemfile' => :ruby, + 'Guardfile' => :ruby, + 'Vagrantfile' => :ruby, + 'Appraisals' => :ruby + } + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/plugin.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/plugin.rb new file mode 100644 index 0000000..9a724ff --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/plugin.rb @@ -0,0 +1,274 @@ +module CodeRay + + # = PluginHost + # + # A simple subclass/subfolder plugin system. + # + # Example: + # class Generators + # extend PluginHost + # plugin_path 'app/generators' + # end + # + # class Generator + # extend Plugin + # PLUGIN_HOST = Generators + # end + # + # class FancyGenerator < Generator + # register_for :fancy + # end + # + # Generators[:fancy] #-> FancyGenerator + # # or + # CodeRay.require_plugin 'Generators/fancy' + # # or + # Generators::Fancy + module PluginHost + + # Raised if Encoders::[] fails because: + # * a file could not be found + # * the requested Plugin is not registered + PluginNotFound = Class.new LoadError + HostNotFound = Class.new LoadError + + PLUGIN_HOSTS = [] + PLUGIN_HOSTS_BY_ID = {} # dummy hash + + # Loads all plugins using list and load. + def load_all + for plugin in list + load plugin + end + end + + # Returns the Plugin for +id+. + # + # Example: + # yaml_plugin = MyPluginHost[:yaml] + def [] id, *args, &blk + plugin = validate_id(id) + begin + plugin = plugin_hash.[](plugin, *args, &blk) + end while plugin.is_a? String + plugin + end + + alias load [] + + # Tries to +load+ the missing plugin by translating +const+ to the + # underscore form (eg. LinesOfCode becomes lines_of_code). + def const_missing const + id = const.to_s. + gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). + gsub(/([a-z\d])([A-Z])/,'\1_\2'). + downcase + load id + end + + class << self + + # Adds the module/class to the PLUGIN_HOSTS list. + def extended mod + PLUGIN_HOSTS << mod + end + + end + + # The path where the plugins can be found. + def plugin_path *args + unless args.empty? + @plugin_path = File.expand_path File.join(*args) + end + @plugin_path ||= '' + end + + # Map a plugin_id to another. + # + # Usage: Put this in a file plugin_path/_map.rb. + # + # class MyColorHost < PluginHost + # map :navy => :dark_blue, + # :maroon => :brown, + # :luna => :moon + # end + def map hash + for from, to in hash + from = validate_id from + to = validate_id to + plugin_hash[from] = to unless plugin_hash.has_key? from + end + end + + # Define the default plugin to use when no plugin is found + # for a given id, or return the default plugin. + # + # See also map. + # + # class MyColorHost < PluginHost + # map :navy => :dark_blue + # default :gray + # end + # + # MyColorHost.default # loads and returns the Gray plugin + def default id = nil + if id + id = validate_id id + raise "The default plugin can't be named \"default\"." if id == :default + plugin_hash[:default] = id + else + load :default + end + end + + # Every plugin must register itself for +id+ by calling register_for, + # which calls this method. + # + # See Plugin#register_for. + def register plugin, id + plugin_hash[validate_id(id)] = plugin + end + + # A Hash of plugion_id => Plugin pairs. + def plugin_hash + @plugin_hash ||= (@plugin_hash = make_plugin_hash).tap { load_plugin_map } + end + + # Returns an array of all .rb files in the plugin path. + # + # The extension .rb is not included. + def list + Dir[path_to('*')].select do |file| + File.basename(file)[/^(?!_)\w+\.rb$/] + end.map do |file| + File.basename(file, '.rb').to_sym + end + end + + # Returns an array of all Plugins. + # + # Note: This loads all plugins using load_all. + def all_plugins + load_all + plugin_hash.values.grep(Class) + end + + # Loads the map file (see map). + # + # This is done automatically when plugin_path is called. + def load_plugin_map + mapfile = path_to '_map' + if File.exist? mapfile + require mapfile + true + else + false + end + end + + protected + + # Return a plugin hash that automatically loads plugins. + def make_plugin_hash + Hash.new do |h, plugin_id| + id = validate_id(plugin_id) + path = path_to id + begin + require path + rescue LoadError => boom + if h.has_key?(:default) + h[:default] + else + raise PluginNotFound, '%p could not load plugin %p: %s' % [self, id, boom] + end + else + # Plugin should have registered by now + if h.has_key? id + h[id] + else + raise PluginNotFound, "No #{self.name} plugin for #{id.inspect} found in #{path}." + end + end + end + end + + # Returns the expected path to the plugin file for the given id. + def path_to plugin_id + File.join plugin_path, "#{plugin_id}.rb" + end + + # Converts +id+ to a valid plugin ID String, or returns +nil+. + # + # Raises +ArgumentError+ for all other objects, or if the + # given String includes non-alphanumeric characters (\W). + def validate_id id + case id + when Symbol + id.to_s + when String + if id[/\w+/] == id + id.downcase + else + raise ArgumentError, "Invalid id given: #{id}" + end + else + raise ArgumentError, "Symbol or String expected, but #{id.class} given." + end + end + + end + + + # = Plugin + # + # Plugins have to include this module. + # + # IMPORTANT: Use extend for this module. + # + # See CodeRay::PluginHost for examples. + module Plugin + + attr_reader :plugin_id + + # Register this class for the given +id+. + # + # Example: + # class MyPlugin < PluginHost::BaseClass + # register_for :my_id + # ... + # end + # + # See PluginHost.register. + def register_for id + @plugin_id = id + plugin_host.register self, id + end + + # Returns the title of the plugin, or sets it to the + # optional argument +title+. + def title title = nil + if title + @title = title.to_s + else + @title ||= name[/([^:]+)$/, 1] + end + end + + # The PluginHost for this Plugin class. + def plugin_host host = nil + if host.is_a? PluginHost + const_set :PLUGIN_HOST, host + end + self::PLUGIN_HOST + end + + def aliases + plugin_host.plugin_hash.inject [] do |aliases, (key, _)| + aliases << key if plugin_host[key] == self + aliases + end + end + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/word_list.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/word_list.rb new file mode 100644 index 0000000..4a42c4a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/helpers/word_list.rb @@ -0,0 +1,72 @@ +module CodeRay + + # = WordList + # + # A Hash subclass designed for mapping word lists to token types. + # + # A WordList is a Hash with some additional features. + # It is intended to be used for keyword recognition. + # + # WordList is optimized to be used in Scanners, + # typically to decide whether a given ident is a special token. + # + # For case insensitive words use WordList::CaseIgnoring. + # + # Example: + # + # # define word arrays + # RESERVED_WORDS = %w[ + # asm break case continue default do else + # ] + # + # PREDEFINED_TYPES = %w[ + # int long short char void + # ] + # + # # make a WordList + # IDENT_KIND = WordList.new(:ident). + # add(RESERVED_WORDS, :reserved). + # add(PREDEFINED_TYPES, :predefined_type) + # + # ... + # + # def scan_tokens tokens, options + # ... + # + # elsif scan(/[A-Za-z_][A-Za-z_0-9]*/) + # # use it + # kind = IDENT_KIND[match] + # ... + class WordList < Hash + + # Create a new WordList with +default+ as default value. + def initialize default = false + super default + end + + # Add words to the list and associate them with +value+. + # + # Returns +self+, so you can concat add calls. + def add words, value = true + words.each { |word| self[word] = value } + self + end + + end + + + # A CaseIgnoring WordList is like a WordList, only that + # keys are compared case-insensitively (normalizing keys using +downcase+). + class WordList::CaseIgnoring < WordList + + def [] key + super key.downcase + end + + def []= key, value + super key.downcase, value + end + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanner.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanner.rb new file mode 100644 index 0000000..b3f7e17 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanner.rb @@ -0,0 +1,355 @@ +# encoding: utf-8 +require 'strscan' + +module CodeRay + + autoload :WordList, coderay_path('helpers', 'word_list') + + # = Scanners + # + # This module holds the Scanner class and its subclasses. + # For example, the Ruby scanner is named CodeRay::Scanners::Ruby + # can be found in coderay/scanners/ruby. + # + # Scanner also provides methods and constants for the register + # mechanism and the [] method that returns the Scanner class + # belonging to the given lang. + # + # See PluginHost. + module Scanners + extend PluginHost + plugin_path File.dirname(__FILE__), 'scanners' + + + # = Scanner + # + # The base class for all Scanners. + # + # It is a subclass of Ruby's great +StringScanner+, which + # makes it easy to access the scanning methods inside. + # + # It is also +Enumerable+, so you can use it like an Array of + # Tokens: + # + # require 'coderay' + # + # c_scanner = CodeRay::Scanners[:c].new "if (*p == '{') nest++;" + # + # for text, kind in c_scanner + # puts text if kind == :operator + # end + # + # # prints: (*==)++; + # + # OK, this is a very simple example :) + # You can also use +map+, +any?+, +find+ and even +sort_by+, + # if you want. + class Scanner < StringScanner + + extend Plugin + plugin_host Scanners + + # Raised if a Scanner fails while scanning + ScanError = Class.new StandardError + + # The default options for all scanner classes. + # + # Define @default_options for subclasses. + DEFAULT_OPTIONS = { } + + KINDS_NOT_LOC = [:comment, :doctype, :docstring] + + attr_accessor :state + + class << self + + # Normalizes the given code into a string with UNIX newlines, in the + # scanner's internal encoding, with invalid and undefined charachters + # replaced by placeholders. Always returns a new object. + def normalize code + # original = code + code = code.to_s unless code.is_a? ::String + return code if code.empty? + + if code.respond_to? :encoding + code = encode_with_encoding code, self.encoding + else + code = to_unix code + end + # code = code.dup if code.eql? original + code + end + + # The typical filename suffix for this scanner's language. + def file_extension extension = lang + @file_extension ||= extension.to_s + end + + # The encoding used internally by this scanner. + def encoding name = 'UTF-8' + @encoding ||= defined?(Encoding.find) && Encoding.find(name) + end + + # The lang of this Scanner class, which is equal to its Plugin ID. + def lang + @plugin_id + end + + protected + + def encode_with_encoding code, target_encoding + if code.encoding == target_encoding + if code.valid_encoding? + return to_unix(code) + else + source_encoding = guess_encoding code + end + else + source_encoding = code.encoding + end + # print "encode_with_encoding from #{source_encoding} to #{target_encoding}" + code.encode target_encoding, source_encoding, :universal_newline => true, :undef => :replace, :invalid => :replace + end + + def to_unix code + code.index(?\r) ? code.gsub(/\r\n?/, "\n") : code + end + + def guess_encoding s + #:nocov: + IO.popen("file -b --mime -", "w+") do |file| + file.write s[0, 1024] + file.close_write + begin + Encoding.find file.gets[/charset=([-\w]+)/, 1] + rescue ArgumentError + Encoding::BINARY + end + end + #:nocov: + end + + end + + # Create a new Scanner. + # + # * +code+ is the input String and is handled by the superclass + # StringScanner. + # * +options+ is a Hash with Symbols as keys. + # It is merged with the default options of the class (you can + # overwrite default options here.) + # + # Else, a Tokens object is used. + def initialize code = '', options = {} + if self.class == Scanner + raise NotImplementedError, "I am only the basic Scanner class. I can't scan anything. :( Use my subclasses." + end + + @options = self.class::DEFAULT_OPTIONS.merge options + + super self.class.normalize(code) + + @tokens = options[:tokens] || Tokens.new + @tokens.scanner = self if @tokens.respond_to? :scanner= + + setup + end + + # Sets back the scanner. Subclasses should redefine the reset_instance + # method instead of this one. + def reset + super + reset_instance + end + + # Set a new string to be scanned. + def string= code + code = self.class.normalize(code) + super code + reset_instance + end + + # the Plugin ID for this scanner + def lang + self.class.lang + end + + # the default file extension for this scanner + def file_extension + self.class.file_extension + end + + # Scan the code and returns all tokens in a Tokens object. + def tokenize source = nil, options = {} + options = @options.merge(options) + + set_tokens_from_options options + set_string_from_source source + + begin + scan_tokens @tokens, options + rescue => e + message = "Error in %s#scan_tokens, initial state was: %p" % [self.class, defined?(state) && state] + raise_inspect e.message, @tokens, message, 30, e.backtrace + end + + @cached_tokens = @tokens + if source.is_a? Array + @tokens.split_into_parts(*source.map { |part| part.size }) + else + @tokens + end + end + + # Cache the result of tokenize. + def tokens + @cached_tokens ||= tokenize + end + + # Traverse the tokens. + def each &block + tokens.each(&block) + end + include Enumerable + + # The current line position of the scanner, starting with 1. + # See also: #column. + # + # Beware, this is implemented inefficiently. It should be used + # for debugging only. + def line pos = self.pos + return 1 if pos <= 0 + binary_string[0...pos].count("\n") + 1 + end + + # The current column position of the scanner, starting with 1. + # See also: #line. + def column pos = self.pos + return 1 if pos <= 0 + pos - (binary_string.rindex(?\n, pos - 1) || -1) + end + + # The string in binary encoding. + # + # To be used with #pos, which is the index of the byte the scanner + # will scan next. + def binary_string + @binary_string ||= + if string.respond_to?(:bytesize) && string.bytesize != string.size + #:nocov: + string.dup.force_encoding('binary') + #:nocov: + else + string + end + end + + protected + + # Can be implemented by subclasses to do some initialization + # that has to be done once per instance. + # + # Use reset for initialization that has to be done once per + # scan. + def setup # :doc: + end + + def set_string_from_source source + case source + when Array + self.string = self.class.normalize(source.join) + when nil + reset + else + self.string = self.class.normalize(source) + end + end + + def set_tokens_from_options options + @tokens = options[:tokens] || @tokens || Tokens.new + @tokens.scanner = self if @tokens.respond_to? :scanner= + end + + # This is the central method, and commonly the only one a + # subclass implements. + # + # Subclasses must implement this method; it must return +tokens+ + # and must only use Tokens#<< for storing scanned tokens! + def scan_tokens tokens, options # :doc: + raise NotImplementedError, "#{self.class}#scan_tokens not implemented." + end + + # Resets the scanner. + def reset_instance + @tokens.clear if @tokens.respond_to?(:clear) && !@options[:keep_tokens] + @cached_tokens = nil + @binary_string = nil if defined? @binary_string + end + + SCAN_ERROR_MESSAGE = <<-MESSAGE + + +***ERROR in %s: %s (after %s tokens) + +tokens: +%s + +%s + +surrounding code: +%p ~~ %p + + +***ERROR*** + + MESSAGE + + def raise_inspect_arguments message, tokens, state, ambit + return File.basename(caller[0]), + message, + tokens_size(tokens), + tokens_last(tokens, 10).map(&:inspect).join("\n"), + scanner_state_info(state), + binary_string[pos - ambit, ambit], + binary_string[pos, ambit] + end + + SCANNER_STATE_INFO = <<-INFO +current line: %d column: %d pos: %d +matched: %p state: %p +bol?: %p, eos?: %p + INFO + + def scanner_state_info state + SCANNER_STATE_INFO % [ + line, column, pos, + matched, state || 'No state given!', + bol?, eos?, + ] + end + + # Scanner error with additional status information + def raise_inspect message, tokens, state = self.state, ambit = 30, backtrace = caller + raise ScanError, SCAN_ERROR_MESSAGE % raise_inspect_arguments(message, tokens, state, ambit), backtrace + end + + def tokens_size tokens + tokens.size if tokens.respond_to?(:size) + end + + def tokens_last tokens, n + tokens.respond_to?(:last) ? tokens.last(n) : [] + end + + # Shorthand for scan_until(/\z/). + # This method also avoids a JRuby 1.9 mode bug. + def scan_rest + rest = self.rest + terminate + rest + end + + end + + end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/_map.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/_map.rb new file mode 100644 index 0000000..a240298 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/_map.rb @@ -0,0 +1,24 @@ +module CodeRay +module Scanners + + map \ + :'c++' => :cpp, + :cplusplus => :cpp, + :ecmascript => :java_script, + :ecma_script => :java_script, + :rhtml => :erb, + :eruby => :erb, + :irb => :ruby, + :javascript => :java_script, + :js => :java_script, + :pascal => :delphi, + :patch => :diff, + :plain => :text, + :plaintext => :text, + :xhtml => :html, + :yml => :yaml + + default :text + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/c.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/c.rb new file mode 100644 index 0000000..84b6e8e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/c.rb @@ -0,0 +1,189 @@ +module CodeRay +module Scanners + + # Scanner for C. + class C < Scanner + + register_for :c + file_extension 'c' + + KEYWORDS = [ + 'asm', 'break', 'case', 'continue', 'default', 'do', + 'else', 'enum', 'for', 'goto', 'if', 'return', + 'sizeof', 'struct', 'switch', 'typedef', 'union', 'while', + 'restrict', # added in C99 + ] # :nodoc: + + PREDEFINED_TYPES = [ + 'int', 'long', 'short', 'char', + 'signed', 'unsigned', 'float', 'double', + 'bool', 'complex', # added in C99 + ] # :nodoc: + + PREDEFINED_CONSTANTS = [ + 'EOF', 'NULL', + 'true', 'false', # added in C99 + ] # :nodoc: + DIRECTIVES = [ + 'auto', 'extern', 'register', 'static', 'void', + 'const', 'volatile', # added in C89 + 'inline', # added in C99 + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(PREDEFINED_TYPES, :predefined_type). + add(DIRECTIVES, :directive). + add(PREDEFINED_CONSTANTS, :predefined_constant) # :nodoc: + + ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + label_expected = true + case_expected = false + label_expected_before_preproc_line = nil + in_preproc_line = false + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + if in_preproc_line && match != "\\\n" && match.index(?\n) + in_preproc_line = false + label_expected = label_expected_before_preproc_line + end + encoder.text_token match, :space + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + encoder.text_token match, :comment + + elsif match = scan(/ [-+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x) + label_expected = match =~ /[;\{\}]/ + if case_expected + label_expected = true if match == ':' + case_expected = false + end + encoder.text_token match, :operator + + elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) + kind = IDENT_KIND[match] + if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/) + kind = :label + match << matched + else + label_expected = false + if kind == :keyword + case match + when 'case', 'default' + case_expected = true + end + end + end + encoder.text_token match, kind + + elsif match = scan(/L?"/) + encoder.begin_group :string + if match[0] == ?L + encoder.text_token 'L', :modifier + match = '"' + end + encoder.text_token match, :delimiter + state = :string + + elsif match = scan(/ \# \s* if \s* 0 /x) + match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos? + encoder.text_token match, :comment + + elsif match = scan(/#[ \t]*(\w*)/) + encoder.text_token match, :preprocessor + in_preproc_line = true + label_expected_before_preproc_line = label_expected + state = :include_expected if self[1] == 'include' + + elsif match = scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox) + label_expected = false + encoder.text_token match, :char + + elsif match = scan(/\$/) + encoder.text_token match, :ident + + elsif match = scan(/0[xX][0-9A-Fa-f]+/) + label_expected = false + encoder.text_token match, :hex + + elsif match = scan(/(?:0[0-7]+)(?![89.eEfF])/) + label_expected = false + encoder.text_token match, :octal + + elsif match = scan(/(?:\d+)(?![.eEfF])L?L?/) + label_expected = false + encoder.text_token match, :integer + + elsif match = scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/) + label_expected = false + encoder.text_token match, :float + + else + encoder.text_token getch, :error + + end + + when :string + if match = scan(/[^\\\n"]+/) + encoder.text_token match, :content + elsif match = scan(/"/) + encoder.text_token match, :delimiter + encoder.end_group :string + state = :initial + label_expected = false + elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + elsif match = scan(/ \\ | $ /x) + encoder.end_group :string + encoder.text_token match, :error unless match.empty? + state = :initial + label_expected = false + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + end + + when :include_expected + if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/) + encoder.text_token match, :include + state = :initial + + elsif match = scan(/\s+/) + encoder.text_token match, :space + state = :initial if match.index ?\n + + else + state = :initial + + end + + else + raise_inspect 'Unknown state', encoder + + end + + end + + if state == :string + encoder.end_group :string + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/clojure.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/clojure.rb new file mode 100644 index 0000000..f8fbf65 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/clojure.rb @@ -0,0 +1,217 @@ +# encoding: utf-8 +module CodeRay + module Scanners + + # Clojure scanner by Licenser. + class Clojure < Scanner + + register_for :clojure + file_extension 'clj' + + SPECIAL_FORMS = %w[ + def if do let quote var fn loop recur throw try catch monitor-enter monitor-exit . + new + ] # :nodoc: + + CORE_FORMS = %w[ + + - -> ->> .. / * <= < = == >= > accessor aclone add-classpath add-watch + agent agent-error agent-errors aget alength alias all-ns alter alter-meta! + alter-var-root amap ancestors and apply areduce array-map aset aset-boolean + aset-byte aset-char aset-double aset-float aset-int aset-long aset-short + assert assoc assoc! assoc-in associative? atom await await-for bases bean + bigdec bigint binding bit-and bit-and-not bit-clear bit-flip bit-not bit-or + bit-set bit-shift-left bit-shift-right bit-test bit-xor boolean boolean-array + booleans bound-fn bound-fn* bound? butlast byte byte-array bytes case cast char + char-array char-escape-string char-name-string char? chars class class? + clear-agent-errors clojure-version coll? comment commute comp comparator + compare compare-and-set! compile complement concat cond condp conj conj! + cons constantly construct-proxy contains? count counted? create-ns + create-struct cycle dec decimal? declare definline defmacro defmethod defmulti + defn defn- defonce defprotocol defrecord defstruct deftype delay delay? + deliver denominator deref derive descendants disj disj! dissoc dissoc! + distinct distinct? doall doc dorun doseq dosync dotimes doto double + double-array doubles drop drop-last drop-while empty empty? ensure + enumeration-seq error-handler error-mode eval even? every? extend + extend-protocol extend-type extenders extends? false? ffirst file-seq + filter find find-doc find-ns find-var first float float-array float? + floats flush fn fn? fnext for force format future future-call future-cancel + future-cancelled? future-done? future? gen-class gen-interface gensym get + get-in get-method get-proxy-class get-thread-bindings get-validator hash + hash-map hash-set identical? identity if-let if-not ifn? import in-ns + inc init-proxy instance? int int-array integer? interleave intern + interpose into into-array ints io! isa? iterate iterator-seq juxt key + keys keyword keyword? last lazy-cat lazy-seq let letfn line-seq list list* + list? load load-file load-reader load-string loaded-libs locking long + long-array longs loop macroexpand macroexpand-1 make-array make-hierarchy + map map? mapcat max max-key memfn memoize merge merge-with meta methods + min min-key mod name namespace neg? newline next nfirst nil? nnext not + not-any? not-empty not-every? not= ns ns-aliases ns-imports ns-interns + ns-map ns-name ns-publics ns-refers ns-resolve ns-unalias ns-unmap nth + nthnext num number? numerator object-array odd? or parents partial + partition pcalls peek persistent! pmap pop pop! pop-thread-bindings + pos? pr pr-str prefer-method prefers print print-namespace-doc + print-str printf println println-str prn prn-str promise proxy + proxy-mappings proxy-super push-thread-bindings pvalues quot rand + rand-int range ratio? rationalize re-find re-groups re-matcher + re-matches re-pattern re-seq read read-line read-string reduce ref + ref-history-count ref-max-history ref-min-history ref-set refer + refer-clojure reify release-pending-sends rem remove remove-all-methods + remove-method remove-ns remove-watch repeat repeatedly replace replicate + require reset! reset-meta! resolve rest restart-agent resultset-seq + reverse reversible? rseq rsubseq satisfies? second select-keys send + send-off seq seq? seque sequence sequential? set set-error-handler! + set-error-mode! set-validator! set? short short-array shorts + shutdown-agents slurp some sort sort-by sorted-map sorted-map-by + sorted-set sorted-set-by sorted? special-form-anchor special-symbol? + split-at split-with str string? struct struct-map subs subseq subvec + supers swap! symbol symbol? sync syntax-symbol-anchor take take-last + take-nth take-while test the-ns thread-bound? time to-array to-array-2d + trampoline transient tree-seq true? type unchecked-add unchecked-dec + unchecked-divide unchecked-inc unchecked-multiply unchecked-negate + unchecked-remainder unchecked-subtract underive update-in update-proxy + use val vals var-get var-set var? vary-meta vec vector vector-of vector? + when when-first when-let when-not while with-bindings with-bindings* + with-in-str with-local-vars with-meta with-open with-out-str + with-precision xml-seq zero? zipmap + ] # :nodoc: + + PREDEFINED_CONSTANTS = %w[ + true false nil *1 *2 *3 *agent* *clojure-version* *command-line-args* + *compile-files* *compile-path* *e *err* *file* *flush-on-newline* + *in* *ns* *out* *print-dup* *print-length* *print-level* *print-meta* + *print-readably* *read-eval* *warn-on-reflection* + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(SPECIAL_FORMS, :keyword). + add(CORE_FORMS, :keyword). + add(PREDEFINED_CONSTANTS, :predefined_constant) + + KEYWORD_NEXT_TOKEN_KIND = WordList.new(nil). + add(%w[ def defn defn- definline defmacro defmulti defmethod defstruct defonce declare ], :function). + add(%w[ ns ], :namespace). + add(%w[ defprotocol defrecord ], :class) + + BASIC_IDENTIFIER = /[a-zA-Z$%*\/_+!?&<>\-=]=?[a-zA-Z0-9$&*+!\/_?<>\-\#]*/ + IDENTIFIER = /(?!-\d)(?:(?:#{BASIC_IDENTIFIER}\.)*#{BASIC_IDENTIFIER}(?:\/#{BASIC_IDENTIFIER})?\.?)|\.\.?/ + SYMBOL = /::?#{IDENTIFIER}/o + DIGIT = /\d/ + DIGIT10 = DIGIT + DIGIT16 = /[0-9a-f]/i + DIGIT8 = /[0-7]/ + DIGIT2 = /[01]/ + RADIX16 = /\#x/i + RADIX8 = /\#o/i + RADIX2 = /\#b/i + RADIX10 = /\#d/i + EXACTNESS = /#i|#e/i + SIGN = /[\+-]?/ + EXP_MARK = /[esfdl]/i + EXP = /#{EXP_MARK}#{SIGN}#{DIGIT}+/ + SUFFIX = /#{EXP}?/ + PREFIX10 = /#{RADIX10}?#{EXACTNESS}?|#{EXACTNESS}?#{RADIX10}?/ + PREFIX16 = /#{RADIX16}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX16}/ + PREFIX8 = /#{RADIX8}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX8}/ + PREFIX2 = /#{RADIX2}#{EXACTNESS}?|#{EXACTNESS}?#{RADIX2}/ + UINT10 = /#{DIGIT10}+#*/ + UINT16 = /#{DIGIT16}+#*/ + UINT8 = /#{DIGIT8}+#*/ + UINT2 = /#{DIGIT2}+#*/ + DECIMAL = /#{DIGIT10}+#+\.#*#{SUFFIX}|#{DIGIT10}+\.#{DIGIT10}*#*#{SUFFIX}|\.#{DIGIT10}+#*#{SUFFIX}|#{UINT10}#{EXP}/ + UREAL10 = /#{UINT10}\/#{UINT10}|#{DECIMAL}|#{UINT10}/ + UREAL16 = /#{UINT16}\/#{UINT16}|#{UINT16}/ + UREAL8 = /#{UINT8}\/#{UINT8}|#{UINT8}/ + UREAL2 = /#{UINT2}\/#{UINT2}|#{UINT2}/ + REAL10 = /#{SIGN}#{UREAL10}/ + REAL16 = /#{SIGN}#{UREAL16}/ + REAL8 = /#{SIGN}#{UREAL8}/ + REAL2 = /#{SIGN}#{UREAL2}/ + IMAG10 = /i|#{UREAL10}i/ + IMAG16 = /i|#{UREAL16}i/ + IMAG8 = /i|#{UREAL8}i/ + IMAG2 = /i|#{UREAL2}i/ + COMPLEX10 = /#{REAL10}@#{REAL10}|#{REAL10}\+#{IMAG10}|#{REAL10}-#{IMAG10}|\+#{IMAG10}|-#{IMAG10}|#{REAL10}/ + COMPLEX16 = /#{REAL16}@#{REAL16}|#{REAL16}\+#{IMAG16}|#{REAL16}-#{IMAG16}|\+#{IMAG16}|-#{IMAG16}|#{REAL16}/ + COMPLEX8 = /#{REAL8}@#{REAL8}|#{REAL8}\+#{IMAG8}|#{REAL8}-#{IMAG8}|\+#{IMAG8}|-#{IMAG8}|#{REAL8}/ + COMPLEX2 = /#{REAL2}@#{REAL2}|#{REAL2}\+#{IMAG2}|#{REAL2}-#{IMAG2}|\+#{IMAG2}|-#{IMAG2}|#{REAL2}/ + NUM10 = /#{PREFIX10}?#{COMPLEX10}/ + NUM16 = /#{PREFIX16}#{COMPLEX16}/ + NUM8 = /#{PREFIX8}#{COMPLEX8}/ + NUM2 = /#{PREFIX2}#{COMPLEX2}/ + NUM = /#{NUM10}|#{NUM16}|#{NUM8}|#{NUM2}/ + + protected + + def scan_tokens encoder, options + + state = :initial + kind = nil + + until eos? + + case state + when :initial + if match = scan(/ \s+ | \\\n | , /x) + encoder.text_token match, :space + elsif match = scan(/['`\(\[\)\]\{\}]|\#[({]|~@?|[@\^]/) + encoder.text_token match, :operator + elsif match = scan(/;.*/) + encoder.text_token match, :comment # TODO: recognize (comment ...) too + elsif match = scan(/\#?\\(?:newline|space|.?)/) + encoder.text_token match, :char + elsif match = scan(/\#[ft]/) + encoder.text_token match, :predefined_constant + elsif match = scan(/#{IDENTIFIER}/o) + kind = IDENT_KIND[match] + encoder.text_token match, kind + if rest? && kind == :keyword + if kind = KEYWORD_NEXT_TOKEN_KIND[match] + encoder.text_token match, :space if match = scan(/\s+/o) + encoder.text_token match, kind if match = scan(/#{IDENTIFIER}/o) + end + end + elsif match = scan(/#{SYMBOL}/o) + encoder.text_token match, :symbol + elsif match = scan(/\./) + encoder.text_token match, :operator + elsif match = scan(/ \# \^ #{IDENTIFIER} /ox) + encoder.text_token match, :type + elsif match = scan(/ (\#)? " /x) + state = self[1] ? :regexp : :string + encoder.begin_group state + encoder.text_token match, :delimiter + elsif match = scan(/#{NUM}/o) and not matched.empty? + encoder.text_token match, match[/[.e\/]/i] ? :float : :integer + else + encoder.text_token getch, :error + end + + when :string, :regexp + if match = scan(/[^"\\]+|\\.?/) + encoder.text_token match, :content + elsif match = scan(/"/) + encoder.text_token match, :delimiter + encoder.end_group state + state = :initial + else + raise_inspect "else case \" reached; %p not handled." % peek(1), + encoder, state + end + + else + raise 'else case reached' + + end + + end + + if [:string, :regexp].include? state + encoder.end_group state + end + + encoder + + end + end + end +end \ No newline at end of file diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/cpp.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/cpp.rb new file mode 100644 index 0000000..e61f56f --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/cpp.rb @@ -0,0 +1,215 @@ +module CodeRay +module Scanners + + # Scanner for C++. + # + # Aliases: +cplusplus+, c++ + class CPlusPlus < Scanner + + register_for :cpp + file_extension 'cpp' + title 'C++' + + #-- http://www.cppreference.com/wiki/keywords/start + KEYWORDS = [ + 'and', 'and_eq', 'asm', 'bitand', 'bitor', 'break', + 'case', 'catch', 'class', 'compl', 'const_cast', + 'continue', 'default', 'delete', 'do', 'dynamic_cast', 'else', + 'enum', 'export', 'for', 'goto', 'if', 'namespace', 'new', + 'not', 'not_eq', 'or', 'or_eq', 'reinterpret_cast', 'return', + 'sizeof', 'static_cast', 'struct', 'switch', 'template', + 'throw', 'try', 'typedef', 'typeid', 'typename', 'union', + 'while', 'xor', 'xor_eq', + ] # :nodoc: + + PREDEFINED_TYPES = [ + 'bool', 'char', 'double', 'float', 'int', 'long', + 'short', 'signed', 'unsigned', 'wchar_t', 'string', + ] # :nodoc: + PREDEFINED_CONSTANTS = [ + 'false', 'true', + 'EOF', 'NULL', + ] # :nodoc: + PREDEFINED_VARIABLES = [ + 'this', + ] # :nodoc: + DIRECTIVES = [ + 'auto', 'const', 'explicit', 'extern', 'friend', 'inline', 'mutable', 'operator', + 'private', 'protected', 'public', 'register', 'static', 'using', 'virtual', 'void', + 'volatile', + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(PREDEFINED_TYPES, :predefined_type). + add(PREDEFINED_VARIABLES, :local_variable). + add(DIRECTIVES, :directive). + add(PREDEFINED_CONSTANTS, :predefined_constant) # :nodoc: + + ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + label_expected = true + case_expected = false + label_expected_before_preproc_line = nil + in_preproc_line = false + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + if in_preproc_line && match != "\\\n" && match.index(?\n) + in_preproc_line = false + label_expected = label_expected_before_preproc_line + end + encoder.text_token match, :space + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + encoder.text_token match, :comment + + elsif match = scan(/ \# \s* if \s* 0 /x) + match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos? + encoder.text_token match, :comment + + elsif match = scan(/ [-+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x) + label_expected = match =~ /[;\{\}]/ + if case_expected + label_expected = true if match == ':' + case_expected = false + end + encoder.text_token match, :operator + + elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) + kind = IDENT_KIND[match] + if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/) + kind = :label + match << matched + else + label_expected = false + if kind == :keyword + case match + when 'class' + state = :class_name_expected + when 'case', 'default' + case_expected = true + end + end + end + encoder.text_token match, kind + + elsif match = scan(/\$/) + encoder.text_token match, :ident + + elsif match = scan(/L?"/) + encoder.begin_group :string + if match[0] == ?L + encoder.text_token match, 'L', :modifier + match = '"' + end + state = :string + encoder.text_token match, :delimiter + + elsif match = scan(/#[ \t]*(\w*)/) + encoder.text_token match, :preprocessor + in_preproc_line = true + label_expected_before_preproc_line = label_expected + state = :include_expected if self[1] == 'include' + + elsif match = scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox) + label_expected = false + encoder.text_token match, :char + + elsif match = scan(/0[xX][0-9A-Fa-f]+/) + label_expected = false + encoder.text_token match, :hex + + elsif match = scan(/(?:0[0-7]+)(?![89.eEfF])/) + label_expected = false + encoder.text_token match, :octal + + elsif match = scan(/(?:\d+)(?![.eEfF])L?L?/) + label_expected = false + encoder.text_token match, :integer + + elsif match = scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/) + label_expected = false + encoder.text_token match, :float + + else + encoder.text_token getch, :error + + end + + when :string + if match = scan(/[^\\"]+/) + encoder.text_token match, :content + elsif match = scan(/"/) + encoder.text_token match, :delimiter + encoder.end_group :string + state = :initial + label_expected = false + elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + elsif match = scan(/ \\ | $ /x) + encoder.end_group :string + encoder.text_token match, :error unless match.empty? + state = :initial + label_expected = false + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + end + + when :include_expected + if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/) + encoder.text_token match, :include + state = :initial + + elsif match = scan(/\s+/) + encoder.text_token match, :space + state = :initial if match.index ?\n + + else + state = :initial + + end + + when :class_name_expected + if match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) + encoder.text_token match, :class + state = :initial + + elsif match = scan(/\s+/) + encoder.text_token match, :space + + else + encoder.text_token getch, :error + state = :initial + + end + + else + raise_inspect 'Unknown state', encoder + + end + + end + + if state == :string + encoder.end_group :string + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/css.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/css.rb new file mode 100644 index 0000000..55d5239 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/css.rb @@ -0,0 +1,196 @@ +module CodeRay +module Scanners + + class CSS < Scanner + + register_for :css + + KINDS_NOT_LOC = [ + :comment, + :class, :pseudo_class, :tag, + :id, :directive, + :key, :value, :operator, :color, :float, :string, + :error, :important, :type, + ] # :nodoc: + + module RE # :nodoc: + Hex = /[0-9a-fA-F]/ + Unicode = /\\#{Hex}{1,6}\b/ # differs from standard because it allows uppercase hex too + Escape = /#{Unicode}|\\[^\n0-9a-fA-F]/ + NMChar = /[-_a-zA-Z0-9]/ + NMStart = /[_a-zA-Z]/ + String1 = /"(?:[^\n\\"]+|\\\n|#{Escape})*"?/ # TODO: buggy regexp + String2 = /'(?:[^\n\\']+|\\\n|#{Escape})*'?/ # TODO: buggy regexp + String = /#{String1}|#{String2}/ + + HexColor = /#(?:#{Hex}{6}|#{Hex}{3})/ + + Num = /-?(?:[0-9]*\.[0-9]+|[0-9]+)n?/ + Name = /#{NMChar}+/ + Ident = /-?#{NMStart}#{NMChar}*/ + AtKeyword = /@#{Ident}/ + Percentage = /#{Num}%/ + + reldimensions = %w[em ex px] + absdimensions = %w[in cm mm pt pc] + Unit = Regexp.union(*(reldimensions + absdimensions + %w[s dpi dppx deg])) + + Dimension = /#{Num}#{Unit}/ + + Function = /(?:url|alpha|attr|counters?)\((?:[^)\n]|\\\))*\)?/ + + Id = /(?!#{HexColor}\b(?!-))##{Name}/ + Class = /\.#{Name}/ + PseudoClass = /::?#{Ident}/ + AttributeSelector = /\[[^\]]*\]?/ + end + + protected + + def setup + @state = :initial + @value_expected = false + end + + def scan_tokens encoder, options + states = Array(options[:state] || @state).dup + value_expected = @value_expected + + until eos? + + if match = scan(/\s+/) + encoder.text_token match, :space + + elsif case states.last + when :initial, :media + if match = scan(/(?>#{RE::Ident})(?!\()|\*/ox) + encoder.text_token match, :tag + next + elsif match = scan(RE::Class) + encoder.text_token match, :class + next + elsif match = scan(RE::Id) + encoder.text_token match, :id + next + elsif match = scan(RE::PseudoClass) + encoder.text_token match, :pseudo_class + next + elsif match = scan(RE::AttributeSelector) + # TODO: Improve highlighting inside of attribute selectors. + encoder.text_token match[0,1], :operator + encoder.text_token match[1..-2], :attribute_name if match.size > 2 + encoder.text_token match[-1,1], :operator if match[-1] == ?] + next + elsif match = scan(/@media/) + encoder.text_token match, :directive + states.push :media_before_name + next + end + + when :block + if match = scan(/(?>#{RE::Ident})(?!\()/ox) + if value_expected + encoder.text_token match, :value + else + encoder.text_token match, :key + end + next + end + + when :media_before_name + if match = scan(RE::Ident) + encoder.text_token match, :type + states[-1] = :media_after_name + next + end + + when :media_after_name + if match = scan(/\{/) + encoder.text_token match, :operator + states[-1] = :media + next + end + + else + #:nocov: + raise_inspect 'Unknown state', encoder + #:nocov: + + end + + elsif match = scan(/\/\*(?:.*?\*\/|\z)/m) + encoder.text_token match, :comment + + elsif match = scan(/\{/) + value_expected = false + encoder.text_token match, :operator + states.push :block + + elsif match = scan(/\}/) + value_expected = false + encoder.text_token match, :operator + if states.last == :block || states.last == :media + states.pop + end + + elsif match = scan(/#{RE::String}/o) + encoder.begin_group :string + encoder.text_token match[0, 1], :delimiter + encoder.text_token match[1..-2], :content if match.size > 2 + encoder.text_token match[-1, 1], :delimiter if match.size >= 2 + encoder.end_group :string + + elsif match = scan(/#{RE::Function}/o) + encoder.begin_group :function + start = match[/^\w+\(/] + encoder.text_token start, :delimiter + if match[-1] == ?) + encoder.text_token match[start.size..-2], :content if match.size > start.size + 1 + encoder.text_token ')', :delimiter + else + encoder.text_token match[start.size..-1], :content if match.size > start.size + end + encoder.end_group :function + + elsif match = scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox) + encoder.text_token match, :float + + elsif match = scan(/#{RE::HexColor}/o) + encoder.text_token match, :color + + elsif match = scan(/! *important/) + encoder.text_token match, :important + + elsif match = scan(/(?:rgb|hsl)a?\([^()\n]*\)?/) + encoder.text_token match, :color + + elsif match = scan(RE::AtKeyword) + encoder.text_token match, :directive + + elsif match = scan(/ [+>~:;,.=()\/] /x) + if match == ':' + value_expected = true + elsif match == ';' + value_expected = false + end + encoder.text_token match, :operator + + else + encoder.text_token getch, :error + + end + + end + + if options[:keep_state] + @state = states + @value_expected = value_expected + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/debug.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/debug.rb new file mode 100644 index 0000000..83ede9a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/debug.rb @@ -0,0 +1,75 @@ +require 'set' + +module CodeRay +module Scanners + + # = Debug Scanner + # + # Interprets the output of the Encoders::Debug encoder (basically the inverse function). + class Debug < Scanner + + register_for :debug + title 'CodeRay Token Dump Import' + + protected + + def setup + super + @known_token_kinds = TokenKinds.keys.map(&:to_s).to_set + end + + def scan_tokens encoder, options + + opened_tokens = [] + + until eos? + + if match = scan(/\s+/) + encoder.text_token match, :space + + elsif match = scan(/ (\w+) \( ( [^\)\\]* ( \\. [^\)\\]* )* ) \)? /x) + if @known_token_kinds.include? self[1] + encoder.text_token self[2].gsub(/\\(.)/m, '\1'), self[1].to_sym + else + encoder.text_token matched, :unknown + end + + elsif match = scan(/ (\w+) ([<\[]) /x) + if @known_token_kinds.include? self[1] + kind = self[1].to_sym + else + kind = :unknown + end + + opened_tokens << kind + case self[2] + when '<' + encoder.begin_group kind + when '[' + encoder.begin_line kind + else + raise 'CodeRay bug: This case should not be reached.' + end + + elsif !opened_tokens.empty? && match = scan(/ > /x) + encoder.end_group opened_tokens.pop + + elsif !opened_tokens.empty? && match = scan(/ \] /x) + encoder.end_line opened_tokens.pop + + else + encoder.text_token getch, :space + + end + + end + + encoder.end_group opened_tokens.pop until opened_tokens.empty? + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/delphi.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/delphi.rb new file mode 100644 index 0000000..b328155 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/delphi.rb @@ -0,0 +1,144 @@ +module CodeRay +module Scanners + + # Scanner for the Delphi language (Object Pascal). + # + # Alias: +pascal+ + class Delphi < Scanner + + register_for :delphi + file_extension 'pas' + + KEYWORDS = [ + 'and', 'array', 'as', 'at', 'asm', 'at', 'begin', 'case', 'class', + 'const', 'constructor', 'destructor', 'dispinterface', 'div', 'do', + 'downto', 'else', 'end', 'except', 'exports', 'file', 'finalization', + 'finally', 'for', 'function', 'goto', 'if', 'implementation', 'in', + 'inherited', 'initialization', 'inline', 'interface', 'is', 'label', + 'library', 'mod', 'nil', 'not', 'object', 'of', 'or', 'out', 'packed', + 'procedure', 'program', 'property', 'raise', 'record', 'repeat', + 'resourcestring', 'set', 'shl', 'shr', 'string', 'then', 'threadvar', + 'to', 'try', 'type', 'unit', 'until', 'uses', 'var', 'while', 'with', + 'xor', 'on', + ] # :nodoc: + + DIRECTIVES = [ + 'absolute', 'abstract', 'assembler', 'at', 'automated', 'cdecl', + 'contains', 'deprecated', 'dispid', 'dynamic', 'export', + 'external', 'far', 'forward', 'implements', 'local', + 'near', 'nodefault', 'on', 'overload', 'override', + 'package', 'pascal', 'platform', 'private', 'protected', 'public', + 'published', 'read', 'readonly', 'register', 'reintroduce', + 'requires', 'resident', 'safecall', 'stdcall', 'stored', 'varargs', + 'virtual', 'write', 'writeonly', + ] # :nodoc: + + IDENT_KIND = WordList::CaseIgnoring.new(:ident). + add(KEYWORDS, :keyword). + add(DIRECTIVES, :directive) # :nodoc: + + NAME_FOLLOWS = WordList::CaseIgnoring.new(false). + add(%w(procedure function .)) # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + last_token = '' + + until eos? + + if state == :initial + + if match = scan(/ \s+ /x) + encoder.text_token match, :space + next + + elsif match = scan(%r! \{ \$ [^}]* \}? | \(\* \$ (?: .*? \*\) | .* ) !mx) + encoder.text_token match, :preprocessor + next + + elsif match = scan(%r! // [^\n]* | \{ [^}]* \}? | \(\* (?: .*? \*\) | .* ) !mx) + encoder.text_token match, :comment + next + + elsif match = scan(/ <[>=]? | >=? | :=? | [-+=*\/;,@\^|\(\)\[\]] | \.\. /x) + encoder.text_token match, :operator + + elsif match = scan(/\./) + encoder.text_token match, :operator + next if last_token == 'end' + + elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) + encoder.text_token match, NAME_FOLLOWS[last_token] ? :ident : IDENT_KIND[match] + + elsif match = skip(/ ' ( [^\n']|'' ) (?:'|$) /x) + encoder.begin_group :char + encoder.text_token "'", :delimiter + encoder.text_token self[1], :content + encoder.text_token "'", :delimiter + encoder.end_group :char + next + + elsif match = scan(/ ' /x) + encoder.begin_group :string + encoder.text_token match, :delimiter + state = :string + + elsif match = scan(/ \# (?: \d+ | \$[0-9A-Fa-f]+ ) /x) + encoder.text_token match, :char + + elsif match = scan(/ \$ [0-9A-Fa-f]+ /x) + encoder.text_token match, :hex + + elsif match = scan(/ (?: \d+ ) (?![eE]|\.[^.]) /x) + encoder.text_token match, :integer + + elsif match = scan(/ \d+ (?: \.\d+ (?: [eE][+-]? \d+ )? | [eE][+-]? \d+ ) /x) + encoder.text_token match, :float + + else + encoder.text_token getch, :error + next + + end + + elsif state == :string + if match = scan(/[^\n']+/) + encoder.text_token match, :content + elsif match = scan(/''/) + encoder.text_token match, :char + elsif match = scan(/'/) + encoder.text_token match, :delimiter + encoder.end_group :string + state = :initial + next + elsif match = scan(/\n/) + encoder.end_group :string + encoder.text_token match, :space + state = :initial + else + raise "else case \' reached; %p not handled." % peek(1), encoder + end + + else + raise 'else-case reached', encoder + + end + + last_token = match + + end + + if state == :string + encoder.end_group state + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/diff.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/diff.rb new file mode 100644 index 0000000..fd1aed6 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/diff.rb @@ -0,0 +1,221 @@ +module CodeRay +module Scanners + + # Scanner for output of the diff command. + # + # Alias: +patch+ + class Diff < Scanner + + register_for :diff + title 'diff output' + + DEFAULT_OPTIONS = { + :highlight_code => true, + :inline_diff => true, + } + + protected + + def scan_tokens encoder, options + + line_kind = nil + state = :initial + deleted_lines_count = 0 + scanners = Hash.new do |h, lang| + h[lang] = Scanners[lang].new '', :keep_tokens => true, :keep_state => true + end + content_scanner = scanners[:plain] + content_scanner_entry_state = nil + + until eos? + + if match = scan(/\n/) + deleted_lines_count = 0 unless line_kind == :delete + if line_kind + encoder.end_line line_kind + line_kind = nil + end + encoder.text_token match, :space + next + end + + case state + + when :initial + if match = scan(/--- |\+\+\+ |=+|_+/) + encoder.begin_line line_kind = :head + encoder.text_token match, :head + if match = scan(/[^\x00\n]+?(?=$|[\t\n]| \(revision)/) + encoder.text_token match, :filename + if options[:highlight_code] && match != '/dev/null' + file_type = CodeRay::FileType.fetch(match, :text) + file_type = :text if file_type == :diff + content_scanner = scanners[file_type] + content_scanner_entry_state = nil + end + end + next unless match = scan(/.+/) + encoder.text_token match, :plain + elsif match = scan(/Index: |Property changes on: /) + encoder.begin_line line_kind = :head + encoder.text_token match, :head + next unless match = scan(/.+/) + encoder.text_token match, :plain + elsif match = scan(/Added: /) + encoder.begin_line line_kind = :head + encoder.text_token match, :head + next unless match = scan(/.+/) + encoder.text_token match, :plain + state = :added + elsif match = scan(/\\ .*/) + encoder.text_token match, :comment + elsif match = scan(/@@(?>[^@\n]+)@@/) + content_scanner.state = :initial unless match?(/\n\+/) + content_scanner_entry_state = nil + if check(/\n|$/) + encoder.begin_line line_kind = :change + else + encoder.begin_group :change + end + encoder.text_token match[0,2], :change + encoder.text_token match[2...-2], :plain + encoder.text_token match[-2,2], :change + encoder.end_group :change unless line_kind + next unless match = scan(/.+/) + if options[:highlight_code] + content_scanner.tokenize match, :tokens => encoder + else + encoder.text_token match, :plain + end + next + elsif match = scan(/\+/) + encoder.begin_line line_kind = :insert + encoder.text_token match, :insert + next unless match = scan(/.+/) + if options[:highlight_code] + content_scanner.tokenize match, :tokens => encoder + else + encoder.text_token match, :plain + end + next + elsif match = scan(/-/) + deleted_lines_count += 1 + if options[:inline_diff] && deleted_lines_count == 1 && (changed_lines_count = 1 + check(/.*(?:\n\-.*)*/).count("\n")) && match?(/(?>.*(?:\n\-.*){#{changed_lines_count - 1}}(?:\n\+.*){#{changed_lines_count}})$(?!\n\+)/) + deleted_lines = Array.new(changed_lines_count) { |i| skip(/\n\-/) if i > 0; scan(/.*/) } + inserted_lines = Array.new(changed_lines_count) { |i| skip(/\n\+/) ; scan(/.*/) } + + deleted_lines_tokenized = [] + inserted_lines_tokenized = [] + for deleted_line, inserted_line in deleted_lines.zip(inserted_lines) + pre, deleted_part, inserted_part, post = diff deleted_line, inserted_line + content_scanner_entry_state = content_scanner.state + deleted_lines_tokenized << content_scanner.tokenize([pre, deleted_part, post], :tokens => Tokens.new) + content_scanner.state = content_scanner_entry_state || :initial + inserted_lines_tokenized << content_scanner.tokenize([pre, inserted_part, post], :tokens => Tokens.new) + end + + for pre, deleted_part, post in deleted_lines_tokenized + encoder.begin_line :delete + encoder.text_token '-', :delete + encoder.tokens pre + unless deleted_part.empty? + encoder.begin_group :eyecatcher + encoder.tokens deleted_part + encoder.end_group :eyecatcher + end + encoder.tokens post + encoder.end_line :delete + encoder.text_token "\n", :space + end + + for pre, inserted_part, post in inserted_lines_tokenized + encoder.begin_line :insert + encoder.text_token '+', :insert + encoder.tokens pre + unless inserted_part.empty? + encoder.begin_group :eyecatcher + encoder.tokens inserted_part + encoder.end_group :eyecatcher + end + encoder.tokens post + changed_lines_count -= 1 + if changed_lines_count > 0 + encoder.end_line :insert + encoder.text_token "\n", :space + end + end + + line_kind = :insert + + elsif match = scan(/.*/) + encoder.begin_line line_kind = :delete + encoder.text_token '-', :delete + if options[:highlight_code] + if deleted_lines_count == 1 + content_scanner_entry_state = content_scanner.state + end + content_scanner.tokenize match, :tokens => encoder unless match.empty? + if !match?(/\n-/) + if match?(/\n\+/) + content_scanner.state = content_scanner_entry_state || :initial + end + content_scanner_entry_state = nil + end + else + encoder.text_token match, :plain + end + end + next + elsif match = scan(/ .*/) + if options[:highlight_code] + content_scanner.tokenize match, :tokens => encoder + else + encoder.text_token match, :plain + end + next + elsif match = scan(/.+/) + encoder.begin_line line_kind = :comment + encoder.text_token match, :plain + else + raise_inspect 'else case rached' + end + + when :added + if match = scan(/ \+/) + encoder.begin_line line_kind = :insert + encoder.text_token match, :insert + next unless match = scan(/.+/) + encoder.text_token match, :plain + else + state = :initial + next + end + end + + end + + encoder.end_line line_kind if line_kind + + encoder + end + + private + + def diff a, b + # i will be the index of the leftmost difference from the left. + i_max = [a.size, b.size].min + i = 0 + i += 1 while i < i_max && a[i] == b[i] + # j_min will be the index of the leftmost difference from the right. + j_min = i - i_max + # j will be the index of the rightmost difference from the right which + # does not precede the leftmost one from the left. + j = -1 + j -= 1 while j >= j_min && a[j] == b[j] + return a[0...i], a[i..j], b[i..j], (j < -1) ? a[j+1..-1] : '' + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/erb.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/erb.rb new file mode 100644 index 0000000..727a993 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/erb.rb @@ -0,0 +1,81 @@ +module CodeRay +module Scanners + + load :html + load :ruby + + # Scanner for HTML ERB templates. + class ERB < Scanner + + register_for :erb + title 'HTML ERB Template' + + KINDS_NOT_LOC = HTML::KINDS_NOT_LOC + + ERB_RUBY_BLOCK = / + (<%(?!%)[-=\#]?) + ((?> + [^\-%]* # normal* + (?> # special + (?: %(?!>) | -(?!%>) ) + [^\-%]* # normal* + )* + )) + ((?: -?%> )?) + /x # :nodoc: + + START_OF_ERB = / + <%(?!%) + /x # :nodoc: + + protected + + def setup + @ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true + @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true, :keep_state => true + end + + def reset_instance + super + @html_scanner.reset + end + + def scan_tokens encoder, options + + until eos? + + if (match = scan_until(/(?=#{START_OF_ERB})/o) || scan_rest) and not match.empty? + @html_scanner.tokenize match, :tokens => encoder + + elsif match = scan(/#{ERB_RUBY_BLOCK}/o) + start_tag = self[1] + code = self[2] + end_tag = self[3] + + encoder.begin_group :inline + encoder.text_token start_tag, :inline_delimiter + + if start_tag == '<%#' + encoder.text_token code, :comment + else + @ruby_scanner.tokenize code, :tokens => encoder + end unless code.empty? + + encoder.text_token end_tag, :inline_delimiter unless end_tag.empty? + encoder.end_group :inline + + else + raise_inspect 'else-case reached!', encoder + + end + + end + + encoder + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/go.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/go.rb new file mode 100644 index 0000000..99fdd63 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/go.rb @@ -0,0 +1,208 @@ +module CodeRay +module Scanners + + class Go < Scanner + + register_for :go + file_extension 'go' + + # http://golang.org/ref/spec#Keywords + KEYWORDS = [ + 'break', 'default', 'func', 'interface', 'select', + 'case', 'defer', 'go', 'map', 'struct', + 'chan', 'else', 'goto', 'package', 'switch', + 'const', 'fallthrough', 'if', 'range', 'type', + 'continue', 'for', 'import', 'return', 'var', + ] # :nodoc: + + # http://golang.org/ref/spec#Types + PREDEFINED_TYPES = [ + 'bool', + 'uint8', 'uint16', 'uint32', 'uint64', + 'int8', 'int16', 'int32', 'int64', + 'float32', 'float64', + 'complex64', 'complex128', + 'byte', 'rune', 'string', 'error', + 'uint', 'int', 'uintptr', + ] # :nodoc: + + PREDEFINED_CONSTANTS = [ + 'nil', 'iota', + 'true', 'false', + ] # :nodoc: + + PREDEFINED_FUNCTIONS = %w[ + append cap close complex copy delete imag len + make new panic print println real recover + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(PREDEFINED_TYPES, :predefined_type). + add(PREDEFINED_CONSTANTS, :predefined_constant). + add(PREDEFINED_FUNCTIONS, :predefined) # :nodoc: + + ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + label_expected = true + case_expected = false + label_expected_before_preproc_line = nil + in_preproc_line = false + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + if in_preproc_line && match != "\\\n" && match.index(?\n) + in_preproc_line = false + case_expected = false + label_expected = label_expected_before_preproc_line + end + encoder.text_token match, :space + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + encoder.text_token match, :comment + + elsif match = scan(/ ?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x) + if case_expected + label_expected = true if match == ':' + case_expected = false + end + encoder.text_token match, :operator + + elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x) + kind = IDENT_KIND[match] + if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/) + kind = :label + label_expected = false + match << matched + else + label_expected = false + if kind == :keyword + case match + when 'case', 'default' + case_expected = true + end + end + end + encoder.text_token match, kind + + elsif match = scan(/L?"/) + encoder.begin_group :string + if match[0] == ?L + encoder.text_token 'L', :modifier + match = '"' + end + encoder.text_token match, :delimiter + state = :string + + elsif match = scan(/ ` ([^`]+)? (`)? /x) + encoder.begin_group :shell + encoder.text_token '`', :delimiter + encoder.text_token self[1], :content if self[1] + encoder.text_token self[2], :delimiter if self[2] + encoder.end_group :shell + + elsif match = scan(/ \# \s* if \s* 0 /x) + match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos? + encoder.text_token match, :comment + + elsif match = scan(/#[ \t]*(\w*)/) + encoder.text_token match, :preprocessor + in_preproc_line = true + label_expected_before_preproc_line = label_expected + state = :include_expected if self[1] == 'include' + + elsif match = scan(/ L?' (?: [^\'\n\\] | \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) )? '? /ox) + label_expected = false + encoder.text_token match, :char + + elsif match = scan(/\$/) + encoder.text_token match, :ident + + elsif match = scan(/-?\d*(\.\d*)?([eE][+-]?\d+)?i/) + label_expected = false + encoder.text_token match, :imaginary + + elsif match = scan(/-?0[xX][0-9A-Fa-f]+/) + label_expected = false + encoder.text_token match, :hex + + elsif match = scan(/-?(?:0[0-7]+)(?![89.eEfF])/) + label_expected = false + encoder.text_token match, :octal + + elsif match = scan(/-?(?:\d*\.\d+|\d+\.)(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+/) + label_expected = false + encoder.text_token match, :float + + elsif match = scan(/-?(?:\d+)(?![.eEfF])L?L?/) + label_expected = false + encoder.text_token match, :integer + + else + encoder.text_token getch, :error + + end + + when :string + if match = scan(/[^\\\n"]+/) + encoder.text_token match, :content + elsif match = scan(/"/) + encoder.text_token match, :delimiter + encoder.end_group :string + state = :initial + label_expected = false + elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + elsif match = scan(/ \\ /x) + encoder.text_token match, :error + elsif match = scan(/$/) + encoder.end_group :string + state = :initial + label_expected = false + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + end + + when :include_expected + if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/) + encoder.text_token match, :include + state = :initial + + elsif match = scan(/\s+/) + encoder.text_token match, :space + state = :initial if match.index ?\n + + else + state = :initial + + end + + else + raise_inspect 'Unknown state', encoder + + end + + end + + if state == :string + encoder.end_group :string + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/groovy.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/groovy.rb new file mode 100644 index 0000000..c64454f --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/groovy.rb @@ -0,0 +1,268 @@ +module CodeRay +module Scanners + + load :java + + # Scanner for Groovy. + class Groovy < Java + + register_for :groovy + + # TODO: check list of keywords + GROOVY_KEYWORDS = %w[ + as assert def in + ] # :nodoc: + KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[ + case instanceof new return throw typeof while as assert in + ] # :nodoc: + GROOVY_MAGIC_VARIABLES = %w[ it ] # :nodoc: + + IDENT_KIND = Java::IDENT_KIND.dup. + add(GROOVY_KEYWORDS, :keyword). + add(GROOVY_MAGIC_VARIABLES, :local_variable) # :nodoc: + + ESCAPE = / [bfnrtv$\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # :nodoc: no 4-byte unicode chars? U[a-fA-F0-9]{8} + REGEXP_ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} | \d | [bBdDsSwW\/] /x # :nodoc: + + # TODO: interpretation inside ', ", / + STRING_CONTENT_PATTERN = { + "'" => /(?>\\[^\\'\n]+|[^\\'\n]+)+/, + '"' => /[^\\$"\n]+/, + "'''" => /(?>[^\\']+|'(?!''))+/, + '"""' => /(?>[^\\$"]+|"(?!""))+/, + '/' => /[^\\$\/\n]+/, + } # :nodoc: + + protected + + def setup + @state = :initial + end + + def scan_tokens encoder, options + state = options[:state] || @state + inline_block_stack = [] + inline_block_paren_depth = nil + string_delimiter = nil + import_clause = class_name_follows = last_token = after_def = false + value_expected = true + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + encoder.text_token match, :space + if match.index ?\n + import_clause = after_def = false + value_expected = true unless value_expected + end + next + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + value_expected = true + after_def = false + encoder.text_token match, :comment + + elsif bol? && match = scan(/ \#!.* /x) + encoder.text_token match, :doctype + + elsif import_clause && match = scan(/ (?!as) #{IDENT} (?: \. #{IDENT} )* (?: \.\* )? /ox) + after_def = value_expected = false + encoder.text_token match, :include + + elsif match = scan(/ #{IDENT} | \[\] /ox) + kind = IDENT_KIND[match] + value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match] + if last_token == '.' + kind = :ident + elsif class_name_follows + kind = :class + class_name_follows = false + elsif after_def && check(/\s*[({]/) + kind = :method + after_def = false + elsif kind == :ident && last_token != '?' && check(/:/) + kind = :key + else + class_name_follows = true if match == 'class' || (import_clause && match == 'as') + import_clause = match == 'import' + after_def = true if match == 'def' + end + encoder.text_token match, kind + + elsif match = scan(/;/) + import_clause = after_def = false + value_expected = true + encoder.text_token match, :operator + + elsif match = scan(/\{/) + class_name_follows = after_def = false + value_expected = true + encoder.text_token match, :operator + if !inline_block_stack.empty? + inline_block_paren_depth += 1 + end + + # TODO: ~'...', ~"..." and ~/.../ style regexps + elsif match = scan(/ \.\.] | \+\+ | + && | \|\| | \*\*=? | ==?~ | <=?>? | [-+*%^~&|>=!]=? | <<>>?=? /x) + value_expected = true + value_expected = :regexp if match == '~' + after_def = false + encoder.text_token match, :operator + + elsif match = scan(/ [)\]}] /x) + value_expected = after_def = false + if !inline_block_stack.empty? && match == '}' + inline_block_paren_depth -= 1 + if inline_block_paren_depth == 0 # closing brace of inline block reached + encoder.text_token match, :inline_delimiter + encoder.end_group :inline + state, string_delimiter, inline_block_paren_depth = inline_block_stack.pop + next + end + end + encoder.text_token match, :operator + + elsif check(/[\d.]/) + after_def = value_expected = false + if match = scan(/0[xX][0-9A-Fa-f]+/) + encoder.text_token match, :hex + elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/) + encoder.text_token match, :octal + elsif match = scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/) + encoder.text_token match, :float + elsif match = scan(/\d+[lLgG]?/) + encoder.text_token match, :integer + end + + elsif match = scan(/'''|"""/) + after_def = value_expected = false + state = :multiline_string + encoder.begin_group :string + string_delimiter = match + encoder.text_token match, :delimiter + + # TODO: record.'name' syntax + elsif match = scan(/["']/) + after_def = value_expected = false + state = match == '/' ? :regexp : :string + encoder.begin_group state + string_delimiter = match + encoder.text_token match, :delimiter + + elsif value_expected && match = scan(/\//) + after_def = value_expected = false + encoder.begin_group :regexp + state = :regexp + string_delimiter = '/' + encoder.text_token match, :delimiter + + elsif match = scan(/ @ #{IDENT} /ox) + after_def = value_expected = false + encoder.text_token match, :annotation + + elsif match = scan(/\//) + after_def = false + value_expected = true + encoder.text_token match, :operator + + else + encoder.text_token getch, :error + + end + + when :string, :regexp, :multiline_string + if match = scan(STRING_CONTENT_PATTERN[string_delimiter]) + encoder.text_token match, :content + + elsif match = scan(state == :multiline_string ? /'''|"""/ : /["'\/]/) + encoder.text_token match, :delimiter + if state == :regexp + # TODO: regexp modifiers? s, m, x, i? + modifiers = scan(/[ix]+/) + encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty? + end + state = :string if state == :multiline_string + encoder.end_group state + string_delimiter = nil + after_def = value_expected = false + state = :initial + next + + elsif (state == :string || state == :multiline_string) && + (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) + if string_delimiter[0] == ?' && !(match == "\\\\" || match == "\\'") + encoder.text_token match, :content + else + encoder.text_token match, :char + end + elsif state == :regexp && match = scan(/ \\ (?: #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + + elsif match = scan(/ \$ #{IDENT} /mox) + encoder.begin_group :inline + encoder.text_token '$', :inline_delimiter + match = match[1..-1] + encoder.text_token match, IDENT_KIND[match] + encoder.end_group :inline + next + elsif match = scan(/ \$ \{ /x) + encoder.begin_group :inline + encoder.text_token match, :inline_delimiter + inline_block_stack << [state, string_delimiter, inline_block_paren_depth] + inline_block_paren_depth = 1 + state = :initial + next + + elsif match = scan(/ \$ /mx) + encoder.text_token match, :content + + elsif match = scan(/ \\. /mx) + encoder.text_token match, :content # TODO: Shouldn't this be :error? + + elsif match = scan(/ \\ | \n /x) + encoder.end_group state == :regexp ? :regexp : :string + encoder.text_token match, :error + after_def = value_expected = false + state = :initial + + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + + end + + else + raise_inspect 'Unknown state', encoder + + end + + last_token = match unless [:space, :comment, :doctype].include? kind + + end + + if [:multiline_string, :string, :regexp].include? state + encoder.end_group state == :regexp ? :regexp : :string + end + + if options[:keep_state] + @state = state + end + + until inline_block_stack.empty? + state, = *inline_block_stack.pop + encoder.end_group :inline + encoder.end_group state == :regexp ? :regexp : :string + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/haml.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/haml.rb new file mode 100644 index 0000000..5433790 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/haml.rb @@ -0,0 +1,168 @@ +module CodeRay +module Scanners + + load :ruby + load :html + load :java_script + + class HAML < Scanner + + register_for :haml + title 'HAML Template' + + KINDS_NOT_LOC = HTML::KINDS_NOT_LOC + + protected + + def setup + super + @ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true + @embedded_ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true, :state => @ruby_scanner.interpreted_string_state + @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true + end + + def scan_tokens encoder, options + + match = nil + code = '' + + until eos? + + if bol? + if match = scan(/!!!.*/) + encoder.text_token match, :doctype + next + end + + if match = scan(/(?>( *)(\/(?!\[if)|-\#|:javascript|:ruby|:\w+) *)(?=\n)/) + encoder.text_token match, :comment + + code = self[2] + if match = scan(/(?:\n+#{self[1]} .*)+/) + case code + when '/', '-#' + encoder.text_token match, :comment + when ':javascript' + # TODO: recognize #{...} snippets inside JavaScript + @java_script_scanner ||= CodeRay.scanner :java_script, :tokens => @tokens, :keep_tokens => true + @java_script_scanner.tokenize match, :tokens => encoder + when ':ruby' + @ruby_scanner.tokenize match, :tokens => encoder + when /:\w+/ + encoder.text_token match, :comment + else + raise 'else-case reached: %p' % [code] + end + end + end + + if match = scan(/ +/) + encoder.text_token match, :space + end + + if match = scan(/\/.*/) + encoder.text_token match, :comment + next + end + + if match = scan(/\\/) + encoder.text_token match, :plain + if match = scan(/.+/) + @html_scanner.tokenize match, :tokens => encoder + end + next + end + + tag = false + + if match = scan(/%[\w:]+\/?/) + encoder.text_token match, :tag + # if match = scan(/( +)(.+)/) + # encoder.text_token self[1], :space + # @embedded_ruby_scanner.tokenize self[2], :tokens => encoder + # end + tag = true + end + + while match = scan(/([.#])[-\w]*\w/) + encoder.text_token match, self[1] == '#' ? :constant : :class + tag = true + end + + if tag && match = scan(/(\()([^)]+)?(\))?/) + # TODO: recognize title=@title, class="widget_#{@widget.number}" + encoder.text_token self[1], :plain + @html_scanner.tokenize self[2], :tokens => encoder, :state => :attribute if self[2] + encoder.text_token self[3], :plain if self[3] + end + + if tag && match = scan(/\{/) + encoder.text_token match, :plain + + code = '' + level = 1 + while true + code << scan(/([^\{\},\n]|, *\n?)*/) + case match = getch + when '{' + level += 1 + code << match + when '}' + level -= 1 + if level > 0 + code << match + else + break + end + when "\n", ",", nil + break + end + end + @ruby_scanner.tokenize code, :tokens => encoder unless code.empty? + + encoder.text_token match, :plain if match + end + + if tag && match = scan(/(\[)([^\]\n]+)?(\])?/) + encoder.text_token self[1], :plain + @ruby_scanner.tokenize self[2], :tokens => encoder if self[2] + encoder.text_token self[3], :plain if self[3] + end + + if tag && match = scan(/\//) + encoder.text_token match, :tag + end + + if scan(/(>? encoder + else + @ruby_scanner.tokenize self[4], :tokens => encoder + end + end + elsif match = scan(/((?:<|> encoder if self[2] + end + + elsif match = scan(/.+/) + @html_scanner.tokenize match, :tokens => encoder + + end + + if match = scan(/\n/) + encoder.text_token match, :space + end + end + + encoder + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/html.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/html.rb new file mode 100644 index 0000000..ebe7b01 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/html.rb @@ -0,0 +1,275 @@ +module CodeRay +module Scanners + + # HTML Scanner + # + # Alias: +xhtml+ + # + # See also: Scanners::XML + class HTML < Scanner + + register_for :html + + KINDS_NOT_LOC = [ + :comment, :doctype, :preprocessor, + :tag, :attribute_name, :operator, + :attribute_value, :string, + :plain, :entity, :error, + ] # :nodoc: + + EVENT_ATTRIBUTES = %w( + onabort onafterprint onbeforeprint onbeforeunload onblur oncanplay + oncanplaythrough onchange onclick oncontextmenu oncuechange ondblclick + ondrag ondragdrop ondragend ondragenter ondragleave ondragover + ondragstart ondrop ondurationchange onemptied onended onerror onfocus + onformchange onforminput onhashchange oninput oninvalid onkeydown + onkeypress onkeyup onload onloadeddata onloadedmetadata onloadstart + onmessage onmousedown onmousemove onmouseout onmouseover onmouseup + onmousewheel onmove onoffline ononline onpagehide onpageshow onpause + onplay onplaying onpopstate onprogress onratechange onreadystatechange + onredo onreset onresize onscroll onseeked onseeking onselect onshow + onstalled onstorage onsubmit onsuspend ontimeupdate onundo onunload + onvolumechange onwaiting + ) + + IN_ATTRIBUTE = WordList::CaseIgnoring.new(nil). + add(EVENT_ATTRIBUTES, :script). + add(['style'], :style) + + ATTR_NAME = /[\w.:-]+/ # :nodoc: + TAG_END = /\/?>/ # :nodoc: + HEX = /[0-9a-fA-F]/ # :nodoc: + ENTITY = / + & + (?: + \w+ + | + \# + (?: + \d+ + | + x#{HEX}+ + ) + ) + ; + /ox # :nodoc: + + PLAIN_STRING_CONTENT = { + "'" => /[^&'>\n]+/, + '"' => /[^&">\n]+/, + } # :nodoc: + + def reset + super + @state = :initial + @plain_string_content = nil + end + + protected + + def setup + @state = :initial + @plain_string_content = nil + @in_tag = nil + end + + def scan_java_script encoder, code + if code && !code.empty? + @java_script_scanner ||= Scanners::JavaScript.new '', :keep_tokens => true + @java_script_scanner.tokenize code, :tokens => encoder + end + end + + def scan_css encoder, code, state = [:initial] + if code && !code.empty? + @css_scanner ||= Scanners::CSS.new '', :keep_tokens => true + @css_scanner.tokenize code, :tokens => encoder, :state => state + end + end + + def scan_tokens encoder, options + state = options[:state] || @state + plain_string_content = @plain_string_content + in_tag = @in_tag + in_attribute = nil + + encoder.begin_group :string if state == :attribute_value_string + + until eos? + + if state != :in_special_tag && match = scan(/\s+/m) + encoder.text_token match, :space + + else + + case state + + when :initial + if match = scan(//m) + encoder.text_token match[0..-4], :plain + encoder.text_token ']]>', :inline_delimiter + elsif match = scan(/.+/) + encoder.text_token match, :error + end + elsif match = scan(/|.*)/m) + encoder.text_token match, :comment + elsif match = scan(/|.*)|\]>/m) + encoder.text_token match, :doctype + elsif match = scan(/<\?xml(?:.*?\?>|.*)/m) + encoder.text_token match, :preprocessor + elsif match = scan(/<\?(?:.*?\?>|.*)/m) + encoder.text_token match, :comment + elsif match = scan(/<\/[-\w.:]*>?/m) + in_tag = nil + encoder.text_token match, :tag + elsif match = scan(/<(?:(script|style)|[-\w.:]+)(>)?/m) + encoder.text_token match, :tag + in_tag = self[1] + if self[2] + state = :in_special_tag if in_tag + else + state = :attribute + end + elsif match = scan(/[^<>&]+/) + encoder.text_token match, :plain + elsif match = scan(/#{ENTITY}/ox) + encoder.text_token match, :entity + elsif match = scan(/[<>&]/) + in_tag = nil + encoder.text_token match, :error + else + raise_inspect '[BUG] else-case reached with state %p' % [state], encoder + end + + when :attribute + if match = scan(/#{TAG_END}/o) + encoder.text_token match, :tag + in_attribute = nil + if in_tag + state = :in_special_tag + else + state = :initial + end + elsif match = scan(/#{ATTR_NAME}/o) + in_attribute = IN_ATTRIBUTE[match] + encoder.text_token match, :attribute_name + state = :attribute_equal + else + in_tag = nil + encoder.text_token getch, :error + end + + when :attribute_equal + if match = scan(/=/) #/ + encoder.text_token match, :operator + state = :attribute_value + else + state = :attribute + next + end + + when :attribute_value + if match = scan(/#{ATTR_NAME}/o) + encoder.text_token match, :attribute_value + state = :attribute + elsif match = scan(/["']/) + if in_attribute == :script || in_attribute == :style + encoder.begin_group :string + encoder.text_token match, :delimiter + if scan(/javascript:[ \t]*/) + encoder.text_token matched, :comment + end + code = scan_until(match == '"' ? /(?="|\z)/ : /(?='|\z)/) + if in_attribute == :script + scan_java_script encoder, code + else + scan_css encoder, code, [:block] + end + match = scan(/["']/) + encoder.text_token match, :delimiter if match + encoder.end_group :string + state = :attribute + in_attribute = nil + else + encoder.begin_group :string + state = :attribute_value_string + plain_string_content = PLAIN_STRING_CONTENT[match] + encoder.text_token match, :delimiter + end + elsif match = scan(/#{TAG_END}/o) + encoder.text_token match, :tag + state = :initial + else + encoder.text_token getch, :error + end + + when :attribute_value_string + if match = scan(plain_string_content) + encoder.text_token match, :content + elsif match = scan(/['"]/) + encoder.text_token match, :delimiter + encoder.end_group :string + state = :attribute + elsif match = scan(/#{ENTITY}/ox) + encoder.text_token match, :entity + elsif match = scan(/&/) + encoder.text_token match, :content + elsif match = scan(/[\n>]/) + encoder.end_group :string + state = :initial + encoder.text_token match, :error + end + + when :in_special_tag + case in_tag + when 'script', 'style' + encoder.text_token match, :space if match = scan(/[ \t]*\n/) + if scan(/(\s*)|(.*))/m) + code = self[2] || self[4] + closing = self[3] + encoder.text_token self[1], :comment + else + code = scan_until(/(?=(?:\n\s*)?<\/#{in_tag}>)|\z/) + closing = false + end + unless code.empty? + encoder.begin_group :inline + if in_tag == 'script' + scan_java_script encoder, code + else + scan_css encoder, code + end + encoder.end_group :inline + end + encoder.text_token closing, :comment if closing + state = :initial + else + raise 'unknown special tag: %p' % [in_tag] + end + + else + raise_inspect 'Unknown state: %p' % [state], encoder + + end + + end + + end + + if options[:keep_state] + @state = state + @plain_string_content = plain_string_content + @in_tag = in_tag + end + + encoder.end_group :string if state == :attribute_value_string + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java.rb new file mode 100644 index 0000000..b282864 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java.rb @@ -0,0 +1,174 @@ +module CodeRay +module Scanners + + # Scanner for Java. + class Java < Scanner + + register_for :java + + autoload :BuiltinTypes, CodeRay.coderay_path('scanners', 'java', 'builtin_types') + + # http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html + KEYWORDS = %w[ + assert break case catch continue default do else + finally for if instanceof import new package + return switch throw try typeof while + debugger export + ] # :nodoc: + RESERVED = %w[ const goto ] # :nodoc: + CONSTANTS = %w[ false null true ] # :nodoc: + MAGIC_VARIABLES = %w[ this super ] # :nodoc: + TYPES = %w[ + boolean byte char class double enum float int interface long + short void + ] << '[]' # :nodoc: because int[] should be highlighted as a type + DIRECTIVES = %w[ + abstract extends final implements native private protected public + static strictfp synchronized throws transient volatile + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(RESERVED, :reserved). + add(CONSTANTS, :predefined_constant). + add(MAGIC_VARIABLES, :local_variable). + add(TYPES, :type). + add(BuiltinTypes::List, :predefined_type). + add(BuiltinTypes::List.select { |builtin| builtin[/(Error|Exception)$/] }, :exception). + add(DIRECTIVES, :directive) # :nodoc: + + ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: + STRING_CONTENT_PATTERN = { + "'" => /[^\\']+/, + '"' => /[^\\"]+/, + '/' => /[^\\\/]+/, + } # :nodoc: + IDENT = /[a-zA-Z_][A-Za-z_0-9]*/ # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + string_delimiter = nil + package_name_expected = false + class_name_follows = false + last_token_dot = false + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + encoder.text_token match, :space + next + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) + encoder.text_token match, :comment + next + + elsif package_name_expected && match = scan(/ #{IDENT} (?: \. #{IDENT} )* /ox) + encoder.text_token match, package_name_expected + + elsif match = scan(/ #{IDENT} | \[\] /ox) + kind = IDENT_KIND[match] + if last_token_dot + kind = :ident + elsif class_name_follows + kind = :class + class_name_follows = false + else + case match + when 'import' + package_name_expected = :include + when 'package' + package_name_expected = :namespace + when 'class', 'interface' + class_name_follows = true + end + end + encoder.text_token match, kind + + elsif match = scan(/ \.(?!\d) | [,?:()\[\]}] | -- | \+\+ | && | \|\| | \*\*=? | [-+*\/%^~&|<>=!]=? | <<>>?=? /x) + encoder.text_token match, :operator + + elsif match = scan(/;/) + package_name_expected = false + encoder.text_token match, :operator + + elsif match = scan(/\{/) + class_name_follows = false + encoder.text_token match, :operator + + elsif check(/[\d.]/) + if match = scan(/0[xX][0-9A-Fa-f]+/) + encoder.text_token match, :hex + elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/) + encoder.text_token match, :octal + elsif match = scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/) + encoder.text_token match, :float + elsif match = scan(/\d+[lL]?/) + encoder.text_token match, :integer + end + + elsif match = scan(/["']/) + state = :string + encoder.begin_group state + string_delimiter = match + encoder.text_token match, :delimiter + + elsif match = scan(/ @ #{IDENT} /ox) + encoder.text_token match, :annotation + + else + encoder.text_token getch, :error + + end + + when :string + if match = scan(STRING_CONTENT_PATTERN[string_delimiter]) + encoder.text_token match, :content + elsif match = scan(/["'\/]/) + encoder.text_token match, :delimiter + encoder.end_group state + state = :initial + string_delimiter = nil + elsif state == :string && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) + if string_delimiter == "'" && !(match == "\\\\" || match == "\\'") + encoder.text_token match, :content + else + encoder.text_token match, :char + end + elsif match = scan(/\\./m) + encoder.text_token match, :content + elsif match = scan(/ \\ | $ /x) + encoder.end_group state + state = :initial + encoder.text_token match, :error unless match.empty? + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + end + + else + raise_inspect 'Unknown state', encoder + + end + + last_token_dot = match == '.' + + end + + if state == :string + encoder.end_group state + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java/builtin_types.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java/builtin_types.rb new file mode 100644 index 0000000..d1b8b73 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java/builtin_types.rb @@ -0,0 +1,421 @@ +module CodeRay +module Scanners + + module Java::BuiltinTypes # :nodoc: + + #:nocov: + List = %w[ + AbstractAction AbstractBorder AbstractButton AbstractCellEditor AbstractCollection + AbstractColorChooserPanel AbstractDocument AbstractExecutorService AbstractInterruptibleChannel + AbstractLayoutCache AbstractList AbstractListModel AbstractMap AbstractMethodError AbstractPreferences + AbstractQueue AbstractQueuedSynchronizer AbstractSelectableChannel AbstractSelectionKey AbstractSelector + AbstractSequentialList AbstractSet AbstractSpinnerModel AbstractTableModel AbstractUndoableEdit + AbstractWriter AccessControlContext AccessControlException AccessController AccessException Accessible + AccessibleAction AccessibleAttributeSequence AccessibleBundle AccessibleComponent AccessibleContext + AccessibleEditableText AccessibleExtendedComponent AccessibleExtendedTable AccessibleExtendedText + AccessibleHyperlink AccessibleHypertext AccessibleIcon AccessibleKeyBinding AccessibleObject + AccessibleRelation AccessibleRelationSet AccessibleResourceBundle AccessibleRole AccessibleSelection + AccessibleState AccessibleStateSet AccessibleStreamable AccessibleTable AccessibleTableModelChange + AccessibleText AccessibleTextSequence AccessibleValue AccountException AccountExpiredException + AccountLockedException AccountNotFoundException Acl AclEntry AclNotFoundException Action ActionEvent + ActionListener ActionMap ActionMapUIResource Activatable ActivateFailedException ActivationDesc + ActivationException ActivationGroup ActivationGroupDesc ActivationGroupID ActivationGroup_Stub + ActivationID ActivationInstantiator ActivationMonitor ActivationSystem Activator ActiveEvent + ActivityCompletedException ActivityRequiredException Adjustable AdjustmentEvent AdjustmentListener + Adler32 AffineTransform AffineTransformOp AlgorithmParameterGenerator AlgorithmParameterGeneratorSpi + AlgorithmParameters AlgorithmParameterSpec AlgorithmParametersSpi AllPermission AlphaComposite + AlreadyBoundException AlreadyConnectedException AncestorEvent AncestorListener AnnotatedElement + Annotation AnnotationFormatError AnnotationTypeMismatchException AppConfigurationEntry Appendable Applet + AppletContext AppletInitializer AppletStub Arc2D Area AreaAveragingScaleFilter ArithmeticException Array + ArrayBlockingQueue ArrayIndexOutOfBoundsException ArrayList Arrays ArrayStoreException ArrayType + AssertionError AsyncBoxView AsynchronousCloseException AtomicBoolean AtomicInteger AtomicIntegerArray + AtomicIntegerFieldUpdater AtomicLong AtomicLongArray AtomicLongFieldUpdater AtomicMarkableReference + AtomicReference AtomicReferenceArray AtomicReferenceFieldUpdater AtomicStampedReference Attribute + AttributeChangeNotification AttributeChangeNotificationFilter AttributedCharacterIterator + AttributedString AttributeException AttributeInUseException AttributeList AttributeModificationException + AttributeNotFoundException Attributes AttributeSet AttributeSetUtilities AttributeValueExp AudioClip + AudioFileFormat AudioFileReader AudioFileWriter AudioFormat AudioInputStream AudioPermission AudioSystem + AuthenticationException AuthenticationNotSupportedException Authenticator AuthorizeCallback + AuthPermission AuthProvider Autoscroll AWTError AWTEvent AWTEventListener AWTEventListenerProxy + AWTEventMulticaster AWTException AWTKeyStroke AWTPermission BackingStoreException + BadAttributeValueExpException BadBinaryOpValueExpException BadLocationException BadPaddingException + BadStringOperationException BandCombineOp BandedSampleModel BaseRowSet BasicArrowButton BasicAttribute + BasicAttributes BasicBorders BasicButtonListener BasicButtonUI BasicCheckBoxMenuItemUI BasicCheckBoxUI + BasicColorChooserUI BasicComboBoxEditor BasicComboBoxRenderer BasicComboBoxUI BasicComboPopup + BasicControl BasicDesktopIconUI BasicDesktopPaneUI BasicDirectoryModel BasicEditorPaneUI + BasicFileChooserUI BasicFormattedTextFieldUI BasicGraphicsUtils BasicHTML BasicIconFactory + BasicInternalFrameTitlePane BasicInternalFrameUI BasicLabelUI BasicListUI BasicLookAndFeel + BasicMenuBarUI BasicMenuItemUI BasicMenuUI BasicOptionPaneUI BasicPanelUI BasicPasswordFieldUI + BasicPermission BasicPopupMenuSeparatorUI BasicPopupMenuUI BasicProgressBarUI BasicRadioButtonMenuItemUI + BasicRadioButtonUI BasicRootPaneUI BasicScrollBarUI BasicScrollPaneUI BasicSeparatorUI BasicSliderUI + BasicSpinnerUI BasicSplitPaneDivider BasicSplitPaneUI BasicStroke BasicTabbedPaneUI BasicTableHeaderUI + BasicTableUI BasicTextAreaUI BasicTextFieldUI BasicTextPaneUI BasicTextUI BasicToggleButtonUI + BasicToolBarSeparatorUI BasicToolBarUI BasicToolTipUI BasicTreeUI BasicViewportUI BatchUpdateException + BeanContext BeanContextChild BeanContextChildComponentProxy BeanContextChildSupport + BeanContextContainerProxy BeanContextEvent BeanContextMembershipEvent BeanContextMembershipListener + BeanContextProxy BeanContextServiceAvailableEvent BeanContextServiceProvider + BeanContextServiceProviderBeanInfo BeanContextServiceRevokedEvent BeanContextServiceRevokedListener + BeanContextServices BeanContextServicesListener BeanContextServicesSupport BeanContextSupport + BeanDescriptor BeanInfo Beans BevelBorder Bidi BigDecimal BigInteger BinaryRefAddr BindException Binding + BitSet Blob BlockingQueue BlockView BMPImageWriteParam Book Boolean BooleanControl Border BorderFactory + BorderLayout BorderUIResource BoundedRangeModel Box BoxLayout BoxView BreakIterator + BrokenBarrierException Buffer BufferCapabilities BufferedImage BufferedImageFilter BufferedImageOp + BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter BufferOverflowException + BufferStrategy BufferUnderflowException Button ButtonGroup ButtonModel ButtonUI Byte + ByteArrayInputStream ByteArrayOutputStream ByteBuffer ByteChannel ByteLookupTable ByteOrder CachedRowSet + CacheRequest CacheResponse Calendar Callable CallableStatement Callback CallbackHandler + CancelablePrintJob CancellationException CancelledKeyException CannotProceedException + CannotRedoException CannotUndoException Canvas CardLayout Caret CaretEvent CaretListener CellEditor + CellEditorListener CellRendererPane Certificate CertificateEncodingException CertificateException + CertificateExpiredException CertificateFactory CertificateFactorySpi CertificateNotYetValidException + CertificateParsingException CertPath CertPathBuilder CertPathBuilderException CertPathBuilderResult + CertPathBuilderSpi CertPathParameters CertPathTrustManagerParameters CertPathValidator + CertPathValidatorException CertPathValidatorResult CertPathValidatorSpi CertSelector CertStore + CertStoreException CertStoreParameters CertStoreSpi ChangedCharSetException ChangeEvent ChangeListener + Channel Channels Character CharacterCodingException CharacterIterator CharArrayReader CharArrayWriter + CharBuffer CharConversionException CharSequence Charset CharsetDecoder CharsetEncoder CharsetProvider + Checkbox CheckboxGroup CheckboxMenuItem CheckedInputStream CheckedOutputStream Checksum Choice + ChoiceCallback ChoiceFormat Chromaticity Cipher CipherInputStream CipherOutputStream CipherSpi Class + ClassCastException ClassCircularityError ClassDefinition ClassDesc ClassFileTransformer ClassFormatError + ClassLoader ClassLoaderRepository ClassLoadingMXBean ClassNotFoundException Clip Clipboard + ClipboardOwner Clob Cloneable CloneNotSupportedException Closeable ClosedByInterruptException + ClosedChannelException ClosedSelectorException CMMException CoderMalfunctionError CoderResult CodeSigner + CodeSource CodingErrorAction CollationElementIterator CollationKey Collator Collection + CollectionCertStoreParameters Collections Color ColorChooserComponentFactory ColorChooserUI + ColorConvertOp ColorModel ColorSelectionModel ColorSpace ColorSupported ColorType ColorUIResource + ComboBoxEditor ComboBoxModel ComboBoxUI ComboPopup CommunicationException Comparable Comparator + CompilationMXBean Compiler CompletionService Component ComponentAdapter ComponentColorModel + ComponentEvent ComponentInputMap ComponentInputMapUIResource ComponentListener ComponentOrientation + ComponentSampleModel ComponentUI ComponentView Composite CompositeContext CompositeData + CompositeDataSupport CompositeName CompositeType CompositeView CompoundBorder CompoundControl + CompoundEdit CompoundName Compression ConcurrentHashMap ConcurrentLinkedQueue ConcurrentMap + ConcurrentModificationException Condition Configuration ConfigurationException ConfirmationCallback + ConnectException ConnectIOException Connection ConnectionEvent ConnectionEventListener + ConnectionPendingException ConnectionPoolDataSource ConsoleHandler Constructor Container + ContainerAdapter ContainerEvent ContainerListener ContainerOrderFocusTraversalPolicy ContentHandler + ContentHandlerFactory ContentModel Context ContextNotEmptyException ContextualRenderedImageFactory + Control ControlFactory ControllerEventListener ConvolveOp CookieHandler Copies CopiesSupported + CopyOnWriteArrayList CopyOnWriteArraySet CountDownLatch CounterMonitor CounterMonitorMBean CRC32 + CredentialException CredentialExpiredException CredentialNotFoundException CRL CRLException CRLSelector + CropImageFilter CSS CubicCurve2D Currency Cursor Customizer CyclicBarrier DatabaseMetaData DataBuffer + DataBufferByte DataBufferDouble DataBufferFloat DataBufferInt DataBufferShort DataBufferUShort + DataFlavor DataFormatException DatagramChannel DatagramPacket DatagramSocket DatagramSocketImpl + DatagramSocketImplFactory DataInput DataInputStream DataLine DataOutput DataOutputStream DataSource + DataTruncation DatatypeConfigurationException DatatypeConstants DatatypeFactory Date DateFormat + DateFormatSymbols DateFormatter DateTimeAtCompleted DateTimeAtCreation DateTimeAtProcessing + DateTimeSyntax DebugGraphics DecimalFormat DecimalFormatSymbols DefaultBoundedRangeModel + DefaultButtonModel DefaultCaret DefaultCellEditor DefaultColorSelectionModel DefaultComboBoxModel + DefaultDesktopManager DefaultEditorKit DefaultFocusManager DefaultFocusTraversalPolicy DefaultFormatter + DefaultFormatterFactory DefaultHighlighter DefaultKeyboardFocusManager DefaultListCellRenderer + DefaultListModel DefaultListSelectionModel DefaultLoaderRepository DefaultMenuLayout DefaultMetalTheme + DefaultMutableTreeNode DefaultPersistenceDelegate DefaultSingleSelectionModel DefaultStyledDocument + DefaultTableCellRenderer DefaultTableColumnModel DefaultTableModel DefaultTextUI DefaultTreeCellEditor + DefaultTreeCellRenderer DefaultTreeModel DefaultTreeSelectionModel Deflater DeflaterOutputStream Delayed + DelayQueue DelegationPermission Deprecated Descriptor DescriptorAccess DescriptorSupport DESedeKeySpec + DesignMode DESKeySpec DesktopIconUI DesktopManager DesktopPaneUI Destination Destroyable + DestroyFailedException DGC DHGenParameterSpec DHKey DHParameterSpec DHPrivateKey DHPrivateKeySpec + DHPublicKey DHPublicKeySpec Dialog Dictionary DigestException DigestInputStream DigestOutputStream + Dimension Dimension2D DimensionUIResource DirContext DirectColorModel DirectoryManager DirObjectFactory + DirStateFactory DisplayMode DnDConstants Doc DocAttribute DocAttributeSet DocFlavor DocPrintJob Document + DocumentBuilder DocumentBuilderFactory Documented DocumentEvent DocumentFilter DocumentListener + DocumentName DocumentParser DomainCombiner DOMLocator DOMResult DOMSource Double DoubleBuffer + DragGestureEvent DragGestureListener DragGestureRecognizer DragSource DragSourceAdapter + DragSourceContext DragSourceDragEvent DragSourceDropEvent DragSourceEvent DragSourceListener + DragSourceMotionListener Driver DriverManager DriverPropertyInfo DropTarget DropTargetAdapter + DropTargetContext DropTargetDragEvent DropTargetDropEvent DropTargetEvent DropTargetListener DSAKey + DSAKeyPairGenerator DSAParameterSpec DSAParams DSAPrivateKey DSAPrivateKeySpec DSAPublicKey + DSAPublicKeySpec DTD DTDConstants DuplicateFormatFlagsException Duration DynamicMBean ECField ECFieldF2m + ECFieldFp ECGenParameterSpec ECKey ECParameterSpec ECPoint ECPrivateKey ECPrivateKeySpec ECPublicKey + ECPublicKeySpec EditorKit Element ElementIterator ElementType Ellipse2D EllipticCurve EmptyBorder + EmptyStackException EncodedKeySpec Encoder EncryptedPrivateKeyInfo Entity Enum + EnumConstantNotPresentException EnumControl Enumeration EnumMap EnumSet EnumSyntax EOFException Error + ErrorListener ErrorManager EtchedBorder Event EventContext EventDirContext EventHandler EventListener + EventListenerList EventListenerProxy EventObject EventQueue EventSetDescriptor Exception + ExceptionInInitializerError ExceptionListener Exchanger ExecutionException Executor + ExecutorCompletionService Executors ExecutorService ExemptionMechanism ExemptionMechanismException + ExemptionMechanismSpi ExpandVetoException ExportException Expression ExtendedRequest ExtendedResponse + Externalizable FactoryConfigurationError FailedLoginException FeatureDescriptor Fidelity Field + FieldPosition FieldView File FileCacheImageInputStream FileCacheImageOutputStream FileChannel + FileChooserUI FileDescriptor FileDialog FileFilter FileHandler FileImageInputStream + FileImageOutputStream FileInputStream FileLock FileLockInterruptionException FilenameFilter FileNameMap + FileNotFoundException FileOutputStream FilePermission FileReader FileSystemView FileView FileWriter + Filter FilteredImageSource FilteredRowSet FilterInputStream FilterOutputStream FilterReader FilterWriter + Finishings FixedHeightLayoutCache FlatteningPathIterator FlavorEvent FlavorException FlavorListener + FlavorMap FlavorTable Float FloatBuffer FloatControl FlowLayout FlowView Flushable FocusAdapter + FocusEvent FocusListener FocusManager FocusTraversalPolicy Font FontFormatException FontMetrics + FontRenderContext FontUIResource Format FormatConversionProvider FormatFlagsConversionMismatchException + Formattable FormattableFlags Formatter FormatterClosedException FormSubmitEvent FormView Frame Future + FutureTask GapContent GarbageCollectorMXBean GatheringByteChannel GaugeMonitor GaugeMonitorMBean + GeneralPath GeneralSecurityException GenericArrayType GenericDeclaration GenericSignatureFormatError + GlyphJustificationInfo GlyphMetrics GlyphVector GlyphView GradientPaint GraphicAttribute Graphics + Graphics2D GraphicsConfigTemplate GraphicsConfiguration GraphicsDevice GraphicsEnvironment GrayFilter + GregorianCalendar GridBagConstraints GridBagLayout GridLayout Group Guard GuardedObject GZIPInputStream + GZIPOutputStream Handler HandshakeCompletedEvent HandshakeCompletedListener HasControls HashAttributeSet + HashDocAttributeSet HashMap HashPrintJobAttributeSet HashPrintRequestAttributeSet + HashPrintServiceAttributeSet HashSet Hashtable HeadlessException HierarchyBoundsAdapter + HierarchyBoundsListener HierarchyEvent HierarchyListener Highlighter HostnameVerifier HTML HTMLDocument + HTMLEditorKit HTMLFrameHyperlinkEvent HTMLWriter HttpRetryException HttpsURLConnection HttpURLConnection + HyperlinkEvent HyperlinkListener ICC_ColorSpace ICC_Profile ICC_ProfileGray ICC_ProfileRGB Icon + IconUIResource IconView Identity IdentityHashMap IdentityScope IIOByteBuffer IIOException IIOImage + IIOInvalidTreeException IIOMetadata IIOMetadataController IIOMetadataFormat IIOMetadataFormatImpl + IIOMetadataNode IIOParam IIOParamController IIOReadProgressListener IIOReadUpdateListener + IIOReadWarningListener IIORegistry IIOServiceProvider IIOWriteProgressListener IIOWriteWarningListener + IllegalAccessError IllegalAccessException IllegalArgumentException IllegalBlockingModeException + IllegalBlockSizeException IllegalCharsetNameException IllegalClassFormatException + IllegalComponentStateException IllegalFormatCodePointException IllegalFormatConversionException + IllegalFormatException IllegalFormatFlagsException IllegalFormatPrecisionException + IllegalFormatWidthException IllegalMonitorStateException IllegalPathStateException + IllegalSelectorException IllegalStateException IllegalThreadStateException Image ImageCapabilities + ImageConsumer ImageFilter ImageGraphicAttribute ImageIcon ImageInputStream ImageInputStreamImpl + ImageInputStreamSpi ImageIO ImageObserver ImageOutputStream ImageOutputStreamImpl ImageOutputStreamSpi + ImageProducer ImageReader ImageReaderSpi ImageReaderWriterSpi ImageReadParam ImageTranscoder + ImageTranscoderSpi ImageTypeSpecifier ImageView ImageWriteParam ImageWriter ImageWriterSpi + ImagingOpException IncompatibleClassChangeError IncompleteAnnotationException IndexColorModel + IndexedPropertyChangeEvent IndexedPropertyDescriptor IndexOutOfBoundsException Inet4Address Inet6Address + InetAddress InetSocketAddress Inflater InflaterInputStream InheritableThreadLocal Inherited + InitialContext InitialContextFactory InitialContextFactoryBuilder InitialDirContext InitialLdapContext + InlineView InputContext InputEvent InputMap InputMapUIResource InputMethod InputMethodContext + InputMethodDescriptor InputMethodEvent InputMethodHighlight InputMethodListener InputMethodRequests + InputMismatchException InputStream InputStreamReader InputSubset InputVerifier Insets InsetsUIResource + InstanceAlreadyExistsException InstanceNotFoundException InstantiationError InstantiationException + Instrument Instrumentation InsufficientResourcesException IntBuffer Integer IntegerSyntax InternalError + InternalFrameAdapter InternalFrameEvent InternalFrameFocusTraversalPolicy InternalFrameListener + InternalFrameUI InternationalFormatter InterruptedException InterruptedIOException + InterruptedNamingException InterruptibleChannel IntrospectionException Introspector + InvalidActivityException InvalidAlgorithmParameterException InvalidApplicationException + InvalidAttributeIdentifierException InvalidAttributesException InvalidAttributeValueException + InvalidClassException InvalidDnDOperationException InvalidKeyException InvalidKeySpecException + InvalidMarkException InvalidMidiDataException InvalidNameException InvalidObjectException + InvalidOpenTypeException InvalidParameterException InvalidParameterSpecException + InvalidPreferencesFormatException InvalidPropertiesFormatException InvalidRelationIdException + InvalidRelationServiceException InvalidRelationTypeException InvalidRoleInfoException + InvalidRoleValueException InvalidSearchControlsException InvalidSearchFilterException + InvalidTargetObjectTypeException InvalidTransactionException InvocationEvent InvocationHandler + InvocationTargetException IOException ItemEvent ItemListener ItemSelectable Iterable Iterator + IvParameterSpec JApplet JarEntry JarException JarFile JarInputStream JarOutputStream JarURLConnection + JButton JCheckBox JCheckBoxMenuItem JColorChooser JComboBox JComponent JdbcRowSet JDesktopPane JDialog + JEditorPane JFileChooser JFormattedTextField JFrame JInternalFrame JLabel JLayeredPane JList JMenu + JMenuBar JMenuItem JMException JMRuntimeException JMXAuthenticator JMXConnectionNotification + JMXConnector JMXConnectorFactory JMXConnectorProvider JMXConnectorServer JMXConnectorServerFactory + JMXConnectorServerMBean JMXConnectorServerProvider JMXPrincipal JMXProviderException + JMXServerErrorException JMXServiceURL JobAttributes JobHoldUntil JobImpressions JobImpressionsCompleted + JobImpressionsSupported JobKOctets JobKOctetsProcessed JobKOctetsSupported JobMediaSheets + JobMediaSheetsCompleted JobMediaSheetsSupported JobMessageFromOperator JobName JobOriginatingUserName + JobPriority JobPrioritySupported JobSheets JobState JobStateReason JobStateReasons Joinable JoinRowSet + JOptionPane JPanel JPasswordField JPEGHuffmanTable JPEGImageReadParam JPEGImageWriteParam JPEGQTable + JPopupMenu JProgressBar JRadioButton JRadioButtonMenuItem JRootPane JScrollBar JScrollPane JSeparator + JSlider JSpinner JSplitPane JTabbedPane JTable JTableHeader JTextArea JTextComponent JTextField + JTextPane JToggleButton JToolBar JToolTip JTree JViewport JWindow KerberosKey KerberosPrincipal + KerberosTicket Kernel Key KeyAdapter KeyAgreement KeyAgreementSpi KeyAlreadyExistsException + KeyboardFocusManager KeyEvent KeyEventDispatcher KeyEventPostProcessor KeyException KeyFactory + KeyFactorySpi KeyGenerator KeyGeneratorSpi KeyListener KeyManagementException KeyManager + KeyManagerFactory KeyManagerFactorySpi Keymap KeyPair KeyPairGenerator KeyPairGeneratorSpi KeyRep + KeySpec KeyStore KeyStoreBuilderParameters KeyStoreException KeyStoreSpi KeyStroke Label LabelUI + LabelView LanguageCallback LastOwnerException LayeredHighlighter LayoutFocusTraversalPolicy + LayoutManager LayoutManager2 LayoutQueue LDAPCertStoreParameters LdapContext LdapName + LdapReferralException Lease Level LimitExceededException Line Line2D LineBorder LineBreakMeasurer + LineEvent LineListener LineMetrics LineNumberInputStream LineNumberReader LineUnavailableException + LinkageError LinkedBlockingQueue LinkedHashMap LinkedHashSet LinkedList LinkException LinkLoopException + LinkRef List ListCellRenderer ListDataEvent ListDataListener ListenerNotFoundException ListIterator + ListModel ListResourceBundle ListSelectionEvent ListSelectionListener ListSelectionModel ListUI ListView + LoaderHandler Locale LocateRegistry Lock LockSupport Logger LoggingMXBean LoggingPermission LoginContext + LoginException LoginModule LogManager LogRecord LogStream Long LongBuffer LookAndFeel LookupOp + LookupTable Mac MacSpi MalformedInputException MalformedLinkException MalformedObjectNameException + MalformedParameterizedTypeException MalformedURLException ManagementFactory ManagementPermission + ManageReferralControl ManagerFactoryParameters Manifest Map MappedByteBuffer MarshalException + MarshalledObject MaskFormatter Matcher MatchResult Math MathContext MatteBorder MBeanAttributeInfo + MBeanConstructorInfo MBeanException MBeanFeatureInfo MBeanInfo MBeanNotificationInfo MBeanOperationInfo + MBeanParameterInfo MBeanPermission MBeanRegistration MBeanRegistrationException MBeanServer + MBeanServerBuilder MBeanServerConnection MBeanServerDelegate MBeanServerDelegateMBean MBeanServerFactory + MBeanServerForwarder MBeanServerInvocationHandler MBeanServerNotification MBeanServerNotificationFilter + MBeanServerPermission MBeanTrustPermission Media MediaName MediaPrintableArea MediaSize MediaSizeName + MediaTracker MediaTray Member MemoryCacheImageInputStream MemoryCacheImageOutputStream MemoryHandler + MemoryImageSource MemoryManagerMXBean MemoryMXBean MemoryNotificationInfo MemoryPoolMXBean MemoryType + MemoryUsage Menu MenuBar MenuBarUI MenuComponent MenuContainer MenuDragMouseEvent MenuDragMouseListener + MenuElement MenuEvent MenuItem MenuItemUI MenuKeyEvent MenuKeyListener MenuListener MenuSelectionManager + MenuShortcut MessageDigest MessageDigestSpi MessageFormat MetaEventListener MetalBorders MetalButtonUI + MetalCheckBoxIcon MetalCheckBoxUI MetalComboBoxButton MetalComboBoxEditor MetalComboBoxIcon + MetalComboBoxUI MetalDesktopIconUI MetalFileChooserUI MetalIconFactory MetalInternalFrameTitlePane + MetalInternalFrameUI MetalLabelUI MetalLookAndFeel MetalMenuBarUI MetalPopupMenuSeparatorUI + MetalProgressBarUI MetalRadioButtonUI MetalRootPaneUI MetalScrollBarUI MetalScrollButton + MetalScrollPaneUI MetalSeparatorUI MetalSliderUI MetalSplitPaneUI MetalTabbedPaneUI MetalTextFieldUI + MetalTheme MetalToggleButtonUI MetalToolBarUI MetalToolTipUI MetalTreeUI MetaMessage Method + MethodDescriptor MGF1ParameterSpec MidiChannel MidiDevice MidiDeviceProvider MidiEvent MidiFileFormat + MidiFileReader MidiFileWriter MidiMessage MidiSystem MidiUnavailableException MimeTypeParseException + MinimalHTMLWriter MissingFormatArgumentException MissingFormatWidthException MissingResourceException + Mixer MixerProvider MLet MLetMBean ModelMBean ModelMBeanAttributeInfo ModelMBeanConstructorInfo + ModelMBeanInfo ModelMBeanInfoSupport ModelMBeanNotificationBroadcaster ModelMBeanNotificationInfo + ModelMBeanOperationInfo ModificationItem Modifier Monitor MonitorMBean MonitorNotification + MonitorSettingException MouseAdapter MouseDragGestureRecognizer MouseEvent MouseInfo MouseInputAdapter + MouseInputListener MouseListener MouseMotionAdapter MouseMotionListener MouseWheelEvent + MouseWheelListener MultiButtonUI MulticastSocket MultiColorChooserUI MultiComboBoxUI MultiDesktopIconUI + MultiDesktopPaneUI MultiDoc MultiDocPrintJob MultiDocPrintService MultiFileChooserUI + MultiInternalFrameUI MultiLabelUI MultiListUI MultiLookAndFeel MultiMenuBarUI MultiMenuItemUI + MultiOptionPaneUI MultiPanelUI MultiPixelPackedSampleModel MultipleDocumentHandling MultipleMaster + MultiPopupMenuUI MultiProgressBarUI MultiRootPaneUI MultiScrollBarUI MultiScrollPaneUI MultiSeparatorUI + MultiSliderUI MultiSpinnerUI MultiSplitPaneUI MultiTabbedPaneUI MultiTableHeaderUI MultiTableUI + MultiTextUI MultiToolBarUI MultiToolTipUI MultiTreeUI MultiViewportUI MutableAttributeSet + MutableComboBoxModel MutableTreeNode Name NameAlreadyBoundException NameCallback NameClassPair + NameNotFoundException NameParser NamespaceChangeListener NamespaceContext Naming NamingEnumeration + NamingEvent NamingException NamingExceptionEvent NamingListener NamingManager NamingSecurityException + NavigationFilter NegativeArraySizeException NetPermission NetworkInterface NoClassDefFoundError + NoConnectionPendingException NodeChangeEvent NodeChangeListener NoInitialContextException + NoninvertibleTransformException NonReadableChannelException NonWritableChannelException + NoPermissionException NoRouteToHostException NoSuchAlgorithmException NoSuchAttributeException + NoSuchElementException NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException + NoSuchObjectException NoSuchPaddingException NoSuchProviderException NotActiveException + NotBoundException NotCompliantMBeanException NotContextException Notification NotificationBroadcaster + NotificationBroadcasterSupport NotificationEmitter NotificationFilter NotificationFilterSupport + NotificationListener NotificationResult NotOwnerException NotSerializableException NotYetBoundException + NotYetConnectedException NullCipher NullPointerException Number NumberFormat NumberFormatException + NumberFormatter NumberOfDocuments NumberOfInterveningJobs NumberUp NumberUpSupported NumericShaper + OAEPParameterSpec Object ObjectChangeListener ObjectFactory ObjectFactoryBuilder ObjectInput + ObjectInputStream ObjectInputValidation ObjectInstance ObjectName ObjectOutput ObjectOutputStream + ObjectStreamClass ObjectStreamConstants ObjectStreamException ObjectStreamField ObjectView ObjID + Observable Observer OceanTheme OpenDataException OpenMBeanAttributeInfo OpenMBeanAttributeInfoSupport + OpenMBeanConstructorInfo OpenMBeanConstructorInfoSupport OpenMBeanInfo OpenMBeanInfoSupport + OpenMBeanOperationInfo OpenMBeanOperationInfoSupport OpenMBeanParameterInfo + OpenMBeanParameterInfoSupport OpenType OperatingSystemMXBean Operation OperationNotSupportedException + OperationsException Option OptionalDataException OptionPaneUI OrientationRequested OutOfMemoryError + OutputDeviceAssigned OutputKeys OutputStream OutputStreamWriter OverlappingFileLockException + OverlayLayout Override Owner Pack200 Package PackedColorModel Pageable PageAttributes + PagedResultsControl PagedResultsResponseControl PageFormat PageRanges PagesPerMinute PagesPerMinuteColor + Paint PaintContext PaintEvent Panel PanelUI Paper ParagraphView ParameterBlock ParameterDescriptor + ParameterizedType ParameterMetaData ParseException ParsePosition Parser ParserConfigurationException + ParserDelegator PartialResultException PasswordAuthentication PasswordCallback PasswordView Patch + PathIterator Pattern PatternSyntaxException PBEKey PBEKeySpec PBEParameterSpec PDLOverrideSupported + Permission PermissionCollection Permissions PersistenceDelegate PersistentMBean PhantomReference Pipe + PipedInputStream PipedOutputStream PipedReader PipedWriter PixelGrabber PixelInterleavedSampleModel + PKCS8EncodedKeySpec PKIXBuilderParameters PKIXCertPathBuilderResult PKIXCertPathChecker + PKIXCertPathValidatorResult PKIXParameters PlainDocument PlainView Point Point2D PointerInfo Policy + PolicyNode PolicyQualifierInfo Polygon PooledConnection Popup PopupFactory PopupMenu PopupMenuEvent + PopupMenuListener PopupMenuUI Port PortableRemoteObject PortableRemoteObjectDelegate + PortUnreachableException Position Predicate PreferenceChangeEvent PreferenceChangeListener Preferences + PreferencesFactory PreparedStatement PresentationDirection Principal Printable PrinterAbortException + PrinterException PrinterGraphics PrinterInfo PrinterIOException PrinterIsAcceptingJobs PrinterJob + PrinterLocation PrinterMakeAndModel PrinterMessageFromOperator PrinterMoreInfo + PrinterMoreInfoManufacturer PrinterName PrinterResolution PrinterState PrinterStateReason + PrinterStateReasons PrinterURI PrintEvent PrintException PrintGraphics PrintJob PrintJobAdapter + PrintJobAttribute PrintJobAttributeEvent PrintJobAttributeListener PrintJobAttributeSet PrintJobEvent + PrintJobListener PrintQuality PrintRequestAttribute PrintRequestAttributeSet PrintService + PrintServiceAttribute PrintServiceAttributeEvent PrintServiceAttributeListener PrintServiceAttributeSet + PrintServiceLookup PrintStream PrintWriter PriorityBlockingQueue PriorityQueue PrivateClassLoader + PrivateCredentialPermission PrivateKey PrivateMLet PrivilegedAction PrivilegedActionException + PrivilegedExceptionAction Process ProcessBuilder ProfileDataException ProgressBarUI ProgressMonitor + ProgressMonitorInputStream Properties PropertyChangeEvent PropertyChangeListener + PropertyChangeListenerProxy PropertyChangeSupport PropertyDescriptor PropertyEditor + PropertyEditorManager PropertyEditorSupport PropertyPermission PropertyResourceBundle + PropertyVetoException ProtectionDomain ProtocolException Provider ProviderException Proxy ProxySelector + PSource PSSParameterSpec PublicKey PushbackInputStream PushbackReader QName QuadCurve2D Query QueryEval + QueryExp Queue QueuedJobCount Random RandomAccess RandomAccessFile Raster RasterFormatException RasterOp + RC2ParameterSpec RC5ParameterSpec Rdn Readable ReadableByteChannel Reader ReadOnlyBufferException + ReadWriteLock RealmCallback RealmChoiceCallback Receiver Rectangle Rectangle2D RectangularShape + ReentrantLock ReentrantReadWriteLock Ref RefAddr Reference Referenceable ReferenceQueue + ReferenceUriSchemesSupported ReferralException ReflectionException ReflectPermission Refreshable + RefreshFailedException Region RegisterableService Registry RegistryHandler RejectedExecutionException + RejectedExecutionHandler Relation RelationException RelationNotFoundException RelationNotification + RelationService RelationServiceMBean RelationServiceNotRegisteredException RelationSupport + RelationSupportMBean RelationType RelationTypeNotFoundException RelationTypeSupport Remote RemoteCall + RemoteException RemoteObject RemoteObjectInvocationHandler RemoteRef RemoteServer RemoteStub + RenderableImage RenderableImageOp RenderableImageProducer RenderContext RenderedImage + RenderedImageFactory Renderer RenderingHints RepaintManager ReplicateScaleFilter RequestingUserName + RequiredModelMBean RescaleOp ResolutionSyntax Resolver ResolveResult ResourceBundle ResponseCache Result + ResultSet ResultSetMetaData Retention RetentionPolicy ReverbType RGBImageFilter RMIClassLoader + RMIClassLoaderSpi RMIClientSocketFactory RMIConnection RMIConnectionImpl RMIConnectionImpl_Stub + RMIConnector RMIConnectorServer RMIFailureHandler RMIIIOPServerImpl RMIJRMPServerImpl + RMISecurityException RMISecurityManager RMIServer RMIServerImpl RMIServerImpl_Stub + RMIServerSocketFactory RMISocketFactory Robot Role RoleInfo RoleInfoNotFoundException RoleList + RoleNotFoundException RoleResult RoleStatus RoleUnresolved RoleUnresolvedList RootPaneContainer + RootPaneUI RoundingMode RoundRectangle2D RowMapper RowSet RowSetEvent RowSetInternal RowSetListener + RowSetMetaData RowSetMetaDataImpl RowSetReader RowSetWarning RowSetWriter RSAKey RSAKeyGenParameterSpec + RSAMultiPrimePrivateCrtKey RSAMultiPrimePrivateCrtKeySpec RSAOtherPrimeInfo RSAPrivateCrtKey + RSAPrivateCrtKeySpec RSAPrivateKey RSAPrivateKeySpec RSAPublicKey RSAPublicKeySpec RTFEditorKit + RuleBasedCollator Runnable Runtime RuntimeErrorException RuntimeException RuntimeMBeanException + RuntimeMXBean RuntimeOperationsException RuntimePermission SampleModel Sasl SaslClient SaslClientFactory + SaslException SaslServer SaslServerFactory Savepoint SAXParser SAXParserFactory SAXResult SAXSource + SAXTransformerFactory Scanner ScatteringByteChannel ScheduledExecutorService ScheduledFuture + ScheduledThreadPoolExecutor Schema SchemaFactory SchemaFactoryLoader SchemaViolationException Scrollable + Scrollbar ScrollBarUI ScrollPane ScrollPaneAdjustable ScrollPaneConstants ScrollPaneLayout ScrollPaneUI + SealedObject SearchControls SearchResult SecretKey SecretKeyFactory SecretKeyFactorySpi SecretKeySpec + SecureCacheResponse SecureClassLoader SecureRandom SecureRandomSpi Security SecurityException + SecurityManager SecurityPermission Segment SelectableChannel SelectionKey Selector SelectorProvider + Semaphore SeparatorUI Sequence SequenceInputStream Sequencer SerialArray SerialBlob SerialClob + SerialDatalink SerialException Serializable SerializablePermission SerialJavaObject SerialRef + SerialStruct ServerCloneException ServerError ServerException ServerNotActiveException ServerRef + ServerRuntimeException ServerSocket ServerSocketChannel ServerSocketFactory ServiceNotFoundException + ServicePermission ServiceRegistry ServiceUI ServiceUIFactory ServiceUnavailableException Set + SetOfIntegerSyntax Severity Shape ShapeGraphicAttribute SheetCollate Short ShortBuffer + ShortBufferException ShortLookupTable ShortMessage Sides Signature SignatureException SignatureSpi + SignedObject Signer SimpleAttributeSet SimpleBeanInfo SimpleDateFormat SimpleDoc SimpleFormatter + SimpleTimeZone SimpleType SinglePixelPackedSampleModel SingleSelectionModel Size2DSyntax + SizeLimitExceededException SizeRequirements SizeSequence Skeleton SkeletonMismatchException + SkeletonNotFoundException SliderUI Socket SocketAddress SocketChannel SocketException SocketFactory + SocketHandler SocketImpl SocketImplFactory SocketOptions SocketPermission SocketSecurityException + SocketTimeoutException SoftBevelBorder SoftReference SortControl SortedMap SortedSet + SortingFocusTraversalPolicy SortKey SortResponseControl Soundbank SoundbankReader SoundbankResource + Source SourceDataLine SourceLocator SpinnerDateModel SpinnerListModel SpinnerModel SpinnerNumberModel + SpinnerUI SplitPaneUI Spring SpringLayout SQLData SQLException SQLInput SQLInputImpl SQLOutput + SQLOutputImpl SQLPermission SQLWarning SSLContext SSLContextSpi SSLEngine SSLEngineResult SSLException + SSLHandshakeException SSLKeyException SSLPeerUnverifiedException SSLPermission SSLProtocolException + SslRMIClientSocketFactory SslRMIServerSocketFactory SSLServerSocket SSLServerSocketFactory SSLSession + SSLSessionBindingEvent SSLSessionBindingListener SSLSessionContext SSLSocket SSLSocketFactory Stack + StackOverflowError StackTraceElement StandardMBean StartTlsRequest StartTlsResponse StateEdit + StateEditable StateFactory Statement StreamCorruptedException StreamHandler StreamPrintService + StreamPrintServiceFactory StreamResult StreamSource StreamTokenizer StrictMath String StringBuffer + StringBufferInputStream StringBuilder StringCharacterIterator StringContent + StringIndexOutOfBoundsException StringMonitor StringMonitorMBean StringReader StringRefAddr + StringSelection StringTokenizer StringValueExp StringWriter Stroke Struct Stub StubDelegate + StubNotFoundException Style StyleConstants StyleContext StyledDocument StyledEditorKit StyleSheet + Subject SubjectDelegationPermission SubjectDomainCombiner SupportedValuesAttribute SuppressWarnings + SwingConstants SwingPropertyChangeSupport SwingUtilities SyncFactory SyncFactoryException + SyncFailedException SynchronousQueue SyncProvider SyncProviderException SyncResolver SynthConstants + SynthContext Synthesizer SynthGraphicsUtils SynthLookAndFeel SynthPainter SynthStyle SynthStyleFactory + SysexMessage System SystemColor SystemFlavorMap TabableView TabbedPaneUI TabExpander TableCellEditor + TableCellRenderer TableColumn TableColumnModel TableColumnModelEvent TableColumnModelListener + TableHeaderUI TableModel TableModelEvent TableModelListener TableUI TableView TabSet TabStop TabularData + TabularDataSupport TabularType TagElement Target TargetDataLine TargetedNotification Templates + TemplatesHandler TextAction TextArea TextAttribute TextComponent TextEvent TextField TextHitInfo + TextInputCallback TextLayout TextListener TextMeasurer TextOutputCallback TextSyntax TextUI TexturePaint + Thread ThreadDeath ThreadFactory ThreadGroup ThreadInfo ThreadLocal ThreadMXBean ThreadPoolExecutor + Throwable Tie TileObserver Time TimeLimitExceededException TimeoutException Timer + TimerAlarmClockNotification TimerMBean TimerNotification TimerTask Timestamp TimeUnit TimeZone + TitledBorder ToolBarUI Toolkit ToolTipManager ToolTipUI TooManyListenersException Track + TransactionalWriter TransactionRequiredException TransactionRolledbackException Transferable + TransferHandler TransformAttribute Transformer TransformerConfigurationException TransformerException + TransformerFactory TransformerFactoryConfigurationError TransformerHandler Transmitter Transparency + TreeCellEditor TreeCellRenderer TreeExpansionEvent TreeExpansionListener TreeMap TreeModel + TreeModelEvent TreeModelListener TreeNode TreePath TreeSelectionEvent TreeSelectionListener + TreeSelectionModel TreeSet TreeUI TreeWillExpandListener TrustAnchor TrustManager TrustManagerFactory + TrustManagerFactorySpi Type TypeInfoProvider TypeNotPresentException Types TypeVariable UID UIDefaults + UIManager UIResource UndeclaredThrowableException UndoableEdit UndoableEditEvent UndoableEditListener + UndoableEditSupport UndoManager UnexpectedException UnicastRemoteObject UnknownError + UnknownFormatConversionException UnknownFormatFlagsException UnknownGroupException UnknownHostException + UnknownObjectException UnknownServiceException UnmappableCharacterException UnmarshalException + UnmodifiableClassException UnmodifiableSetException UnrecoverableEntryException + UnrecoverableKeyException Unreferenced UnresolvedAddressException UnresolvedPermission + UnsatisfiedLinkError UnsolicitedNotification UnsolicitedNotificationEvent + UnsolicitedNotificationListener UnsupportedAddressTypeException UnsupportedAudioFileException + UnsupportedCallbackException UnsupportedCharsetException UnsupportedClassVersionError + UnsupportedEncodingException UnsupportedFlavorException UnsupportedLookAndFeelException + UnsupportedOperationException URI URIException URIResolver URISyntax URISyntaxException URL + URLClassLoader URLConnection URLDecoder URLEncoder URLStreamHandler URLStreamHandlerFactory + UTFDataFormatException Util UtilDelegate Utilities UUID Validator ValidatorHandler ValueExp ValueHandler + ValueHandlerMultiFormat VariableHeightLayoutCache Vector VerifyError VetoableChangeListener + VetoableChangeListenerProxy VetoableChangeSupport View ViewFactory ViewportLayout ViewportUI + VirtualMachineError Visibility VMID VoiceStatus Void VolatileImage WeakHashMap WeakReference WebRowSet + WildcardType Window WindowAdapter WindowConstants WindowEvent WindowFocusListener WindowListener + WindowStateListener WrappedPlainView WritableByteChannel WritableRaster WritableRenderedImage + WriteAbortedException Writer X500Principal X500PrivateCredential X509Certificate X509CertSelector + X509CRL X509CRLEntry X509CRLSelector X509EncodedKeySpec X509ExtendedKeyManager X509Extension + X509KeyManager X509TrustManager XAConnection XADataSource XAException XAResource Xid XMLConstants + XMLDecoder XMLEncoder XMLFormatter XMLGregorianCalendar XMLParseException XmlReader XmlWriter XPath + XPathConstants XPathException XPathExpression XPathExpressionException XPathFactory + XPathFactoryConfigurationException XPathFunction XPathFunctionException XPathFunctionResolver + XPathVariableResolver ZipEntry ZipException ZipFile ZipInputStream ZipOutputStream ZoneView + ] + #:nocov: + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java_script.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java_script.rb new file mode 100644 index 0000000..9eb0a0a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/java_script.rb @@ -0,0 +1,237 @@ +module CodeRay +module Scanners + + # Scanner for JavaScript. + # + # Aliases: +ecmascript+, +ecma_script+, +javascript+ + class JavaScript < Scanner + + register_for :java_script + file_extension 'js' + + # The actual JavaScript keywords. + KEYWORDS = %w[ + break case catch continue default delete do else + finally for function if in instanceof new + return switch throw try typeof var void while with + ] # :nodoc: + PREDEFINED_CONSTANTS = %w[ + false null true undefined NaN Infinity + ] # :nodoc: + + MAGIC_VARIABLES = %w[ this arguments ] # :nodoc: arguments was introduced in JavaScript 1.4 + + KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[ + case delete in instanceof new return throw typeof with + ] # :nodoc: + + # Reserved for future use. + RESERVED_WORDS = %w[ + abstract boolean byte char class debugger double enum export extends + final float goto implements import int interface long native package + private protected public short static super synchronized throws transient + volatile + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(RESERVED_WORDS, :reserved). + add(PREDEFINED_CONSTANTS, :predefined_constant). + add(MAGIC_VARIABLES, :local_variable). + add(KEYWORDS, :keyword) # :nodoc: + + ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc: + REGEXP_ESCAPE = / [bBdDsSwW] /x # :nodoc: + STRING_CONTENT_PATTERN = { + "'" => /[^\\']+/, + '"' => /[^\\"]+/, + '/' => /[^\\\/]+/, + } # :nodoc: + KEY_CHECK_PATTERN = { + "'" => / (?> [^\\']* (?: \\. [^\\']* )* ) ' \s* : /mx, + '"' => / (?> [^\\"]* (?: \\. [^\\"]* )* ) " \s* : /mx, + } # :nodoc: + + protected + + def setup + @state = :initial + end + + def scan_tokens encoder, options + + state, string_delimiter = options[:state] || @state + if string_delimiter + encoder.begin_group state + end + + value_expected = true + key_expected = false + function_expected = false + + until eos? + + case state + + when :initial + + if match = scan(/ \s+ | \\\n /x) + value_expected = true if !value_expected && match.index(?\n) + encoder.text_token match, :space + + elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .*() ) !mx) + value_expected = true + encoder.text_token match, :comment + state = :open_multi_line_comment if self[1] + + elsif check(/\.?\d/) + key_expected = value_expected = false + if match = scan(/0[xX][0-9A-Fa-f]+/) + encoder.text_token match, :hex + elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/) + encoder.text_token match, :octal + elsif match = scan(/\d+[fF]|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/) + encoder.text_token match, :float + elsif match = scan(/\d+/) + encoder.text_token match, :integer + end + + elsif value_expected && match = scan(/<([[:alpha:]]\w*) (?: [^\/>]*\/> | .*?<\/\1>)/xim) + # TODO: scan over nested tags + xml_scanner.tokenize match, :tokens => encoder + value_expected = false + next + + elsif match = scan(/ [-+*=<>?:;,!&^|(\[{~%]+ | \.(?!\d) /x) + value_expected = true + last_operator = match[-1] + key_expected = (last_operator == ?{) || (last_operator == ?,) + function_expected = false + encoder.text_token match, :operator + + elsif match = scan(/ [)\]}]+ /x) + function_expected = key_expected = value_expected = false + encoder.text_token match, :operator + + elsif match = scan(/ [$a-zA-Z_][A-Za-z_0-9$]* /x) + kind = IDENT_KIND[match] + value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match] + # TODO: labels + if kind == :ident + if match.index(?$) # $ allowed inside an identifier + kind = :predefined + elsif function_expected + kind = :function + elsif check(/\s*[=:]\s*function\b/) + kind = :function + elsif key_expected && check(/\s*:/) + kind = :key + end + end + function_expected = (kind == :keyword) && (match == 'function') + key_expected = false + encoder.text_token match, kind + + elsif match = scan(/["']/) + if key_expected && check(KEY_CHECK_PATTERN[match]) + state = :key + else + state = :string + end + encoder.begin_group state + string_delimiter = match + encoder.text_token match, :delimiter + + elsif value_expected && (match = scan(/\//)) + encoder.begin_group :regexp + state = :regexp + string_delimiter = '/' + encoder.text_token match, :delimiter + + elsif match = scan(/ \/ /x) + value_expected = true + key_expected = false + encoder.text_token match, :operator + + else + encoder.text_token getch, :error + + end + + when :string, :regexp, :key + if match = scan(STRING_CONTENT_PATTERN[string_delimiter]) + encoder.text_token match, :content + elsif match = scan(/["'\/]/) + encoder.text_token match, :delimiter + if state == :regexp + modifiers = scan(/[gim]+/) + encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty? + end + encoder.end_group state + string_delimiter = nil + key_expected = value_expected = false + state = :initial + elsif state != :regexp && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) + if string_delimiter == "'" && !(match == "\\\\" || match == "\\'") + encoder.text_token match, :content + else + encoder.text_token match, :char + end + elsif state == :regexp && match = scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + elsif match = scan(/\\./m) + encoder.text_token match, :content + elsif match = scan(/ \\ | $ /x) + encoder.end_group state + encoder.text_token match, :error unless match.empty? + string_delimiter = nil + key_expected = value_expected = false + state = :initial + else + raise_inspect "else case #{string_delimiter} reached; %p not handled." % peek(1), encoder + end + + when :open_multi_line_comment + if match = scan(%r! .*? \*/ !mx) + state = :initial + else + match = scan(%r! .+ !mx) + end + value_expected = true + encoder.text_token match, :comment if match + + else + #:nocov: + raise_inspect 'Unknown state: %p' % [state], encoder + #:nocov: + + end + + end + + if options[:keep_state] + @state = state, string_delimiter + end + + if [:string, :regexp].include? state + encoder.end_group state + end + + encoder + end + + protected + + def reset_instance + super + @xml_scanner.reset if defined? @xml_scanner + end + + def xml_scanner + @xml_scanner ||= CodeRay.scanner :xml, :tokens => @tokens, :keep_tokens => true, :keep_state => false + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/json.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/json.rb new file mode 100644 index 0000000..b09970c --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/json.rb @@ -0,0 +1,98 @@ +module CodeRay +module Scanners + + # Scanner for JSON (JavaScript Object Notation). + class JSON < Scanner + + register_for :json + file_extension 'json' + + KINDS_NOT_LOC = [ + :float, :char, :content, :delimiter, + :error, :integer, :operator, :value, + ] # :nodoc: + + ESCAPE = / [bfnrt\\"\/] /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # :nodoc: + KEY = / (?> (?: [^\\"]+ | \\. )* ) " \s* : /x + + protected + + def setup + @state = :initial + end + + # See http://json.org/ for a definition of the JSON lexic/grammar. + def scan_tokens encoder, options + state = options[:state] || @state + + if [:string, :key].include? state + encoder.begin_group state + end + + until eos? + + case state + + when :initial + if match = scan(/ \s+ /x) + encoder.text_token match, :space + elsif match = scan(/"/) + state = check(/#{KEY}/o) ? :key : :string + encoder.begin_group state + encoder.text_token match, :delimiter + elsif match = scan(/ [:,\[{\]}] /x) + encoder.text_token match, :operator + elsif match = scan(/ true | false | null /x) + encoder.text_token match, :value + elsif match = scan(/ -? (?: 0 | [1-9]\d* ) /x) + if scan(/ \.\d+ (?:[eE][-+]?\d+)? | [eE][-+]? \d+ /x) + match << matched + encoder.text_token match, :float + else + encoder.text_token match, :integer + end + else + encoder.text_token getch, :error + end + + when :string, :key + if match = scan(/[^\\"]+/) + encoder.text_token match, :content + elsif match = scan(/"/) + encoder.text_token match, :delimiter + encoder.end_group state + state = :initial + elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + encoder.text_token match, :char + elsif match = scan(/\\./m) + encoder.text_token match, :content + elsif match = scan(/ \\ | $ /x) + encoder.end_group state + encoder.text_token match, :error unless match.empty? + state = :initial + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder + end + + else + raise_inspect 'Unknown state: %p' % [state], encoder + + end + end + + if options[:keep_state] + @state = state + end + + if [:string, :key].include? state + encoder.end_group state + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/lua.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/lua.rb new file mode 100644 index 0000000..fb1e45a --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/lua.rb @@ -0,0 +1,280 @@ +# encoding: utf-8 + +module CodeRay +module Scanners + + # Scanner for the Lua[http://lua.org] programming lanuage. + # + # The language’s complete syntax is defined in + # {the Lua manual}[http://www.lua.org/manual/5.2/manual.html], + # which is what this scanner tries to conform to. + class Lua < Scanner + + register_for :lua + file_extension 'lua' + title 'Lua' + + # Keywords used in Lua. + KEYWORDS = %w[and break do else elseif end + for function goto if in + local not or repeat return + then until while + ] + + # Constants set by the Lua core. + PREDEFINED_CONSTANTS = %w[false true nil] + + # The expressions contained in this array are parts of Lua’s `basic' + # library. Although it’s not entirely necessary to load that library, + # it is highly recommended and one would have to provide own implementations + # of some of these expressions if one does not do so. They however aren’t + # keywords, neither are they constants, but nearly predefined, so they + # get tagged as `predefined' rather than anything else. + # + # This list excludes values of form `_UPPERCASE' because the Lua manual + # requires such identifiers to be reserved by Lua anyway and they are + # highlighted directly accordingly, without the need for specific + # identifiers to be listed here. + PREDEFINED_EXPRESSIONS = %w[ + assert collectgarbage dofile error getmetatable + ipairs load loadfile next pairs pcall print + rawequal rawget rawlen rawset select setmetatable + tonumber tostring type xpcall + ] + + # Automatic token kind selection for normal words. + IDENT_KIND = CodeRay::WordList.new(:ident). + add(KEYWORDS, :keyword). + add(PREDEFINED_CONSTANTS, :predefined_constant). + add(PREDEFINED_EXPRESSIONS, :predefined) + + protected + + # Scanner initialization. + def setup + @state = :initial + @brace_depth = 0 + end + + # CodeRay entry hook. Starts parsing. + def scan_tokens(encoder, options) + state = options[:state] || @state + brace_depth = @brace_depth + num_equals = nil + + until eos? + case state + + when :initial + if match = scan(/\-\-\[\=*\[/) #--[[ long (possibly multiline) comment ]] + num_equals = match.count("=") # Number must match for comment end + encoder.begin_group(:comment) + encoder.text_token(match, :delimiter) + state = :long_comment + + elsif match = scan(/--.*$/) # --Lua comment + encoder.text_token(match, :comment) + + elsif match = scan(/\[=*\[/) # [[ long (possibly multiline) string ]] + num_equals = match.count("=") # Number must match for comment end + encoder.begin_group(:string) + encoder.text_token(match, :delimiter) + state = :long_string + + elsif match = scan(/::\s*[a-zA-Z_][a-zA-Z0-9_]+\s*::/) # ::goto_label:: + encoder.text_token(match, :label) + + elsif match = scan(/_[A-Z]+/) # _UPPERCASE are names reserved for Lua + encoder.text_token(match, :predefined) + + elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) # Normal letters (or letters followed by digits) + kind = IDENT_KIND[match] + + # Extra highlighting for entities following certain keywords + if kind == :keyword and match == "function" + state = :function_expected + elsif kind == :keyword and match == "goto" + state = :goto_label_expected + elsif kind == :keyword and match == "local" + state = :local_var_expected + end + + encoder.text_token(match, kind) + + elsif match = scan(/\{/) # Opening table brace { + encoder.begin_group(:map) + encoder.text_token(match, brace_depth >= 1 ? :inline_delimiter : :delimiter) + brace_depth += 1 + state = :map + + elsif match = scan(/\}/) # Closing table brace } + if brace_depth == 1 + brace_depth = 0 + encoder.text_token(match, :delimiter) + encoder.end_group(:map) + elsif brace_depth == 0 # Mismatched brace + encoder.text_token(match, :error) + else + brace_depth -= 1 + encoder.text_token(match, :inline_delimiter) + encoder.end_group(:map) + state = :map + end + + elsif match = scan(/["']/) # String delimiters " and ' + encoder.begin_group(:string) + encoder.text_token(match, :delimiter) + start_delim = match + state = :string + + # ↓Prefix hex number ←|→ decimal number + elsif match = scan(/-? (?:0x\h* \. \h+ (?:p[+\-]?\d+)? | \d*\.\d+ (?:e[+\-]?\d+)?)/ix) # hexadecimal constants have no E power, decimal ones no P power + encoder.text_token(match, :float) + + # ↓Prefix hex number ←|→ decimal number + elsif match = scan(/-? (?:0x\h+ (?:p[+\-]?\d+)? | \d+ (?:e[+\-]?\d+)?)/ix) # hexadecimal constants have no E power, decimal ones no P power + encoder.text_token(match, :integer) + + elsif match = scan(/[\+\-\*\/%^\#=~<>\(\)\[\]:;,] | \.(?!\d)/x) # Operators + encoder.text_token(match, :operator) + + elsif match = scan(/\s+/) # Space + encoder.text_token(match, :space) + + else # Invalid stuff. Note that Lua doesn’t accept multibyte chars outside of strings, hence these are also errors. + encoder.text_token(getch, :error) + end + + # It may be that we’re scanning a full-blown subexpression of a table + # (tables can contain full expressions in parts). + # If this is the case, return to :map scanning state. + state = :map if state == :initial && brace_depth >= 1 + + when :function_expected + if match = scan(/\(.*?\)/m) # x = function() # "Anonymous" function without explicit name + encoder.text_token(match, :operator) + state = :initial + elsif match = scan(/[a-zA-Z_] (?:[a-zA-Z0-9_\.] (?!\.\d))* [\.\:]/x) # function tbl.subtbl.foo() | function tbl:foo() # Colon only allowed as last separator + encoder.text_token(match, :ident) + elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) # function foo() + encoder.text_token(match, :function) + state = :initial + elsif match = scan(/\s+/) # Between the `function' keyword and the ident may be any amount of whitespace + encoder.text_token(match, :space) + else + encoder.text_token(getch, :error) + state = :initial + end + + when :goto_label_expected + if match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) + encoder.text_token(match, :label) + state = :initial + elsif match = scan(/\s+/) # Between the `goto' keyword and the label may be any amount of whitespace + encoder.text_token(match, :space) + else + encoder.text_token(getch, :error) + end + + when :local_var_expected + if match = scan(/function/) # local function ... + encoder.text_token(match, :keyword) + state = :function_expected + elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]*/) + encoder.text_token(match, :local_variable) + elsif match = scan(/,/) + encoder.text_token(match, :operator) + elsif match = scan(/\=/) + encoder.text_token(match, :operator) + # After encountering the equal sign, arbitrary expressions are + # allowed again, so just return to the main state for further + # parsing. + state = :initial + elsif match = scan(/\n/) + encoder.text_token(match, :space) + state = :initial + elsif match = scan(/\s+/) + encoder.text_token(match, :space) + else + encoder.text_token(getch, :error) + end + + when :long_comment + if match = scan(/.*?(?=\]={#{num_equals}}\])/m) + encoder.text_token(match, :content) + + delim = scan(/\]={#{num_equals}}\]/) + encoder.text_token(delim, :delimiter) + else # No terminator found till EOF + encoder.text_token(rest, :error) + terminate + end + encoder.end_group(:comment) + state = :initial + + when :long_string + if match = scan(/.*?(?=\]={#{num_equals}}\])/m) # Long strings do not interpret any escape sequences + encoder.text_token(match, :content) + + delim = scan(/\]={#{num_equals}}\]/) + encoder.text_token(delim, :delimiter) + else # No terminator found till EOF + encoder.text_token(rest, :error) + terminate + end + encoder.end_group(:string) + state = :initial + + when :string + if match = scan(/[^\\#{start_delim}\n]+/) # Everything except \ and the start delimiter character is string content (newlines are only allowed if preceeded by \ or \z) + encoder.text_token(match, :content) + elsif match = scan(/\\(?:['"abfnrtv\\]|z\s*|x\h\h|\d{1,3}|\n)/m) + encoder.text_token(match, :char) + elsif match = scan(Regexp.compile(start_delim)) + encoder.text_token(match, :delimiter) + encoder.end_group(:string) + state = :initial + elsif match = scan(/\n/) # Lua forbids unescaped newlines in normal non-long strings + encoder.text_token("\\n\n", :error) # Visually appealing error indicator--otherwise users may wonder whether the highlighter cannot highlight multine strings + encoder.end_group(:string) + state = :initial + else + encoder.text_token(getch, :error) + end + + when :map + if match = scan(/[,;]/) + encoder.text_token(match, :operator) + elsif match = scan(/[a-zA-Z_][a-zA-Z0-9_]* (?=\s*=)/x) + encoder.text_token(match, :key) + encoder.text_token(scan(/\s+/), :space) if check(/\s+/) + encoder.text_token(scan(/\=/), :operator) + state = :initial + elsif match = scan(/\s+/m) + encoder.text_token(match, :space) + else + # Note this clause doesn’t advance the scan pointer, it’s a kind of + # "retry with other options" (the :initial state then of course + # advances the pointer). + state = :initial + end + else + raise + end + + end + + if options[:keep_state] + @state = state + end + + encoder.end_group :string if [:string].include? state + brace_depth.times { encoder.end_group :map } + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/php.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/php.rb new file mode 100644 index 0000000..7a8d75d --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/php.rb @@ -0,0 +1,527 @@ +# encoding: utf-8 +module CodeRay +module Scanners + + load :html + + # Scanner for PHP. + # + # Original by Stefan Walk. + class PHP < Scanner + + register_for :php + file_extension 'php' + + KINDS_NOT_LOC = HTML::KINDS_NOT_LOC + + protected + + def setup + @html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true, :keep_state => true + end + + def reset_instance + super + @html_scanner.reset + end + + module Words # :nodoc: + + # according to http://www.php.net/manual/en/reserved.keywords.php + KEYWORDS = %w[ + abstract and array as break case catch class clone const continue declare default do else elseif + enddeclare endfor endforeach endif endswitch endwhile extends final for foreach function global + goto if implements interface instanceof namespace new or private protected public static switch + throw try use var while xor + cfunction old_function + ] + + TYPES = %w[ int integer float double bool boolean string array object resource ] + + LANGUAGE_CONSTRUCTS = %w[ + die echo empty exit eval include include_once isset list + require require_once return print unset + ] + + CLASSES = %w[ Directory stdClass __PHP_Incomplete_Class exception php_user_filter Closure ] + + # according to http://php.net/quickref.php on 2009-04-21; + # all functions with _ excluded (module functions) and selected additional functions + BUILTIN_FUNCTIONS = %w[ + abs acos acosh addcslashes addslashes aggregate array arsort ascii2ebcdic asin asinh asort assert atan atan2 + atanh basename bcadd bccomp bcdiv bcmod bcmul bcpow bcpowmod bcscale bcsqrt bcsub bin2hex bindec + bindtextdomain bzclose bzcompress bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite + calculhmac ceil chdir checkdate checkdnsrr chgrp chmod chop chown chr chroot clearstatcache closedir closelog + compact constant copy cos cosh count crc32 crypt current date dcgettext dcngettext deaggregate decbin dechex + decoct define defined deg2rad delete dgettext die dirname diskfreespace dl dngettext doubleval each + ebcdic2ascii echo empty end ereg eregi escapeshellarg escapeshellcmd eval exec exit exp explode expm1 extract + fclose feof fflush fgetc fgetcsv fgets fgetss file fileatime filectime filegroup fileinode filemtime fileowner + fileperms filepro filesize filetype floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv + fputs fread frenchtojd fscanf fseek fsockopen fstat ftell ftok ftruncate fwrite getallheaders getcwd getdate + getenv gethostbyaddr gethostbyname gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid + getmyuid getopt getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext + gettimeofday gettype glob gmdate gmmktime gmstrftime gregoriantojd gzclose gzcompress gzdecode gzdeflate + gzencode gzeof gzfile gzgetc gzgets gzgetss gzinflate gzopen gzpassthru gzputs gzread gzrewind gzseek gztell + gzuncompress gzwrite hash header hebrev hebrevc hexdec htmlentities htmlspecialchars hypot iconv idate + implode include intval ip2long iptcembed iptcparse isset + jddayofweek jdmonthname jdtofrench jdtogregorian jdtojewish jdtojulian jdtounix jewishtojd join jpeg2wbmp + juliantojd key krsort ksort lcfirst lchgrp lchown levenshtein link linkinfo list localeconv localtime log + log10 log1p long2ip lstat ltrim mail main max md5 metaphone mhash microtime min mkdir mktime msql natcasesort + natsort next ngettext nl2br nthmac octdec opendir openlog + ord overload pack passthru pathinfo pclose pfsockopen phpcredits phpinfo phpversion pi png2wbmp popen pos pow + prev print printf putenv quotemeta rad2deg rand range rawurldecode rawurlencode readdir readfile readgzfile + readline readlink realpath recode rename require reset rewind rewinddir rmdir round rsort rtrim scandir + serialize setcookie setlocale setrawcookie settype sha1 shuffle signeurlpaiement sin sinh sizeof sleep snmpget + snmpgetnext snmprealwalk snmpset snmpwalk snmpwalkoid sort soundex split spliti sprintf sqrt srand sscanf stat + strcasecmp strchr strcmp strcoll strcspn strftime stripcslashes stripos stripslashes stristr strlen + strnatcasecmp strnatcmp strncasecmp strncmp strpbrk strpos strptime strrchr strrev strripos strrpos strspn + strstr strtok strtolower strtotime strtoupper strtr strval substr symlink syslog system tan tanh tempnam + textdomain time tmpfile touch trim uasort ucfirst ucwords uksort umask uniqid unixtojd unlink unpack + unserialize unset urldecode urlencode usleep usort vfprintf virtual vprintf vsprintf wordwrap + array_change_key_case array_chunk array_combine array_count_values array_diff array_diff_assoc + array_diff_key array_diff_uassoc array_diff_ukey array_fill array_fill_keys array_filter array_flip + array_intersect array_intersect_assoc array_intersect_key array_intersect_uassoc array_intersect_ukey + array_key_exists array_keys array_map array_merge array_merge_recursive array_multisort array_pad + array_pop array_product array_push array_rand array_reduce array_reverse array_search array_shift + array_slice array_splice array_sum array_udiff array_udiff_assoc array_udiff_uassoc array_uintersect + array_uintersect_assoc array_uintersect_uassoc array_unique array_unshift array_values array_walk + array_walk_recursive + assert_options base_convert base64_decode base64_encode + chunk_split class_exists class_implements class_parents + count_chars debug_backtrace debug_print_backtrace debug_zval_dump + error_get_last error_log error_reporting extension_loaded + file_exists file_get_contents file_put_contents load_file + func_get_arg func_get_args func_num_args function_exists + get_browser get_called_class get_cfg_var get_class get_class_methods get_class_vars + get_current_user get_declared_classes get_declared_interfaces get_defined_constants + get_defined_functions get_defined_vars get_extension_funcs get_headers get_html_translation_table + get_include_path get_included_files get_loaded_extensions get_magic_quotes_gpc get_magic_quotes_runtime + get_meta_tags get_object_vars get_parent_class get_required_filesget_resource_type + gc_collect_cycles gc_disable gc_enable gc_enabled + halt_compiler headers_list headers_sent highlight_file highlight_string + html_entity_decode htmlspecialchars_decode + in_array include_once inclued_get_data + is_a is_array is_binary is_bool is_buffer is_callable is_dir is_double is_executable is_file is_finite + is_float is_infinite is_int is_integer is_link is_long is_nan is_null is_numeric is_object is_readable + is_real is_resource is_scalar is_soap_fault is_string is_subclass_of is_unicode is_uploaded_file + is_writable is_writeable + locale_get_default locale_set_default + number_format override_function parse_str parse_url + php_check_syntax php_ini_loaded_file php_ini_scanned_files php_logo_guid php_sapi_name + php_strip_whitespace php_uname + preg_filter preg_grep preg_last_error preg_match preg_match_all preg_quote preg_replace + preg_replace_callback preg_split print_r + require_once register_shutdown_function register_tick_function + set_error_handler set_exception_handler set_file_buffer set_include_path + set_magic_quotes_runtime set_time_limit shell_exec + str_getcsv str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split str_word_count + strip_tags substr_compare substr_count substr_replace + time_nanosleep time_sleep_until + token_get_all token_name trigger_error + unregister_tick_function use_soap_error_handler user_error + utf8_decode utf8_encode var_dump var_export + version_compare + zend_logo_guid zend_thread_id zend_version + create_function call_user_func_array + posix_access posix_ctermid posix_get_last_error posix_getcwd posix_getegid + posix_geteuid posix_getgid posix_getgrgid posix_getgrnam posix_getgroups + posix_getlogin posix_getpgid posix_getpgrp posix_getpid posix_getppid + posix_getpwnam posix_getpwuid posix_getrlimit posix_getsid posix_getuid + posix_initgroups posix_isatty posix_kill posix_mkfifo posix_mknod + posix_setegid posix_seteuid posix_setgid posix_setpgid posix_setsid + posix_setuid posix_strerror posix_times posix_ttyname posix_uname + pcntl_alarm pcntl_exec pcntl_fork pcntl_getpriority pcntl_setpriority + pcntl_signal pcntl_signal_dispatch pcntl_sigprocmask pcntl_sigtimedwait + pcntl_sigwaitinfo pcntl_wait pcntl_waitpid pcntl_wexitstatus pcntl_wifexited + pcntl_wifsignaled pcntl_wifstopped pcntl_wstopsig pcntl_wtermsig + ] + # TODO: more built-in PHP functions? + + EXCEPTIONS = %w[ + E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING + E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_DEPRECATED E_USER_DEPRECATED E_ALL E_STRICT + ] + + CONSTANTS = %w[ + null true false self parent + __LINE__ __DIR__ __FILE__ __LINE__ + __CLASS__ __NAMESPACE__ __METHOD__ __FUNCTION__ + PHP_VERSION PHP_MAJOR_VERSION PHP_MINOR_VERSION PHP_RELEASE_VERSION PHP_VERSION_ID PHP_EXTRA_VERSION PHP_ZTS + PHP_DEBUG PHP_MAXPATHLEN PHP_OS PHP_SAPI PHP_EOL PHP_INT_MAX PHP_INT_SIZE DEFAULT_INCLUDE_PATH + PEAR_INSTALL_DIR PEAR_EXTENSION_DIR PHP_EXTENSION_DIR PHP_PREFIX PHP_BINDIR PHP_LIBDIR PHP_DATADIR + PHP_SYSCONFDIR PHP_LOCALSTATEDIR PHP_CONFIG_FILE_PATH PHP_CONFIG_FILE_SCAN_DIR PHP_SHLIB_SUFFIX + PHP_OUTPUT_HANDLER_START PHP_OUTPUT_HANDLER_CONT PHP_OUTPUT_HANDLER_END + __COMPILER_HALT_OFFSET__ + EXTR_OVERWRITE EXTR_SKIP EXTR_PREFIX_SAME EXTR_PREFIX_ALL EXTR_PREFIX_INVALID EXTR_PREFIX_IF_EXISTS + EXTR_IF_EXISTS SORT_ASC SORT_DESC SORT_REGULAR SORT_NUMERIC SORT_STRING CASE_LOWER CASE_UPPER COUNT_NORMAL + COUNT_RECURSIVE ASSERT_ACTIVE ASSERT_CALLBACK ASSERT_BAIL ASSERT_WARNING ASSERT_QUIET_EVAL CONNECTION_ABORTED + CONNECTION_NORMAL CONNECTION_TIMEOUT INI_USER INI_PERDIR INI_SYSTEM INI_ALL M_E M_LOG2E M_LOG10E M_LN2 M_LN10 + M_PI M_PI_2 M_PI_4 M_1_PI M_2_PI M_2_SQRTPI M_SQRT2 M_SQRT1_2 CRYPT_SALT_LENGTH CRYPT_STD_DES CRYPT_EXT_DES + CRYPT_MD5 CRYPT_BLOWFISH DIRECTORY_SEPARATOR SEEK_SET SEEK_CUR SEEK_END LOCK_SH LOCK_EX LOCK_UN LOCK_NB + HTML_SPECIALCHARS HTML_ENTITIES ENT_COMPAT ENT_QUOTES ENT_NOQUOTES INFO_GENERAL INFO_CREDITS + INFO_CONFIGURATION INFO_MODULES INFO_ENVIRONMENT INFO_VARIABLES INFO_LICENSE INFO_ALL CREDITS_GROUP + CREDITS_GENERAL CREDITS_SAPI CREDITS_MODULES CREDITS_DOCS CREDITS_FULLPAGE CREDITS_QA CREDITS_ALL STR_PAD_LEFT + STR_PAD_RIGHT STR_PAD_BOTH PATHINFO_DIRNAME PATHINFO_BASENAME PATHINFO_EXTENSION PATH_SEPARATOR CHAR_MAX + LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_ALL LC_MESSAGES ABDAY_1 ABDAY_2 ABDAY_3 ABDAY_4 ABDAY_5 + ABDAY_6 ABDAY_7 DAY_1 DAY_2 DAY_3 DAY_4 DAY_5 DAY_6 DAY_7 ABMON_1 ABMON_2 ABMON_3 ABMON_4 ABMON_5 ABMON_6 + ABMON_7 ABMON_8 ABMON_9 ABMON_10 ABMON_11 ABMON_12 MON_1 MON_2 MON_3 MON_4 MON_5 MON_6 MON_7 MON_8 MON_9 + MON_10 MON_11 MON_12 AM_STR PM_STR D_T_FMT D_FMT T_FMT T_FMT_AMPM ERA ERA_YEAR ERA_D_T_FMT ERA_D_FMT ERA_T_FMT + ALT_DIGITS INT_CURR_SYMBOL CURRENCY_SYMBOL CRNCYSTR MON_DECIMAL_POINT MON_THOUSANDS_SEP MON_GROUPING + POSITIVE_SIGN NEGATIVE_SIGN INT_FRAC_DIGITS FRAC_DIGITS P_CS_PRECEDES P_SEP_BY_SPACE N_CS_PRECEDES + N_SEP_BY_SPACE P_SIGN_POSN N_SIGN_POSN DECIMAL_POINT RADIXCHAR THOUSANDS_SEP THOUSEP GROUPING YESEXPR NOEXPR + YESSTR NOSTR CODESET LOG_EMERG LOG_ALERT LOG_CRIT LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG LOG_KERN + LOG_USER LOG_MAIL LOG_DAEMON LOG_AUTH LOG_SYSLOG LOG_LPR LOG_NEWS LOG_UUCP LOG_CRON LOG_AUTHPRIV LOG_LOCAL0 + LOG_LOCAL1 LOG_LOCAL2 LOG_LOCAL3 LOG_LOCAL4 LOG_LOCAL5 LOG_LOCAL6 LOG_LOCAL7 LOG_PID LOG_CONS LOG_ODELAY + LOG_NDELAY LOG_NOWAIT LOG_PERROR + ] + + PREDEFINED = %w[ + $GLOBALS $_SERVER $_GET $_POST $_FILES $_REQUEST $_SESSION $_ENV + $_COOKIE $php_errormsg $HTTP_RAW_POST_DATA $http_response_header + $argc $argv + ] + + IDENT_KIND = WordList::CaseIgnoring.new(:ident). + add(KEYWORDS, :keyword). + add(TYPES, :predefined_type). + add(LANGUAGE_CONSTRUCTS, :keyword). + add(BUILTIN_FUNCTIONS, :predefined). + add(CLASSES, :predefined_constant). + add(EXCEPTIONS, :exception). + add(CONSTANTS, :predefined_constant) + + VARIABLE_KIND = WordList.new(:local_variable). + add(PREDEFINED, :predefined) + end + + module RE # :nodoc: + + PHP_START = / + ]*?language\s*=\s*"php"[^>]*?> | + ]*?language\s*=\s*'php'[^>]*?> | + <\?php\d? | + <\?(?!xml) + /xi + + PHP_END = %r! + | + \?> + !xi + + HTML_INDICATOR = / ]/i + + IDENTIFIER = 'ä'[/[[:alpha:]]/] == 'ä' ? Regexp.new('[[:alpha:]_[^\0-\177]][[:alnum:]_[^\0-\177]]*') : Regexp.new('[a-z_\x7f-\xFF][a-z0-9_\x7f-\xFF]*', true) + VARIABLE = /\$#{IDENTIFIER}/ + + OPERATOR = / + \.(?!\d)=? | # dot that is not decimal point, string concatenation + && | \|\| | # logic + :: | -> | => | # scope, member, dictionary + \\(?!\n) | # namespace + \+\+ | -- | # increment, decrement + [,;?:()\[\]{}] | # simple delimiters + [-+*\/%&|^]=? | # ordinary math, binary logic, assignment shortcuts + [~$] | # whatever + =& | # reference assignment + [=!]=?=? | <> | # comparison and assignment + <<=? | >>=? | [<>]=? # comparison and shift + /x + + end + + protected + + def scan_tokens encoder, options + + if check(RE::PHP_START) || # starts with #{RE::IDENTIFIER}/o) + encoder.begin_group :inline + encoder.text_token match, :local_variable + encoder.text_token scan(/->/), :operator + encoder.text_token scan(/#{RE::IDENTIFIER}/o), :ident + encoder.end_group :inline + elsif check(/->/) + match << scan(/->/) + encoder.text_token match, :error + else + encoder.text_token match, :local_variable + end + elsif match = scan(/\{/) + if check(/\$/) + encoder.begin_group :inline + states[-1] = [states.last, delimiter] + delimiter = nil + states.push :php_inline + encoder.text_token match, :delimiter + else + encoder.text_token match, :content + end + elsif match = scan(/\$\{#{RE::IDENTIFIER}\}/o) + encoder.text_token match, :local_variable + elsif match = scan(/\$/) + encoder.text_token match, :content + else + encoder.end_group :string + states.pop + end + + when :class_expected + if match = scan(/\s+/) + encoder.text_token match, :space + elsif match = scan(/#{RE::IDENTIFIER}/o) + encoder.text_token match, :class + states.pop + else + states.pop + end + + when :function_expected + if match = scan(/\s+/) + encoder.text_token match, :space + elsif match = scan(/&/) + encoder.text_token match, :operator + elsif match = scan(/#{RE::IDENTIFIER}/o) + encoder.text_token match, :function + states.pop + else + states.pop + end + + else + raise_inspect 'Unknown state!', encoder, states + end + + end + + while state = states.pop + encoder.end_group :string if [:sqstring, :dqstring].include? state + if state.is_a? Array + encoder.end_group :inline + encoder.end_group :string if [:sqstring, :dqstring].include? state.first + end + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/python.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/python.rb new file mode 100644 index 0000000..09c8b6e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/python.rb @@ -0,0 +1,287 @@ +module CodeRay +module Scanners + + # Scanner for Python. Supports Python 3. + # + # Based on pygments' PythonLexer, see + # http://dev.pocoo.org/projects/pygments/browser/pygments/lexers/agile.py. + class Python < Scanner + + register_for :python + file_extension 'py' + + KEYWORDS = [ + 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', + 'del', 'elif', 'else', 'except', 'finally', 'for', + 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', + 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield', + 'nonlocal', # new in Python 3 + ] # :nodoc: + + OLD_KEYWORDS = [ + 'exec', 'print', # gone in Python 3 + ] # :nodoc: + + PREDEFINED_METHODS_AND_TYPES = %w[ + __import__ abs all any apply basestring bin bool buffer + bytearray bytes callable chr classmethod cmp coerce compile + complex delattr dict dir divmod enumerate eval execfile exit + file filter float frozenset getattr globals hasattr hash hex id + input int intern isinstance issubclass iter len list locals + long map max min next object oct open ord pow property range + raw_input reduce reload repr reversed round set setattr slice + sorted staticmethod str sum super tuple type unichr unicode + vars xrange zip + ] # :nodoc: + + PREDEFINED_EXCEPTIONS = %w[ + ArithmeticError AssertionError AttributeError + BaseException DeprecationWarning EOFError EnvironmentError + Exception FloatingPointError FutureWarning GeneratorExit IOError + ImportError ImportWarning IndentationError IndexError KeyError + KeyboardInterrupt LookupError MemoryError NameError + NotImplemented NotImplementedError OSError OverflowError + OverflowWarning PendingDeprecationWarning ReferenceError + RuntimeError RuntimeWarning StandardError StopIteration + SyntaxError SyntaxWarning SystemError SystemExit TabError + TypeError UnboundLocalError UnicodeDecodeError + UnicodeEncodeError UnicodeError UnicodeTranslateError + UnicodeWarning UserWarning ValueError Warning ZeroDivisionError + ] # :nodoc: + + PREDEFINED_VARIABLES_AND_CONSTANTS = [ + 'False', 'True', 'None', # "keywords" since Python 3 + 'self', 'Ellipsis', 'NotImplemented', + ] # :nodoc: + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(OLD_KEYWORDS, :old_keyword). + add(PREDEFINED_METHODS_AND_TYPES, :predefined). + add(PREDEFINED_VARIABLES_AND_CONSTANTS, :predefined_constant). + add(PREDEFINED_EXCEPTIONS, :exception) # :nodoc: + + NAME = / [[:alpha:]_] \w* /x # :nodoc: + ESCAPE = / [abfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc: + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} | N\{[-\w ]+\} /x # :nodoc: + + OPERATOR = / + \.\.\. | # ellipsis + \.(?!\d) | # dot but not decimal point + [,;:()\[\]{}] | # simple delimiters + \/\/=? | \*\*=? | # special math + [-+*\/%&|^]=? | # ordinary math and binary logic + [~`] | # binary complement and inspection + <<=? | >>=? | [<>=]=? | != # comparison and assignment + /x # :nodoc: + + STRING_DELIMITER_REGEXP = Hash.new { |h, delimiter| + h[delimiter] = Regexp.union delimiter # :nodoc: + } + + STRING_CONTENT_REGEXP = Hash.new { |h, delimiter| + h[delimiter] = / [^\\\n]+? (?= \\ | $ | #{Regexp.escape(delimiter)} ) /x # :nodoc: + } + + DEF_NEW_STATE = WordList.new(:initial). + add(%w(def), :def_expected). + add(%w(import from), :include_expected). + add(%w(class), :class_expected) # :nodoc: + + DESCRIPTOR = / + #{NAME} + (?: \. #{NAME} )* + | \* + /x # :nodoc: + + DOCSTRING_COMING = / + [ \t]* u?r? ("""|''') + /x # :nodoc: + + protected + + def scan_tokens encoder, options + + state = :initial + string_delimiter = nil + string_raw = false + string_type = nil + docstring_coming = match?(/#{DOCSTRING_COMING}/o) + last_token_dot = false + unicode = string.respond_to?(:encoding) && string.encoding.name == 'UTF-8' + from_import_state = [] + + until eos? + + if state == :string + if match = scan(STRING_DELIMITER_REGEXP[string_delimiter]) + encoder.text_token match, :delimiter + encoder.end_group string_type + string_type = nil + state = :initial + next + elsif string_delimiter.size == 3 && match = scan(/\n/) + encoder.text_token match, :content + elsif match = scan(STRING_CONTENT_REGEXP[string_delimiter]) + encoder.text_token match, :content + elsif !string_raw && match = scan(/ \\ #{ESCAPE} /ox) + encoder.text_token match, :char + elsif match = scan(/ \\ #{UNICODE_ESCAPE} /ox) + encoder.text_token match, :char + elsif match = scan(/ \\ . /x) + encoder.text_token match, :content + elsif match = scan(/ \\ | $ /x) + encoder.end_group string_type + string_type = nil + encoder.text_token match, :error unless match.empty? + state = :initial + else + raise_inspect "else case \" reached; %p not handled." % peek(1), encoder, state + end + + elsif match = scan(/ [ \t]+ | \\?\n /x) + encoder.text_token match, :space + if match == "\n" + state = :initial if state == :include_expected + docstring_coming = true if match?(/#{DOCSTRING_COMING}/o) + end + next + + elsif match = scan(/ \# [^\n]* /mx) + encoder.text_token match, :comment + next + + elsif state == :initial + + if match = scan(/#{OPERATOR}/o) + encoder.text_token match, :operator + + elsif match = scan(/(u?r?|b)?("""|"|'''|')/i) + modifiers = self[1] + string_delimiter = self[2] + string_type = docstring_coming ? :docstring : (modifiers == 'b' ? :binary : :string) + docstring_coming = false if docstring_coming + encoder.begin_group string_type + string_raw = false + unless modifiers.empty? + string_raw = !!modifiers.index(?r) + encoder.text_token modifiers, :modifier + match = string_delimiter + end + state = :string + encoder.text_token match, :delimiter + + # TODO: backticks + + elsif match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o) + kind = IDENT_KIND[match] + # TODO: keyword arguments + kind = :ident if last_token_dot + if kind == :old_keyword + kind = check(/\(/) ? :ident : :keyword + elsif kind == :predefined && check(/ *=/) + kind = :ident + elsif kind == :keyword + state = DEF_NEW_STATE[match] + from_import_state << match.to_sym if state == :include_expected + end + encoder.text_token match, kind + + elsif match = scan(/@[a-zA-Z0-9_.]+[lL]?/) + encoder.text_token match, :decorator + + elsif match = scan(/0[xX][0-9A-Fa-f]+[lL]?/) + encoder.text_token match, :hex + + elsif match = scan(/0[bB][01]+[lL]?/) + encoder.text_token match, :binary + + elsif match = scan(/(?:\d*\.\d+|\d+\.\d*)(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+/) + if scan(/[jJ]/) + match << matched + encoder.text_token match, :imaginary + else + encoder.text_token match, :float + end + + elsif match = scan(/0[oO][0-7]+|0[0-7]+(?![89.eE])[lL]?/) + encoder.text_token match, :octal + + elsif match = scan(/\d+([lL])?/) + if self[1] == nil && scan(/[jJ]/) + match << matched + encoder.text_token match, :imaginary + else + encoder.text_token match, :integer + end + + else + encoder.text_token getch, :error + + end + + elsif state == :def_expected + state = :initial + if match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o) + encoder.text_token match, :method + else + next + end + + elsif state == :class_expected + state = :initial + if match = scan(unicode ? /#{NAME}/uo : /#{NAME}/o) + encoder.text_token match, :class + else + next + end + + elsif state == :include_expected + if match = scan(unicode ? /#{DESCRIPTOR}/uo : /#{DESCRIPTOR}/o) + if match == 'as' + encoder.text_token match, :keyword + from_import_state << :as + elsif from_import_state.first == :from && match == 'import' + encoder.text_token match, :keyword + from_import_state << :import + elsif from_import_state.last == :as + # encoder.text_token match, match[0,1][unicode ? /[[:upper:]]/u : /[[:upper:]]/] ? :class : :method + encoder.text_token match, :ident + from_import_state.pop + elsif IDENT_KIND[match] == :keyword + unscan + match = nil + state = :initial + next + else + encoder.text_token match, :include + end + elsif match = scan(/,/) + from_import_state.pop if from_import_state.last == :as + encoder.text_token match, :operator + else + from_import_state = [] + state = :initial + next + end + + else + raise_inspect 'Unknown state', encoder, state + + end + + last_token_dot = match == '.' + + end + + if state == :string + encoder.end_group string_type + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/raydebug.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/raydebug.rb new file mode 100644 index 0000000..1effdc8 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/raydebug.rb @@ -0,0 +1,75 @@ +require 'set' + +module CodeRay +module Scanners + + # = Raydebug Scanner + # + # Highlights the output of the Encoders::Debug encoder. + class Raydebug < Scanner + + register_for :raydebug + file_extension 'raydebug' + title 'CodeRay Token Dump' + + protected + + def setup + super + @known_token_kinds = TokenKinds.keys.map(&:to_s).to_set + end + + def scan_tokens encoder, options + + opened_tokens = [] + + until eos? + + if match = scan(/\s+/) + encoder.text_token match, :space + + elsif match = scan(/ (\w+) \( ( [^\)\\]* ( \\. [^\)\\]* )* ) /x) + kind = self[1] + encoder.text_token kind, :class + encoder.text_token '(', :operator + match = self[2] + unless match.empty? + if @known_token_kinds.include? kind + encoder.text_token match, kind.to_sym + else + encoder.text_token match, :plain + end + end + encoder.text_token match, :operator if match = scan(/\)/) + + elsif match = scan(/ (\w+) ([<\[]) /x) + encoder.text_token self[1], :class + if @known_token_kinds.include? self[1] + kind = self[1].to_sym + else + kind = :unknown + end + opened_tokens << kind + encoder.begin_group kind + encoder.text_token self[2], :operator + + elsif !opened_tokens.empty? && match = scan(/ [>\]] /x) + encoder.text_token match, :operator + encoder.end_group opened_tokens.pop + + else + encoder.text_token getch, :space + + end + + end + + encoder.end_group opened_tokens.pop until opened_tokens.empty? + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby.rb new file mode 100644 index 0000000..80165ca --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby.rb @@ -0,0 +1,470 @@ +module CodeRay +module Scanners + + # This scanner is really complex, since Ruby _is_ a complex language! + # + # It tries to highlight 100% of all common code, + # and 90% of strange codes. + # + # It is optimized for HTML highlighting, and is not very useful for + # parsing or pretty printing. + class Ruby < Scanner + + register_for :ruby + file_extension 'rb' + + autoload :Patterns, CodeRay.coderay_path('scanners', 'ruby', 'patterns') + autoload :StringState, CodeRay.coderay_path('scanners', 'ruby', 'string_state') + + def interpreted_string_state + StringState.new :string, true, '"' + end + + protected + + def setup + @state = :initial + end + + def scan_tokens encoder, options + state, heredocs = options[:state] || @state + heredocs = heredocs.dup if heredocs.is_a?(Array) + + if state && state.instance_of?(StringState) + encoder.begin_group state.type + end + + last_state = nil + + method_call_expected = false + value_expected = true + + inline_block_stack = nil + inline_block_curly_depth = 0 + + if heredocs + state = heredocs.shift + encoder.begin_group state.type + heredocs = nil if heredocs.empty? + end + + # def_object_stack = nil + # def_object_paren_depth = 0 + + patterns = Patterns # avoid constant lookup + + unicode = string.respond_to?(:encoding) && string.encoding.name == 'UTF-8' + + until eos? + + if state.instance_of? ::Symbol + + if match = scan(/[ \t\f\v]+/) + encoder.text_token match, :space + + elsif match = scan(/\n/) + if heredocs + unscan # heredoc scanning needs \n at start + state = heredocs.shift + encoder.begin_group state.type + heredocs = nil if heredocs.empty? + else + state = :initial if state == :undef_comma_expected + encoder.text_token match, :space + value_expected = true + end + + elsif match = scan(bol? ? / \#(!)?.* | #{patterns::RUBYDOC_OR_DATA} /ox : /\#.*/) + encoder.text_token match, self[1] ? :doctype : :comment + + elsif match = scan(/\\\n/) + if heredocs + unscan # heredoc scanning needs \n at start + encoder.text_token scan(/\\/), :space + state = heredocs.shift + encoder.begin_group state.type + heredocs = nil if heredocs.empty? + else + encoder.text_token match, :space + end + + elsif state == :initial + + # IDENTS # + if !method_call_expected && + match = scan(unicode ? /#{patterns::METHOD_NAME}/uo : + /#{patterns::METHOD_NAME}/o) + + kind = patterns::IDENT_KIND[match] + if value_expected != :colon_expected && scan(/:(?!:)/) + value_expected = true + encoder.text_token match, :key + encoder.text_token ':', :operator + else + value_expected = false + if kind == :ident + if match[/\A[A-Z]/] && !(match[/[!?]$/] || match?(/\(/)) + kind = :constant + end + elsif kind == :keyword + state = patterns::KEYWORD_NEW_STATE[match] + if patterns::KEYWORDS_EXPECTING_VALUE[match] + value_expected = match == 'when' ? :colon_expected : true + end + end + value_expected = true if !value_expected && check(/#{patterns::VALUE_FOLLOWS}/o) + encoder.text_token match, kind + end + + elsif method_call_expected && + match = scan(unicode ? /#{patterns::METHOD_AFTER_DOT}/uo : + /#{patterns::METHOD_AFTER_DOT}/o) + if method_call_expected == '::' && match[/\A[A-Z]/] && !match?(/\(/) + encoder.text_token match, :constant + else + encoder.text_token match, :ident + end + method_call_expected = false + value_expected = check(/#{patterns::VALUE_FOLLOWS}/o) + + # OPERATORS # + elsif !method_call_expected && match = scan(/ (\.(?!\.)|::) | ( \.\.\.? | ==?=? | [,\(\[\{] ) | [\)\]\}] /x) + method_call_expected = self[1] + value_expected = !method_call_expected && !!self[2] + if inline_block_stack + case match + when '{' + inline_block_curly_depth += 1 + when '}' + inline_block_curly_depth -= 1 + if inline_block_curly_depth == 0 # closing brace of inline block reached + state, inline_block_curly_depth, heredocs = inline_block_stack.pop + inline_block_stack = nil if inline_block_stack.empty? + heredocs = nil if heredocs && heredocs.empty? + encoder.text_token match, :inline_delimiter + encoder.end_group :inline + next + end + end + end + encoder.text_token match, :operator + + elsif match = scan(unicode ? /#{patterns::SYMBOL}/uo : + /#{patterns::SYMBOL}/o) + case delim = match[1] + when ?', ?" + encoder.begin_group :symbol + encoder.text_token ':', :symbol + match = delim.chr + encoder.text_token match, :delimiter + state = self.class::StringState.new :symbol, delim == ?", match + else + encoder.text_token match, :symbol + value_expected = false + end + + elsif match = scan(/ ' (?:(?>[^'\\]*) ')? | " (?:(?>[^"\\\#]*) ")? /mx) + encoder.begin_group :string + if match.size == 1 + encoder.text_token match, :delimiter + state = self.class::StringState.new :string, match == '"', match # important for streaming + else + encoder.text_token match[0,1], :delimiter + encoder.text_token match[1..-2], :content if match.size > 2 + encoder.text_token match[-1,1], :delimiter + encoder.end_group :string + value_expected = false + end + + elsif match = scan(unicode ? /#{patterns::INSTANCE_VARIABLE}/uo : + /#{patterns::INSTANCE_VARIABLE}/o) + value_expected = false + encoder.text_token match, :instance_variable + + elsif value_expected && match = scan(/\//) + encoder.begin_group :regexp + encoder.text_token match, :delimiter + state = self.class::StringState.new :regexp, true, '/' + + elsif match = scan(value_expected ? /[-+]?#{patterns::NUMERIC}/o : /#{patterns::NUMERIC}/o) + if method_call_expected + encoder.text_token match, :error + method_call_expected = false + else + encoder.text_token match, self[1] ? :float : :integer # TODO: send :hex/:octal/:binary + end + value_expected = false + + elsif match = scan(/ [-+!~^\/]=? | [:;] | [*|&]{1,2}=? | >>? /x) + value_expected = true + encoder.text_token match, :operator + + elsif value_expected && match = scan(/#{patterns::HEREDOC_OPEN}/o) + quote = self[3] + delim = self[quote ? 4 : 2] + kind = patterns::QUOTE_TO_TYPE[quote] + encoder.begin_group kind + encoder.text_token match, :delimiter + encoder.end_group kind + heredocs ||= [] # create heredocs if empty + heredocs << self.class::StringState.new(kind, quote != "'", delim, + self[1] == '-' ? :indented : :linestart) + value_expected = false + + elsif value_expected && match = scan(/#{patterns::FANCY_STRING_START}/o) + kind = patterns::FANCY_STRING_KIND[self[1]] + encoder.begin_group kind + state = self.class::StringState.new kind, patterns::FANCY_STRING_INTERPRETED[self[1]], self[2] + encoder.text_token match, :delimiter + + elsif value_expected && match = scan(/#{patterns::CHARACTER}/o) + value_expected = false + encoder.text_token match, :integer + + elsif match = scan(/ %=? | <(?:<|=>?)? | \? /x) + value_expected = match == '?' ? :colon_expected : true + encoder.text_token match, :operator + + elsif match = scan(/`/) + encoder.begin_group :shell + encoder.text_token match, :delimiter + state = self.class::StringState.new :shell, true, match + + elsif match = scan(unicode ? /#{patterns::GLOBAL_VARIABLE}/uo : + /#{patterns::GLOBAL_VARIABLE}/o) + encoder.text_token match, :global_variable + value_expected = false + + elsif match = scan(unicode ? /#{patterns::CLASS_VARIABLE}/uo : + /#{patterns::CLASS_VARIABLE}/o) + encoder.text_token match, :class_variable + value_expected = false + + elsif match = scan(/\\\z/) + encoder.text_token match, :space + + else + if method_call_expected + method_call_expected = false + next + end + unless unicode + # check for unicode + $DEBUG_BEFORE, $DEBUG = $DEBUG, false + begin + if check(/./mu).size > 1 + # seems like we should try again with unicode + unicode = true + end + rescue + # bad unicode char; use getch + ensure + $DEBUG = $DEBUG_BEFORE + end + next if unicode + end + + encoder.text_token getch, :error + + end + + if last_state + state = last_state unless state.is_a?(StringState) # otherwise, a simple 'def"' results in unclosed tokens + last_state = nil + end + + elsif state == :def_expected + if match = scan(unicode ? /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/uo : + /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/o) + encoder.text_token match, :method + state = :initial + else + last_state = :dot_expected + state = :initial + end + + elsif state == :dot_expected + if match = scan(/\.|::/) + # invalid definition + state = :def_expected + encoder.text_token match, :operator + else + state = :initial + end + + elsif state == :module_expected + if match = scan(/<#{patterns::METHOD_NAME_EX})(?!\.|::)/uo : + /(?>#{patterns::METHOD_NAME_EX})(?!\.|::)/o) + encoder.text_token match, :method + elsif match = scan(/#{patterns::SYMBOL}/o) + case delim = match[1] + when ?', ?" + encoder.begin_group :symbol + encoder.text_token ':', :symbol + match = delim.chr + encoder.text_token match, :delimiter + state = self.class::StringState.new :symbol, delim == ?", match + state.next_state = :undef_comma_expected + else + encoder.text_token match, :symbol + end + else + state = :initial + end + + elsif state == :undef_comma_expected + if match = scan(/,/) + encoder.text_token match, :operator + state = :undef_expected + else + state = :initial + end + + elsif state == :alias_expected + match = scan(unicode ? /(#{patterns::METHOD_NAME_OR_SYMBOL})([ \t]+)(#{patterns::METHOD_NAME_OR_SYMBOL})/uo : + /(#{patterns::METHOD_NAME_OR_SYMBOL})([ \t]+)(#{patterns::METHOD_NAME_OR_SYMBOL})/o) + + if match + encoder.text_token self[1], (self[1][0] == ?: ? :symbol : :method) + encoder.text_token self[2], :space + encoder.text_token self[3], (self[3][0] == ?: ? :symbol : :method) + end + state = :initial + + else + #:nocov: + raise_inspect 'Unknown state: %p' % [state], encoder + #:nocov: + end + + else # StringState + + match = scan_until(state.pattern) || scan_rest + unless match.empty? + encoder.text_token match, :content + break if eos? + end + + if state.heredoc && self[1] # end of heredoc + match = getch + match << scan_until(/$/) unless eos? + encoder.text_token match, :delimiter unless match.empty? + encoder.end_group state.type + state = state.next_state + next + end + + case match = getch + + when state.delim + if state.paren_depth + state.paren_depth -= 1 + if state.paren_depth > 0 + encoder.text_token match, :content + next + end + end + encoder.text_token match, :delimiter + if state.type == :regexp && !eos? + match = scan(/#{patterns::REGEXP_MODIFIERS}/o) + encoder.text_token match, :modifier unless match.empty? + end + encoder.end_group state.type + value_expected = false + state = state.next_state + + when '\\' + if state.interpreted + if esc = scan(/#{patterns::ESCAPE}/o) + encoder.text_token match + esc, :char + else + encoder.text_token match, :error + end + else + case esc = getch + when nil + encoder.text_token match, :content + when state.delim, '\\' + encoder.text_token match + esc, :char + else + encoder.text_token match + esc, :content + end + end + + when '#' + case peek(1) + when '{' + inline_block_stack ||= [] + inline_block_stack << [state, inline_block_curly_depth, heredocs] + value_expected = true + state = :initial + inline_block_curly_depth = 1 + encoder.begin_group :inline + encoder.text_token match + getch, :inline_delimiter + when '$', '@' + encoder.text_token match, :escape + last_state = state + state = :initial + else + #:nocov: + raise_inspect 'else-case # reached; #%p not handled' % [peek(1)], encoder + #:nocov: + end + + when state.opening_paren + state.paren_depth += 1 + encoder.text_token match, :content + + else + #:nocov + raise_inspect 'else-case " reached; %p not handled, state = %p' % [match, state], encoder + #:nocov: + + end + + end + + end + + # cleaning up + if state.is_a? StringState + encoder.end_group state.type + end + + if options[:keep_state] + if state.is_a?(StringState) && state.heredoc + (heredocs ||= []).unshift state + state = :initial + elsif heredocs && heredocs.empty? + heredocs = nil + end + @state = state, heredocs + end + + if inline_block_stack + until inline_block_stack.empty? + state, = *inline_block_stack.pop + encoder.end_group :inline + encoder.end_group state.type + end + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/patterns.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/patterns.rb new file mode 100644 index 0000000..0b36e13 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/patterns.rb @@ -0,0 +1,178 @@ +# encoding: utf-8 +module CodeRay +module Scanners + + module Ruby::Patterns # :nodoc: all + + KEYWORDS = %w[ + and def end in or unless begin + defined? ensure module redo super until + BEGIN break do next rescue then + when END case else for retry + while alias class elsif if not return + undef yield + ] + + # See http://murfy.de/ruby-constants. + PREDEFINED_CONSTANTS = %w[ + nil true false self + DATA ARGV ARGF ENV + FALSE TRUE NIL + STDERR STDIN STDOUT + TOPLEVEL_BINDING + RUBY_COPYRIGHT RUBY_DESCRIPTION RUBY_ENGINE RUBY_PATCHLEVEL + RUBY_PLATFORM RUBY_RELEASE_DATE RUBY_REVISION RUBY_VERSION + __FILE__ __LINE__ __ENCODING__ + ] + + IDENT_KIND = WordList.new(:ident). + add(KEYWORDS, :keyword). + add(PREDEFINED_CONSTANTS, :predefined_constant) + + KEYWORD_NEW_STATE = WordList.new(:initial). + add(%w[ def ], :def_expected). + add(%w[ undef ], :undef_expected). + add(%w[ alias ], :alias_expected). + add(%w[ class module ], :module_expected) + + IDENT = 'ä'[/[[:alpha:]]/] == 'ä' ? Regexp.new('[[:alpha:]_[^\0-\177]][[:alnum:]_[^\0-\177]]*') : /[^\W\d]\w*/ + + METHOD_NAME = / #{IDENT} [?!]? /ox + METHOD_NAME_OPERATOR = / + \*\*? # multiplication and power + | [-+~]@? # plus, minus, tilde with and without at sign + | [\/%&|^`] # division, modulo or format strings, and, or, xor, system + | \[\]=? # array getter and setter + | << | >> # append or shift left, shift right + | <=?>? | >=? # comparison, rocket operator + | ===? | =~ # simple equality, case equality, match + | ![~=@]? # negation with and without at sign, not-equal and not-match + /ox + METHOD_SUFFIX = / (?: [?!] | = (?![~>]|=(?!>)) ) /x + METHOD_NAME_EX = / #{IDENT} #{METHOD_SUFFIX}? | #{METHOD_NAME_OPERATOR} /ox + METHOD_AFTER_DOT = / #{IDENT} [?!]? | #{METHOD_NAME_OPERATOR} /ox + INSTANCE_VARIABLE = / @ #{IDENT} /ox + CLASS_VARIABLE = / @@ #{IDENT} /ox + OBJECT_VARIABLE = / @@? #{IDENT} /ox + GLOBAL_VARIABLE = / \$ (?: #{IDENT} | [1-9]\d* | 0\w* | [~&+`'=\/,;_.<>!@$?*":\\] | -[a-zA-Z_0-9] ) /ox + PREFIX_VARIABLE = / #{GLOBAL_VARIABLE} | #{OBJECT_VARIABLE} /ox + VARIABLE = / @?@? #{IDENT} | #{GLOBAL_VARIABLE} /ox + + QUOTE_TO_TYPE = { + '`' => :shell, + '/'=> :regexp, + } + QUOTE_TO_TYPE.default = :string + + REGEXP_MODIFIERS = /[mousenix]*/ + + DECIMAL = /\d+(?:_\d+)*/ + OCTAL = /0_?[0-7]+(?:_[0-7]+)*/ + HEXADECIMAL = /0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/ + BINARY = /0b[01]+(?:_[01]+)*/ + + EXPONENT = / [eE] [+-]? #{DECIMAL} /ox + FLOAT_SUFFIX = / #{EXPONENT} | \. #{DECIMAL} #{EXPONENT}? /ox + FLOAT_OR_INT = / #{DECIMAL} (?: #{FLOAT_SUFFIX} () )? /ox + NUMERIC = / (?: (?=0) (?: #{OCTAL} | #{HEXADECIMAL} | #{BINARY} ) | #{FLOAT_OR_INT} ) /ox + + SYMBOL = / + : + (?: + #{METHOD_NAME_EX} + | #{PREFIX_VARIABLE} + | ['"] + ) + /ox + METHOD_NAME_OR_SYMBOL = / #{METHOD_NAME_EX} | #{SYMBOL} /ox + + SIMPLE_ESCAPE = / + [abefnrstv] + | [0-7]{1,3} + | x[0-9A-Fa-f]{1,2} + | . + /mx + + CONTROL_META_ESCAPE = / + (?: M-|C-|c ) + (?: \\ (?: M-|C-|c ) )* + (?: [^\\] | \\ #{SIMPLE_ESCAPE} )? + /mox + + ESCAPE = / + #{CONTROL_META_ESCAPE} | #{SIMPLE_ESCAPE} + /mox + + CHARACTER = / + \? + (?: + [^\s\\] + | \\ #{ESCAPE} + ) + /mox + + # NOTE: This is not completely correct, but + # nobody needs heredoc delimiters ending with \n. + HEREDOC_OPEN = / + << (-)? # $1 = float + (?: + ( [A-Za-z_0-9]+ ) # $2 = delim + | + ( ["'`\/] ) # $3 = quote, type + ( [^\n]*? ) \3 # $4 = delim + ) + /mx + + RUBYDOC = / + =begin (?!\S) + .*? + (?: \Z | ^=end (?!\S) [^\n]* ) + /mx + + DATA = / + __END__$ + .*? + (?: \Z | (?=^\#CODE) ) + /mx + + RUBYDOC_OR_DATA = / #{RUBYDOC} | #{DATA} /xo + + # Checks for a valid value to follow. This enables + # value_expected in method calls without parentheses. + VALUE_FOLLOWS = / + (?>[ \t\f\v]+) + (?: + [%\/][^\s=] + | <<-?\S + | [-+] \d + | #{CHARACTER} + ) + /ox + KEYWORDS_EXPECTING_VALUE = WordList.new.add(%w[ + and end in or unless begin + defined? ensure redo super until + break do next rescue then + when case else for retry + while elsif if not return + yield + ]) + + FANCY_STRING_START = / % ( [iIqQrswWx] | (?![a-zA-Z0-9]) ) ([^a-zA-Z0-9]) /x + FANCY_STRING_KIND = Hash.new(:string).merge({ + 'i' => :symbol, + 'I' => :symbol, + 'r' => :regexp, + 's' => :symbol, + 'x' => :shell, + }) + FANCY_STRING_INTERPRETED = Hash.new(true).merge({ + 'i' => false, + 'q' => false, + 's' => false, + 'w' => false, + }) + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/string_state.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/string_state.rb new file mode 100644 index 0000000..28ddd6c --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/ruby/string_state.rb @@ -0,0 +1,71 @@ +# encoding: utf-8 +module CodeRay +module Scanners + + class Ruby + + class StringState < Struct.new :type, :interpreted, :delim, :heredoc, + :opening_paren, :paren_depth, :pattern, :next_state # :nodoc: all + + CLOSING_PAREN = Hash[ *%w[ + ( ) + [ ] + < > + { } + ] ].each { |k,v| k.freeze; v.freeze } # debug, if I try to change it with << + + STRING_PATTERN = Hash.new do |h, k| + delim, interpreted = *k + delim_pattern = Regexp.escape(delim) + if closing_paren = CLOSING_PAREN[delim] + delim_pattern << Regexp.escape(closing_paren) + end + delim_pattern << '\\\\' unless delim == '\\' + + # special_escapes = + # case interpreted + # when :regexp_symbols + # '| [|?*+(){}\[\].^$]' + # end + + if interpreted && delim != '#' + / (?= [#{delim_pattern}] | \# [{$@] ) /mx + else + / (?= [#{delim_pattern}] ) /mx + end.tap do |pattern| + h[k] = pattern if (delim.respond_to?(:ord) ? delim.ord : delim[0]) < 256 + end + end + + def initialize kind, interpreted, delim, heredoc = false + if heredoc + pattern = heredoc_pattern delim, interpreted, heredoc == :indented + delim = nil + else + pattern = STRING_PATTERN[ [delim, interpreted] ] + if closing_paren = CLOSING_PAREN[delim] + opening_paren = delim + delim = closing_paren + paren_depth = 1 + end + end + super kind, interpreted, delim, heredoc, opening_paren, paren_depth, pattern, :initial + end + + def heredoc_pattern delim, interpreted, indented + # delim = delim.dup # workaround for old Ruby + delim_pattern = Regexp.escape(delim) + delim_pattern = / (?:\A|\n) #{ '(?>[ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x + if interpreted + / (?= #{delim_pattern}() | \\ | \# [{$@] ) /mx # $1 set == end of heredoc + else + / (?= #{delim_pattern}() | \\ ) /mx + end + end + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sass.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sass.rb new file mode 100644 index 0000000..e3296b9 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sass.rb @@ -0,0 +1,232 @@ +module CodeRay +module Scanners + + # A scanner for Sass. + class Sass < CSS + + register_for :sass + file_extension 'sass' + + protected + + def setup + @state = :initial + end + + def scan_tokens encoder, options + states = Array(options[:state] || @state).dup + + encoder.begin_group :string if states.last == :sqstring || states.last == :dqstring + + until eos? + + if bol? && (match = scan(/(?>( +)?(\/[\*\/])(.+)?)(?=\n)/)) + encoder.text_token self[1], :space if self[1] + encoder.begin_group :comment + encoder.text_token self[2], :delimiter + encoder.text_token self[3], :content if self[3] + if match = scan(/(?:\n+#{self[1]} .*)+/) + encoder.text_token match, :content + end + encoder.end_group :comment + elsif match = scan(/\n|[^\n\S]+\n?/) + encoder.text_token match, :space + if match.index(/\n/) + value_expected = false + states.pop if states.last == :include + end + + elsif states.last == :sass_inline && (match = scan(/\}/)) + encoder.text_token match, :inline_delimiter + encoder.end_group :inline + states.pop + + elsif case states.last + when :initial, :media, :sass_inline + if match = scan(/(?>#{RE::Ident})(?!\()/ox) + encoder.text_token match, value_expected ? :value : (check(/.*:(?![a-z])/) ? :key : :tag) + next + elsif !value_expected && (match = scan(/\*/)) + encoder.text_token match, :tag + next + elsif match = scan(RE::Class) + encoder.text_token match, :class + next + elsif match = scan(RE::Id) + encoder.text_token match, :id + next + elsif match = scan(RE::PseudoClass) + encoder.text_token match, :pseudo_class + next + elsif match = scan(RE::AttributeSelector) + # TODO: Improve highlighting inside of attribute selectors. + encoder.text_token match[0,1], :operator + encoder.text_token match[1..-2], :attribute_name if match.size > 2 + encoder.text_token match[-1,1], :operator if match[-1] == ?] + next + elsif match = scan(/(\=|@mixin +)#{RE::Ident}/o) + encoder.text_token match, :function + next + elsif match = scan(/@import\b/) + encoder.text_token match, :directive + states << :include + next + elsif match = scan(/@media\b/) + encoder.text_token match, :directive + # states.push :media_before_name + next + end + + when :block + if match = scan(/(?>#{RE::Ident})(?!\()/ox) + if value_expected + encoder.text_token match, :value + else + encoder.text_token match, :key + end + next + end + + when :sqstring, :dqstring + if match = scan(states.last == :sqstring ? /(?:[^\n\'\#]+|\\\n|#{RE::Escape}|#(?!\{))+/o : /(?:[^\n\"\#]+|\\\n|#{RE::Escape}|#(?!\{))+/o) + encoder.text_token match, :content + elsif match = scan(/['"]/) + encoder.text_token match, :delimiter + encoder.end_group :string + states.pop + elsif match = scan(/#\{/) + encoder.begin_group :inline + encoder.text_token match, :inline_delimiter + states.push :sass_inline + elsif match = scan(/ \\ | $ /x) + encoder.end_group states.last + encoder.text_token match, :error unless match.empty? + states.pop + else + raise_inspect "else case #{states.last} reached; %p not handled." % peek(1), encoder + end + + when :include + if match = scan(/[^\s'",]+/) + encoder.text_token match, :include + next + end + + else + #:nocov: + raise_inspect 'Unknown state: %p' % [states.last], encoder + #:nocov: + + end + + elsif match = scan(/\$#{RE::Ident}/o) + encoder.text_token match, :variable + next + + elsif match = scan(/&/) + encoder.text_token match, :local_variable + + elsif match = scan(/\+#{RE::Ident}/o) + encoder.text_token match, :include + value_expected = true + + elsif match = scan(/\/\*(?:.*?\*\/|.*)|\/\/.*/) + encoder.text_token match, :comment + + elsif match = scan(/#\{/) + encoder.begin_group :inline + encoder.text_token match, :inline_delimiter + states.push :sass_inline + + elsif match = scan(/\{/) + value_expected = false + encoder.text_token match, :operator + states.push :block + + elsif match = scan(/\}/) + value_expected = false + encoder.text_token match, :operator + if states.last == :block || states.last == :media + states.pop + end + + elsif match = scan(/['"]/) + encoder.begin_group :string + encoder.text_token match, :delimiter + if states.include? :sass_inline + # no nesting, just scan the string until delimiter + content = scan_until(/(?=#{match}|\}|\z)/) + encoder.text_token content, :content unless content.empty? + encoder.text_token match, :delimiter if scan(/#{match}/) + encoder.end_group :string + else + states.push match == "'" ? :sqstring : :dqstring + end + + elsif match = scan(/#{RE::Function}/o) + encoder.begin_group :function + start = match[/^[-\w]+\(/] + encoder.text_token start, :delimiter + if match[-1] == ?) + encoder.text_token match[start.size..-2], :content + encoder.text_token ')', :delimiter + else + encoder.text_token match[start.size..-1], :content if start.size < match.size + end + encoder.end_group :function + + elsif match = scan(/[a-z][-a-z_]*(?=\()/o) + encoder.text_token match, :predefined + + elsif match = scan(/(?: #{RE::Dimension} | #{RE::Percentage} | #{RE::Num} )/ox) + encoder.text_token match, :float + + elsif match = scan(/#{RE::HexColor}/o) + encoder.text_token match, :color + + elsif match = scan(/! *(?:important|optional)/) + encoder.text_token match, :important + + elsif match = scan(/(?:rgb|hsl)a?\([^()\n]*\)?/) + encoder.text_token match, :color + + elsif match = scan(/@else if\b|#{RE::AtKeyword}/o) + encoder.text_token match, :directive + value_expected = true + + elsif match = scan(/ == | != | [-+*\/>~:;,.=()] /x) + if match == ':' + value_expected = true + elsif match == ';' + value_expected = false + end + encoder.text_token match, :operator + + else + encoder.text_token getch, :error + + end + + end + + states.pop if states.last == :include + + if options[:keep_state] + @state = states.dup + end + + while state = states.pop + if state == :sass_inline + encoder.end_group :inline + elsif state == :sqstring || state == :dqstring + encoder.end_group :string + end + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sql.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sql.rb new file mode 100644 index 0000000..93aeaf3 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/sql.rb @@ -0,0 +1,177 @@ +module CodeRay +module Scanners + + # by Josh Goebel + class SQL < Scanner + + register_for :sql + + KEYWORDS = %w( + all and any as before begin between by case check collate + each else end exists + for foreign from full group having if in inner is join + like not of on or order outer over references + then to union using values when where + left right distinct + ) + + OBJECTS = %w( + database databases table tables column columns fields index constraint + constraints transaction function procedure row key view trigger + ) + + COMMANDS = %w( + add alter comment create delete drop grant insert into select update set + show prompt begin commit rollback replace truncate + ) + + PREDEFINED_TYPES = %w( + char varchar varchar2 enum binary text tinytext mediumtext + longtext blob tinyblob mediumblob longblob timestamp + date time datetime year double decimal float int + integer tinyint mediumint bigint smallint unsigned bit + bool boolean hex bin oct + ) + + PREDEFINED_FUNCTIONS = %w( sum cast substring abs pi count min max avg now ) + + DIRECTIVES = %w( + auto_increment unique default charset initially deferred + deferrable cascade immediate read write asc desc after + primary foreign return engine + ) + + PREDEFINED_CONSTANTS = %w( null true false ) + + IDENT_KIND = WordList::CaseIgnoring.new(:ident). + add(KEYWORDS, :keyword). + add(OBJECTS, :type). + add(COMMANDS, :class). + add(PREDEFINED_TYPES, :predefined_type). + add(PREDEFINED_CONSTANTS, :predefined_constant). + add(PREDEFINED_FUNCTIONS, :predefined). + add(DIRECTIVES, :directive) + + ESCAPE = / [rbfntv\n\\\/'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} | . /mx + UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x + + STRING_PREFIXES = /[xnb]|_\w+/i + + def scan_tokens encoder, options + + state = :initial + string_type = nil + string_content = '' + name_expected = false + + until eos? + + if state == :initial + + if match = scan(/ \s+ | \\\n /x) + encoder.text_token match, :space + + elsif match = scan(/(?:--\s?|#).*/) + encoder.text_token match, :comment + + elsif match = scan(%r( /\* (!)? (?: .*? \*/ | .* ) )mx) + encoder.text_token match, self[1] ? :directive : :comment + + elsif match = scan(/ [*\/=<>:;,!&^|()\[\]{}~%] | [-+\.](?!\d) /x) + name_expected = true if match == '.' && check(/[A-Za-z_]/) + encoder.text_token match, :operator + + elsif match = scan(/(#{STRING_PREFIXES})?([`"'])/o) + prefix = self[1] + string_type = self[2] + encoder.begin_group :string + encoder.text_token prefix, :modifier if prefix + match = string_type + state = :string + encoder.text_token match, :delimiter + + elsif match = scan(/ @? [A-Za-z_][A-Za-z_0-9]* /x) + encoder.text_token match, name_expected ? :ident : (match[0] == ?@ ? :variable : IDENT_KIND[match]) + name_expected = false + + elsif match = scan(/0[xX][0-9A-Fa-f]+/) + encoder.text_token match, :hex + + elsif match = scan(/0[0-7]+(?![89.eEfF])/) + encoder.text_token match, :octal + + elsif match = scan(/[-+]?(?>\d+)(?![.eEfF])/) + encoder.text_token match, :integer + + elsif match = scan(/[-+]?(?:\d[fF]|\d*\.\d+(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+)/) + encoder.text_token match, :float + + elsif match = scan(/\\N/) + encoder.text_token match, :predefined_constant + + else + encoder.text_token getch, :error + + end + + elsif state == :string + if match = scan(/[^\\"'`]+/) + string_content << match + next + elsif match = scan(/["'`]/) + if string_type == match + if peek(1) == string_type # doubling means escape + string_content << string_type << getch + next + end + unless string_content.empty? + encoder.text_token string_content, :content + string_content = '' + end + encoder.text_token match, :delimiter + encoder.end_group :string + state = :initial + string_type = nil + else + string_content << match + end + elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox) + unless string_content.empty? + encoder.text_token string_content, :content + string_content = '' + end + encoder.text_token match, :char + elsif match = scan(/ \\ . /mox) + string_content << match + next + elsif match = scan(/ \\ | $ /x) + unless string_content.empty? + encoder.text_token string_content, :content + string_content = '' + end + encoder.text_token match, :error unless match.empty? + encoder.end_group :string + state = :initial + else + raise "else case \" reached; %p not handled." % peek(1), encoder + end + + else + raise 'else-case reached', encoder + + end + + end + + if state == :string + encoder.end_group state + end + + encoder + + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/taskpaper.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/taskpaper.rb new file mode 100644 index 0000000..42670bc --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/taskpaper.rb @@ -0,0 +1,36 @@ +module CodeRay +module Scanners + + class Taskpaper < Scanner + + register_for :taskpaper + file_extension 'taskpaper' + + protected + + def scan_tokens encoder, options + until eos? + if match = scan(/\S.*:.*$/) # project + encoder.text_token(match, :namespace) + elsif match = scan(/-.+@done.*/) # completed task + encoder.text_token(match, :done) + elsif match = scan(/-(?:[^@\n]+|@(?!due))*/) # task + encoder.text_token(match, :plain) + elsif match = scan(/@due.*/) # comment + encoder.text_token(match, :important) + elsif match = scan(/.+/) # comment + encoder.text_token(match, :comment) + elsif match = scan(/\s+/) # space + encoder.text_token(match, :space) + else # other + encoder.text_token getch, :error + end + end + + encoder + end + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/text.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/text.rb new file mode 100644 index 0000000..bde9029 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/text.rb @@ -0,0 +1,26 @@ +module CodeRay + module Scanners + + # Scanner for plain text. + # + # Yields just one token of the kind :plain. + # + # Alias: +plaintext+, +plain+ + class Text < Scanner + + register_for :text + title 'Plain text' + + KINDS_NOT_LOC = [:plain] # :nodoc: + + protected + + def scan_tokens encoder, options + encoder.text_token string, :plain + encoder + end + + end + + end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/xml.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/xml.rb new file mode 100644 index 0000000..947f16e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/xml.rb @@ -0,0 +1,17 @@ +module CodeRay +module Scanners + + load :html + + # Scanner for XML. + # + # Currently this is the same scanner as Scanners::HTML. + class XML < HTML + + register_for :xml + file_extension 'xml' + + end + +end +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/yaml.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/yaml.rb new file mode 100644 index 0000000..32c8e2c --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/scanners/yaml.rb @@ -0,0 +1,140 @@ +module CodeRay +module Scanners + + # Scanner for YAML. + # + # Based on the YAML scanner from Syntax by Jamis Buck. + class YAML < Scanner + + register_for :yaml + file_extension 'yml' + + KINDS_NOT_LOC = :all + + protected + + def scan_tokens encoder, options + + state = :initial + key_indent = string_indent = 0 + + until eos? + + key_indent = nil if bol? + + if match = scan(/ +[\t ]*/) + encoder.text_token match, :space + + elsif match = scan(/\n+/) + encoder.text_token match, :space + state = :initial if match.index(?\n) + + elsif match = scan(/#.*/) + encoder.text_token match, :comment + + elsif bol? and case + when match = scan(/---|\.\.\./) + encoder.begin_group :head + encoder.text_token match, :head + encoder.end_group :head + next + when match = scan(/%.*/) + encoder.text_token match, :doctype + next + end + + elsif state == :value and case + when !check(/(?:"[^"]*")(?=: |:$)/) && match = scan(/"/) + encoder.begin_group :string + encoder.text_token match, :delimiter + encoder.text_token match, :content if (match = scan(/ [^"\\]* (?: \\. [^"\\]* )* /mx)) && !match.empty? + encoder.text_token match, :delimiter if match = scan(/"/) + encoder.end_group :string + next + when match = scan(/[|>][-+]?/) + encoder.begin_group :string + encoder.text_token match, :delimiter + string_indent = key_indent || column(pos - match.size) - 1 + encoder.text_token matched, :content if scan(/(?:\n+ {#{string_indent + 1}}.*)+/) + encoder.end_group :string + next + when match = scan(/(?![!"*&]).+?(?=$|\s+#)/) + encoder.begin_group :string + encoder.text_token match, :content + string_indent = key_indent || column(pos - match.size) - 1 + encoder.text_token matched, :content if scan(/(?:\n+ {#{string_indent + 1}}.*)+/) + encoder.end_group :string + next + end + + elsif case + when match = scan(/[-:](?= |$)/) + state = :value if state == :colon && (match == ':' || match == '-') + state = :value if state == :initial && match == '-' + encoder.text_token match, :operator + next + when match = scan(/[,{}\[\]]/) + encoder.text_token match, :operator + next + when state == :initial && match = scan(/[-\w.()\/ ]*\S(?= *:(?: |$))/) + encoder.text_token match, :key + key_indent = column(pos - match.size) - 1 + state = :colon + next + when match = scan(/(?:"[^"\n]*"|'[^'\n]*')(?= *:(?: |$))/) + encoder.begin_group :key + encoder.text_token match[0,1], :delimiter + encoder.text_token match[1..-2], :content if match.size > 2 + encoder.text_token match[-1,1], :delimiter + encoder.end_group :key + key_indent = column(pos - match.size) - 1 + state = :colon + next + when match = scan(/(![\w\/]+)(:([\w:]+))?/) + encoder.text_token self[1], :type + if self[2] + encoder.text_token ':', :operator + encoder.text_token self[3], :class + end + next + when match = scan(/&\S+/) + encoder.text_token match, :variable + next + when match = scan(/\*\w+/) + encoder.text_token match, :global_variable + next + when match = scan(/< 'debug', # highlight for debugging (white on blue background) + + :annotation => 'annotation', # Groovy, Java + :attribute_name => 'attribute-name', # HTML, CSS + :attribute_value => 'attribute-value', # HTML + :binary => 'binary', # Python, Ruby + :char => 'char', # most scanners, also inside of strings + :class => 'class', # lots of scanners, for different purposes also in CSS + :class_variable => 'class-variable', # Ruby, YAML + :color => 'color', # CSS + :comment => 'comment', # most scanners + :constant => 'constant', # PHP, Ruby + :content => 'content', # inside of strings, most scanners + :decorator => 'decorator', # Python + :definition => 'definition', # CSS + :delimiter => 'delimiter', # inside strings, comments and other types + :directive => 'directive', # lots of scanners + :doctype => 'doctype', # Goorvy, HTML, Ruby, YAML + :docstring => 'docstring', # Python + :done => 'done', # Taskpaper + :entity => 'entity', # HTML + :error => 'error', # invalid token, most scanners + :escape => 'escape', # Ruby (string inline variables like #$foo, #@bar) + :exception => 'exception', # Java, PHP, Python + :filename => 'filename', # Diff + :float => 'float', # most scanners + :function => 'function', # CSS, JavaScript, PHP + :global_variable => 'global-variable', # Ruby, YAML + :hex => 'hex', # hexadecimal number; lots of scanners + :id => 'id', # CSS + :imaginary => 'imaginary', # Python + :important => 'important', # CSS, Taskpaper + :include => 'include', # C, Groovy, Java, Python, Sass + :inline => 'inline', # nested code, eg. inline string evaluation; lots of scanners + :inline_delimiter => 'inline-delimiter', # used instead of :inline > :delimiter FIXME: Why use inline_delimiter? + :instance_variable => 'instance-variable', # Ruby + :integer => 'integer', # most scanners + :key => 'key', # lots of scanners, used together with :value + :keyword => 'keyword', # reserved word that's actually implemented; most scanners + :label => 'label', # C, PHP + :local_variable => 'local-variable', # local and magic variables; some scanners + :map => 'map', # Lua tables + :modifier => 'modifier', # used inside on strings; lots of scanners + :namespace => 'namespace', # Clojure, Java, Taskpaper + :octal => 'octal', # lots of scanners + :predefined => 'predefined', # predefined function: lots of scanners + :predefined_constant => 'predefined-constant',# lots of scanners + :predefined_type => 'predefined-type', # C, Java, PHP + :preprocessor => 'preprocessor', # C, Delphi, HTML + :pseudo_class => 'pseudo-class', # CSS + :regexp => 'regexp', # Groovy, JavaScript, Ruby + :reserved => 'reserved', # most scanners + :shell => 'shell', # Ruby + :string => 'string', # most scanners + :symbol => 'symbol', # Clojure, Ruby, YAML + :tag => 'tag', # CSS, HTML + :type => 'type', # CSS, Java, SQL, YAML + :value => 'value', # used together with :key; CSS, JSON, YAML + :variable => 'variable', # Sass, SQL, YAML + + :change => 'change', # Diff + :delete => 'delete', # Diff + :head => 'head', # Diff, YAML + :insert => 'insert', # Diff + :eyecatcher => 'eyecatcher', # Diff + + :ident => false, # almost all scanners + :operator => false, # almost all scanners + + :space => false, # almost all scanners + :plain => false # almost all scanners + ) + + TokenKinds[:method] = TokenKinds[:function] + TokenKinds[:unknown] = TokenKinds[:plain] +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens.rb new file mode 100644 index 0000000..e7bffce --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens.rb @@ -0,0 +1,161 @@ +module CodeRay + + # The Tokens class represents a list of tokens returned from + # a Scanner. It's actually just an Array with a few helper methods. + # + # A token itself is not a special object, just two elements in an Array: + # * the _token_ _text_ (the original source of the token in a String) or + # a _token_ _action_ (begin_group, end_group, begin_line, end_line) + # * the _token_ _kind_ (a Symbol representing the type of the token) + # + # It looks like this: + # + # ..., '# It looks like this', :comment, ... + # ..., '3.1415926', :float, ... + # ..., '$^', :error, ... + # + # Some scanners also yield sub-tokens, represented by special + # token actions, for example :begin_group and :end_group. + # + # The Ruby scanner, for example, splits "a string" into: + # + # [ + # :begin_group, :string, + # '"', :delimiter, + # 'a string', :content, + # '"', :delimiter, + # :end_group, :string + # ] + # + # Tokens can be used to save the output of a Scanners in a simple + # Ruby object that can be send to an Encoder later: + # + # tokens = CodeRay.scan('price = 2.59', :ruby).tokens + # tokens.encode(:html) + # tokens.html + # CodeRay.encoder(:html).encode_tokens(tokens) + # + # Tokens gives you the power to handle pre-scanned code very easily: + # You can serialize it to a JSON string and store it in a database, pass it + # around to encode it more than once, send it to other algorithms... + class Tokens < Array + + # The Scanner instance that created the tokens. + attr_accessor :scanner + + # Encode the tokens using encoder. + # + # encoder can be + # * a plugin name like :html oder 'statistic' + # * an Encoder object + # + # options are passed to the encoder. + def encode encoder, options = {} + encoder = Encoders[encoder].new options if encoder.respond_to? :to_sym + encoder.encode_tokens self, options + end + + # Turn tokens into a string by concatenating them. + def to_s + encode CodeRay::Encoders::Encoder.new + end + + # Redirects unknown methods to encoder calls. + # + # For example, if you call +tokens.html+, the HTML encoder + # is used to highlight the tokens. + def method_missing meth, options = {} + encode meth, options + rescue PluginHost::PluginNotFound + super + end + + # Split the tokens into parts of the given +sizes+. + # + # The result will be an Array of Tokens objects. The parts have + # the text size specified by the parameter. In addition, each + # part closes all opened tokens. This is useful to insert tokens + # betweem them. + # + # This method is used by @Scanner#tokenize@ when called with an Array + # of source strings. The Diff encoder uses it for inline highlighting. + def split_into_parts *sizes + return Array.new(sizes.size) { Tokens.new } if size == 2 && first == '' + parts = [] + opened = [] + content = nil + part = Tokens.new + part_size = 0 + size = sizes.first + i = 0 + for item in self + case content + when nil + content = item + when String + if size && part_size + content.size > size # token must be cut + if part_size < size # some part of the token goes into this part + content = content.dup # content may no be safe to change + part << content.slice!(0, size - part_size) << item + end + # close all open groups and lines... + closing = opened.reverse.flatten.map do |content_or_kind| + case content_or_kind + when :begin_group + :end_group + when :begin_line + :end_line + else + content_or_kind + end + end + part.concat closing + begin + parts << part + part = Tokens.new + size = sizes[i += 1] + end until size.nil? || size > 0 + # ...and open them again. + part.concat opened.flatten + part_size = 0 + redo unless content.empty? + else + part << content << item + part_size += content.size + end + content = nil + when Symbol + case content + when :begin_group, :begin_line + opened << [content, item] + when :end_group, :end_line + opened.pop + else + raise ArgumentError, 'Unknown token action: %p, kind = %p' % [content, item] + end + part << content << item + content = nil + else + raise ArgumentError, 'Token input junk: %p, kind = %p' % [content, item] + end + end + parts << part + parts << Tokens.new while parts.size < sizes.size + parts + end + + # Return the actual number of tokens. + def count + size / 2 + end + + alias text_token push + def begin_group kind; push :begin_group, kind end + def end_group kind; push :end_group, kind end + def begin_line kind; push :begin_line, kind end + def end_line kind; push :end_line, kind end + alias tokens concat + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens_proxy.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens_proxy.rb new file mode 100644 index 0000000..31ff39b --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/tokens_proxy.rb @@ -0,0 +1,55 @@ +module CodeRay + + # The result of a scan operation is a TokensProxy, but should act like Tokens. + # + # This proxy makes it possible to use the classic CodeRay.scan.encode API + # while still providing the benefits of direct streaming. + class TokensProxy + + attr_accessor :input, :lang, :options, :block + + # Create a new TokensProxy with the arguments of CodeRay.scan. + def initialize input, lang, options = {}, block = nil + @input = input + @lang = lang + @options = options + @block = block + end + + # Call CodeRay.encode if +encoder+ is a Symbol; + # otherwise, convert the receiver to tokens and call encoder.encode_tokens. + def encode encoder, options = {} + if encoder.respond_to? :to_sym + CodeRay.encode(input, lang, encoder, options) + else + encoder.encode_tokens tokens, options + end + end + + # Tries to call encode; + # delegates to tokens otherwise. + def method_missing method, *args, &blk + encode method.to_sym, *args + rescue PluginHost::PluginNotFound + tokens.send(method, *args, &blk) + end + + # The (cached) result of the tokenized input; a Tokens instance. + def tokens + @tokens ||= scanner.tokenize(input) + end + + # A (cached) scanner instance to use for the scan task. + def scanner + @scanner ||= CodeRay.scanner(lang, options, &block) + end + + # Overwrite Struct#each. + def each *args, &blk + tokens.each(*args, &blk) + self + end + + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/lib/coderay/version.rb b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/version.rb new file mode 100644 index 0000000..4b4f085 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/lib/coderay/version.rb @@ -0,0 +1,3 @@ +module CodeRay + VERSION = '1.1.0' +end diff --git a/vendor/bundle/gems/coderay-1.1.0/test/functional/basic.rb b/vendor/bundle/gems/coderay-1.1.0/test/functional/basic.rb new file mode 100755 index 0000000..752d4ba --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/test/functional/basic.rb @@ -0,0 +1,318 @@ +# encoding: utf-8 +require 'test/unit' +require File.expand_path('../../lib/assert_warning', __FILE__) + +$:.unshift File.expand_path('../../../lib', __FILE__) +require 'coderay' + +class BasicTest < Test::Unit::TestCase + + def test_version + assert_nothing_raised do + assert_match(/\A\d\.\d\.\d?\z/, CodeRay::VERSION) + end + end + + def with_empty_load_path + old_load_path = $:.dup + $:.clear + yield + ensure + $:.replace old_load_path + end + + def test_autoload + with_empty_load_path do + assert_nothing_raised do + CodeRay::Scanners::Java::BuiltinTypes + end + end + end + + RUBY_TEST_CODE = 'puts "Hello, World!"' + + RUBY_TEST_TOKENS = [ + ['puts', :ident], + [' ', :space], + [:begin_group, :string], + ['"', :delimiter], + ['Hello, World!', :content], + ['"', :delimiter], + [:end_group, :string] + ].flatten + def test_simple_scan + assert_nothing_raised do + assert_equal RUBY_TEST_TOKENS, CodeRay.scan(RUBY_TEST_CODE, :ruby).tokens + end + end + + RUBY_TEST_HTML = 'puts "' + + 'Hello, World!"' + def test_simple_highlight + assert_nothing_raised do + assert_equal RUBY_TEST_HTML, CodeRay.scan(RUBY_TEST_CODE, :ruby).html + end + end + + def test_scan_file + CodeRay.scan_file __FILE__ + end + + def test_encode + assert_equal 1, CodeRay.encode('test', :python, :count) + end + + def test_encode_tokens + assert_equal 1, CodeRay.encode_tokens(CodeRay::Tokens['test', :string], :count) + end + + def test_encode_file + assert_equal File.read(__FILE__), CodeRay.encode_file(__FILE__, :text) + end + + def test_highlight + assert_match '
test
', CodeRay.highlight('test', :python) + end + + def test_highlight_file + assert_match "require 'test/unit'\n", CodeRay.highlight_file(__FILE__) + end + + def test_duo + assert_equal(RUBY_TEST_CODE, + CodeRay::Duo[:plain, :text].highlight(RUBY_TEST_CODE)) + assert_equal(RUBY_TEST_CODE, + CodeRay::Duo[:plain => :text].highlight(RUBY_TEST_CODE)) + end + + def test_duo_stream + assert_equal(RUBY_TEST_CODE, + CodeRay::Duo[:plain, :text].highlight(RUBY_TEST_CODE, :stream => true)) + end + + def test_comment_filter + assert_equal <<-EXPECTED, CodeRay.scan(<<-INPUT, :ruby).comment_filter.text +#!/usr/bin/env ruby + +code + +more code + EXPECTED +#!/usr/bin/env ruby +=begin +A multi-line comment. +=end +code +# A single-line comment. +more code # and another comment, in-line. + INPUT + end + + def test_lines_of_code + assert_equal 2, CodeRay.scan(<<-INPUT, :ruby).lines_of_code +#!/usr/bin/env ruby +=begin +A multi-line comment. +=end +code +# A single-line comment. +more code # and another comment, in-line. + INPUT + rHTML = <<-RHTML + + + + + + <%= controller.controller_name.titleize %>: <%= controller.action_name %> + <%= stylesheet_link_tag 'scaffold' %> + + + +

<%= flash[:notice] %>

+ +
+ <%= yield %> +
+ + + + RHTML + assert_equal 0, CodeRay.scan(rHTML, :html).lines_of_code + assert_equal 0, CodeRay.scan(rHTML, :php).lines_of_code + assert_equal 0, CodeRay.scan(rHTML, :yaml).lines_of_code + assert_equal 4, CodeRay.scan(rHTML, :erb).lines_of_code + end + + def test_list_of_encoders + assert_kind_of(Array, CodeRay::Encoders.list) + assert CodeRay::Encoders.list.include?(:count) + end + + def test_list_of_scanners + assert_kind_of(Array, CodeRay::Scanners.list) + assert CodeRay::Scanners.list.include?(:text) + end + + def test_token_kinds + assert_kind_of Hash, CodeRay::TokenKinds + for kind, css_class in CodeRay::TokenKinds + assert_kind_of Symbol, kind + if css_class != false + assert_kind_of String, css_class, "TokenKinds[%p] == %p" % [kind, css_class] + end + end + assert_equal 'reserved', CodeRay::TokenKinds[:reserved] + assert_equal false, CodeRay::TokenKinds[:shibboleet] + end + + class Milk < CodeRay::Encoders::Encoder + FILE_EXTENSION = 'cocoa' + end + + class HoneyBee < CodeRay::Encoders::Encoder + end + + def test_encoder_file_extension + assert_nothing_raised do + assert_equal 'html', CodeRay::Encoders::Page::FILE_EXTENSION + assert_equal 'cocoa', Milk::FILE_EXTENSION + assert_equal 'cocoa', Milk.new.file_extension + assert_equal 'honeybee', HoneyBee::FILE_EXTENSION + assert_equal 'honeybee', HoneyBee.new.file_extension + end + assert_raise NameError do + HoneyBee::MISSING_CONSTANT + end + end + + def test_encoder_tokens + encoder = CodeRay::Encoders::Encoder.new + encoder.send :setup, {} + assert_raise(ArgumentError) { encoder.token :strange, '' } + encoder.token 'test', :debug + end + + def test_encoder_deprecated_interface + encoder = CodeRay::Encoders::Encoder.new + encoder.send :setup, {} + assert_warning 'Using old Tokens#<< interface.' do + encoder << ['test', :content] + end + assert_raise ArgumentError do + encoder << [:strange, :input] + end + assert_raise ArgumentError do + encoder.encode_tokens [['test', :token]] + end + end + + def encoder_token_interface_deprecation_warning_given + CodeRay::Encoders::Encoder.send :class_variable_get, :@@CODERAY_TOKEN_INTERFACE_DEPRECATION_WARNING_GIVEN + end + + def test_scanner_file_extension + assert_equal 'rb', CodeRay::Scanners::Ruby.file_extension + assert_equal 'rb', CodeRay::Scanners::Ruby.new.file_extension + assert_equal 'java', CodeRay::Scanners::Java.file_extension + assert_equal 'java', CodeRay::Scanners::Java.new.file_extension + end + + def test_scanner_lang + assert_equal :ruby, CodeRay::Scanners::Ruby.lang + assert_equal :ruby, CodeRay::Scanners::Ruby.new.lang + assert_equal :java, CodeRay::Scanners::Java.lang + assert_equal :java, CodeRay::Scanners::Java.new.lang + end + + def test_scanner_tokenize + assert_equal ['foo', :plain], CodeRay::Scanners::Plain.new.tokenize('foo') + assert_equal [['foo', :plain], ['bar', :plain]], CodeRay::Scanners::Plain.new.tokenize(['foo', 'bar']) + CodeRay::Scanners::Plain.new.tokenize 42 + end + + def test_scanner_tokens + scanner = CodeRay::Scanners::Plain.new + scanner.tokenize('foo') + assert_equal ['foo', :plain], scanner.tokens + scanner.string = '' + assert_equal ['', :plain], scanner.tokens + end + + def test_scanner_line_and_column + scanner = CodeRay::Scanners::Plain.new "foo\nbär+quux" + assert_equal 0, scanner.pos + assert_equal 1, scanner.line + assert_equal 1, scanner.column + scanner.scan(/foo/) + assert_equal 3, scanner.pos + assert_equal 1, scanner.line + assert_equal 4, scanner.column + scanner.scan(/\n/) + assert_equal 4, scanner.pos + assert_equal 2, scanner.line + assert_equal 1, scanner.column + scanner.scan(/b/) + assert_equal 5, scanner.pos + assert_equal 2, scanner.line + assert_equal 2, scanner.column + scanner.scan(/a/) + assert_equal 5, scanner.pos + assert_equal 2, scanner.line + assert_equal 2, scanner.column + scanner.scan(/ä/) + assert_equal 7, scanner.pos + assert_equal 2, scanner.line + assert_equal 4, scanner.column + scanner.scan(/r/) + assert_equal 8, scanner.pos + assert_equal 2, scanner.line + assert_equal 5, scanner.column + end + + def test_scanner_use_subclasses + assert_raise NotImplementedError do + CodeRay::Scanners::Scanner.new + end + end + + class InvalidScanner < CodeRay::Scanners::Scanner + end + + def test_scanner_scan_tokens + assert_raise NotImplementedError do + InvalidScanner.new.tokenize '' + end + end + + class RaisingScanner < CodeRay::Scanners::Scanner + def scan_tokens encoder, options + raise_inspect 'message', [], :initial + end + end + + def test_scanner_raise_inspect + assert_raise CodeRay::Scanners::Scanner::ScanError do + RaisingScanner.new.tokenize '' + end + end + + def test_scan_a_frozen_string + assert_nothing_raised do + CodeRay.scan RUBY_VERSION, :ruby + CodeRay.scan RUBY_VERSION, :plain + end + end + + def test_scan_a_non_string + assert_nothing_raised do + CodeRay.scan 42, :ruby + CodeRay.scan nil, :ruby + CodeRay.scan self, :ruby + CodeRay.encode ENV.to_hash, :ruby, :page + CodeRay.highlight CodeRay, :plain + end + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/test/functional/examples.rb b/vendor/bundle/gems/coderay-1.1.0/test/functional/examples.rb new file mode 100755 index 0000000..985ef87 --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/test/functional/examples.rb @@ -0,0 +1,129 @@ +require 'test/unit' + +$:.unshift File.expand_path('../../../lib', __FILE__) +require 'coderay' + +class ExamplesTest < Test::Unit::TestCase + + def test_examples + # output as HTML div (using inline CSS styles) + div = CodeRay.scan('puts "Hello, world!"', :ruby).div + assert_equal <<-DIV, div +
+
puts "Hello, world!"
+
+ DIV + + # ...with line numbers + div = CodeRay.scan(<<-CODE.chomp, :ruby).div(:line_numbers => :table) +5.times do + puts 'Hello, world!' +end + CODE + assert_equal <<-DIV, div + + + +
1
+2
+3
+
5.times do
+  puts 'Hello, world!'
+end
+ DIV + + # output as standalone HTML page (using CSS classes) + page = CodeRay.scan('puts "Hello, world!"', :ruby).page + assert_match <<-PAGE, page + + + + + +
1
+
puts "Hello, world!"
+ + + PAGE + + # keep scanned tokens for later use + tokens = CodeRay.scan('{ "just": "an", "example": 42 }', :json) + assert_kind_of CodeRay::TokensProxy, tokens + + assert_equal ["{", :operator, " ", :space, :begin_group, :key, + "\"", :delimiter, "just", :content, "\"", :delimiter, + :end_group, :key, ":", :operator, " ", :space, + :begin_group, :string, "\"", :delimiter, "an", :content, + "\"", :delimiter, :end_group, :string, ",", :operator, + " ", :space, :begin_group, :key, "\"", :delimiter, + "example", :content, "\"", :delimiter, :end_group, :key, + ":", :operator, " ", :space, "42", :integer, + " ", :space, "}", :operator], tokens.tokens + + # produce a token statistic + assert_equal <<-STATISTIC, tokens.statistic + +Code Statistics + +Tokens 26 + Non-Whitespace 15 +Bytes Total 31 + +Token Types (7): + type count ratio size (average) +------------------------------------------------------------- + TOTAL 26 100.00 % 1.2 + delimiter 6 23.08 % 1.0 + operator 5 19.23 % 1.0 + space 5 19.23 % 1.0 + key 4 15.38 % 0.0 + :begin_group 3 11.54 % 0.0 + :end_group 3 11.54 % 0.0 + content 3 11.54 % 4.3 + string 2 7.69 % 0.0 + integer 1 3.85 % 2.0 + + STATISTIC + + # count the tokens + assert_equal 26, tokens.count + + # produce a HTML div, but with CSS classes + div = tokens.div(:css => :class) + assert_equal <<-DIV, div +
+
{ "just": "an", "example": 42 }
+
+ DIV + + # highlight a file (HTML div); guess the file type base on the extension + assert_equal :ruby, CodeRay::FileType[__FILE__] + + # get a new scanner for Python + python_scanner = CodeRay.scanner :python + assert_kind_of CodeRay::Scanners::Python, python_scanner + + # get a new encoder for terminal + terminal_encoder = CodeRay.encoder :term + assert_kind_of CodeRay::Encoders::Terminal, terminal_encoder + + # scanning into tokens + tokens = python_scanner.tokenize 'import this; # The Zen of Python' + assert_equal ["import", :keyword, " ", :space, "this", :include, + ";", :operator, " ", :space, "# The Zen of Python", :comment], tokens + + # format the tokens + term = terminal_encoder.encode_tokens(tokens) + assert_equal "\e[32mimport\e[0m \e[31mthis\e[0m; \e[1;30m# The Zen of Python\e[0m", term + + # re-using scanner and encoder + ruby_highlighter = CodeRay::Duo[:ruby, :div] + div = ruby_highlighter.encode('puts "Hello, world!"') + assert_equal <<-DIV, div +
+
puts "Hello, world!"
+
+ DIV + end + +end diff --git a/vendor/bundle/gems/coderay-1.1.0/test/functional/for_redcloth.rb b/vendor/bundle/gems/coderay-1.1.0/test/functional/for_redcloth.rb new file mode 100644 index 0000000..9fd244e --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/test/functional/for_redcloth.rb @@ -0,0 +1,78 @@ +require 'test/unit' + +$:.unshift File.expand_path('../../../lib', __FILE__) +require 'coderay' + +begin + require 'rubygems' unless defined? Gem + gem 'RedCloth', '>= 4.0.3' rescue nil + require 'redcloth' +rescue LoadError + warn 'RedCloth not found - skipping for_redcloth tests.' + undef RedCloth if defined? RedCloth +end + +class BasicTest < Test::Unit::TestCase + + def test_for_redcloth + require 'coderay/for_redcloth' + assert_equal "

puts "Hello, World!"

", + RedCloth.new('@[ruby]puts "Hello, World!"@').to_html + assert_equal <<-BLOCKCODE.chomp, +
+
puts "Hello, World!"
+
+ BLOCKCODE + RedCloth.new('bc[ruby]. puts "Hello, World!"').to_html + end + + def test_for_redcloth_no_lang + require 'coderay/for_redcloth' + assert_equal "

puts \"Hello, World!\"

", + RedCloth.new('@puts "Hello, World!"@').to_html + assert_equal <<-BLOCKCODE.chomp, +
puts \"Hello, World!\"
+ BLOCKCODE + RedCloth.new('bc. puts "Hello, World!"').to_html + end + + def test_for_redcloth_style + require 'coderay/for_redcloth' + assert_equal <<-BLOCKCODE.chomp, +
puts \"Hello, World!\"
+ BLOCKCODE + RedCloth.new('bc{color: red}. puts "Hello, World!"').to_html + end + + def test_for_redcloth_escapes + require 'coderay/for_redcloth' + assert_equal '

>

', + RedCloth.new('@[ruby]>@').to_html + assert_equal <<-BLOCKCODE.chomp, +
+
&
+
+ BLOCKCODE + RedCloth.new('bc[ruby]. &').to_html + end + + def test_for_redcloth_escapes2 + require 'coderay/for_redcloth' + assert_equal "

#include <test.h>

", + RedCloth.new('@[c]#include @').to_html + end + + # See http://jgarber.lighthouseapp.com/projects/13054/tickets/124-code-markup-does-not-allow-brackets. + def test_for_redcloth_false_positive + require 'coderay/for_redcloth' + assert_equal '

[project]_dff.skjd

', + RedCloth.new('@[project]_dff.skjd@').to_html + # false positive, but expected behavior / known issue + assert_equal "

_dff.skjd

", + RedCloth.new('@[ruby]_dff.skjd@').to_html + assert_equal <<-BLOCKCODE.chomp, RedCloth.new('bc. [project]_dff.skjd').to_html +
[project]_dff.skjd
+ BLOCKCODE + end + +end if defined? RedCloth \ No newline at end of file diff --git a/vendor/bundle/gems/coderay-1.1.0/test/functional/suite.rb b/vendor/bundle/gems/coderay-1.1.0/test/functional/suite.rb new file mode 100755 index 0000000..ec23eec --- /dev/null +++ b/vendor/bundle/gems/coderay-1.1.0/test/functional/suite.rb @@ -0,0 +1,15 @@ +require 'test/unit' + +$VERBOSE = $CODERAY_DEBUG = true +$:.unshift File.expand_path('../../../lib', __FILE__) +require 'coderay' + +mydir = File.dirname(__FILE__) +suite = Dir[File.join(mydir, '*.rb')]. + map { |tc| File.basename(tc).sub(/\.rb$/, '') } - %w'suite for_redcloth' + +puts "Running basic CodeRay #{CodeRay::VERSION} tests: #{suite.join(', ')}" + +for test_case in suite + load File.join(mydir, test_case + '.rb') +end diff --git a/vendor/bundle/gems/columnize-0.8.9/.gitignore b/vendor/bundle/gems/columnize-0.8.9/.gitignore new file mode 100644 index 0000000..73f35cf --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/.gitignore @@ -0,0 +1,3 @@ +*~ +/doc +/pkg diff --git a/vendor/bundle/gems/columnize-0.8.9/.travis.yml b/vendor/bundle/gems/columnize-0.8.9/.travis.yml new file mode 100644 index 0000000..9292c33 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/.travis.yml @@ -0,0 +1,9 @@ +language: ruby + +rvm: + - 1.8.7 + - 1.9.3 + - 2.0.0 + - ruby-head + - rbx-18mode + - rbx-19mode diff --git a/vendor/bundle/gems/columnize-0.8.9/AUTHORS b/vendor/bundle/gems/columnize-0.8.9/AUTHORS new file mode 100644 index 0000000..463be9b --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/AUTHORS @@ -0,0 +1,2 @@ +R. Bernstein (rockyb@rubyforge.net) +M. Davis (waslogic@gmail.com) diff --git a/vendor/bundle/gems/columnize-0.8.9/COPYING b/vendor/bundle/gems/columnize-0.8.9/COPYING new file mode 100644 index 0000000..32e46ac --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/COPYING @@ -0,0 +1,57 @@ +Columnize is copyrighted free software by Rocky Bernstein . + +You can redistribute it and/or modify it under either the terms of the GPL +version 2, or the conditions below: + + 1. You may make and give away verbatim copies of the source form of the + software without restriction, provided that you duplicate all of the + original copyright notices and associated disclaimers. + + 2. You may modify your copy of the software in any way, provided that + you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or by allowing + the author to include your modifications in the software. + + b) use the modified software only within your corporation or + organization. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 3. You may distribute the software in object code or binary form, + provided that you do at least ONE of the following: + + a) distribute the binaries and library files of the software, + together with instructions (in the manual page or equivalent) + on where to get the original distribution. + + b) accompany the distribution with the machine-readable source of + the software. + + c) give non-standard binaries non-standard names, with + instructions on where to get the original software distribution. + + d) make other distribution arrangements with the author. + + 4. You may modify and include the part of the software into any other + software (possibly commercial). But some files in the distribution + are not written by the author, so that they are not under these terms. + + For the list of those files and their copying conditions, see the + file LEGAL. + + 5. The scripts and library files supplied as input to or produced as + output from the software do not automatically fall under the + copyright of the software, but belong to whomever generated them, + and may be sold commercially, and may be aggregated with this + software. + + 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + PURPOSE. diff --git a/vendor/bundle/gems/columnize-0.8.9/ChangeLog b/vendor/bundle/gems/columnize-0.8.9/ChangeLog new file mode 100644 index 0000000..becafe2 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/ChangeLog @@ -0,0 +1,282 @@ +2011-06-09 rocky + + * ChangeLog, NEWS, Rakefile: Get ready for new release. + +2011-04-27 r + + * README.md: Fix code example. + +2011-04-27 r + + * .gemspec, README, README.md, Rakefile: README->README.md + +2011-04-27 r + + * .gemspec, AUTHORS, COPYING, ChangeLog, Makefile, NEWS, README, + Rakefile, lib/Makefile, lib/columnize.rb, lib/version.rb, + tags/release-0.2.1/AUTHORS, tags/release-0.2.1/COPYING, + tags/release-0.2.1/ChangeLog, tags/release-0.2.1/NEWS, + tags/release-0.2.1/README, tags/release-0.2.1/Rakefile, + tags/release-0.2.1/VERSION, tags/release-0.2.1/lib/columnize.rb, + tags/release-0.2.1/test/test-columnize.rb, + tags/release-0.3.0/AUTHORS, tags/release-0.3.0/COPYING, + tags/release-0.3.0/ChangeLog, tags/release-0.3.0/NEWS, + tags/release-0.3.0/README, tags/release-0.3.0/Rakefile, + tags/release-0.3.0/VERSION, tags/release-0.3.0/lib/columnize.rb, + tags/release-0.3.0/test/test-columnize.rb, + tags/release-0.3.1/AUTHORS, tags/release-0.3.1/COPYING, + tags/release-0.3.1/ChangeLog, tags/release-0.3.1/NEWS, + tags/release-0.3.1/README, tags/release-0.3.1/Rakefile, + tags/release-0.3.1/VERSION, tags/release-0.3.1/lib/columnize.rb, + tags/release-0.3.1/test/test-columnize.rb, test/test-columnize.rb, + test/test-hashparm.rb, trunk/.gemspec, trunk/AUTHORS, + trunk/COPYING, trunk/ChangeLog, trunk/Makefile, trunk/NEWS, + trunk/README, trunk/Rakefile, trunk/lib/Makefile, + trunk/lib/columnize.rb, trunk/lib/version.rb, + trunk/test/test-columnize.rb, trunk/test/test-hashparm.rb: Remove + trunk and tags. + +2011-04-27 rockyb + + * trunk/ChangeLog, trunk/lib/columnize.rb, trunk/lib/version.rb, + trunk/test/test-columnize.rb, trunk/test/test-hashparm.rb: Redo + columnize options processing to allow for a single hash of options + instead of the numerous optional arguments. This make future + expansion easier. + +2010-09-22 rockyb + + * trunk/Makefile, trunk/Rakefile: Rakefile: Remove bad test task + Makefile: simplify. + +2010-09-21 rockyb + + * trunk/Makefile, trunk/Rakefile: Makefile was a little off + +2010-09-21 rockyb + + * trunk/.gemspec, trunk/Rakefile, trunk/lib/columnize.rb: Small + changes to Rakefile and rdoc and so on. + +2010-09-20 rockyb + + * trunk/.gemspec, trunk/Rakefile: Forgot to add .gemspec + +2010-09-20 rockyb + + * trunk/ChangeLog, trunk/Makefile, trunk/NEWS, trunk/README, + trunk/Rakefile, trunk/VERSION, trunk/lib/Makefile, + trunk/lib/columnize.rb, trunk/lib/version.rb: Add .gemspec, correct + description field and add a summary. Add Columnize::VERSION Simplify + Rakefile Add stub Makefiles + +2010-03-01 rockyb + + * trunk/README: Better README description + +2010-03-01 rockyb + + * trunk/README: Update README + +2010-02-22 rockyb + + * trunk/ChangeLog, trunk/VERSION, trunk/lib/columnize.rb: Remove + shadow variable warnings. Bump version number + +2009-07-26 rockyb + + * tags/release-0.3.1/AUTHORS, tags/release-0.3.1/COPYING, + tags/release-0.3.1/ChangeLog, tags/release-0.3.1/NEWS, + tags/release-0.3.1/README, tags/release-0.3.1/Rakefile, + tags/release-0.3.1/VERSION, tags/release-0.3.1/lib/columnize.rb, + tags/release-0.3.1/test/test-columnize.rb: Release 0.3.1 + +2009-07-26 rockyb + + * trunk/lib/columnize.rb: Small comment spelling typo. + +2009-07-26 rockyb + + * trunk/ChangeLog: Get ready for 0.3.1 release + +2009-07-26 rockyb + + * trunk/NEWS, trunk/lib/columnize.rb, trunk/test/test-columnize.rb: + Add lineprefix. Get ready for release. + +2009-07-26 mark-moseley + + * trunk/ChangeLog, trunk/lib/columnize.rb: Ruby 1.9 updates + +2009-03-30 rockyb + + * trunk/Rakefile: Revise for 1.9 version of rake + +2009-01-16 rockyb + + * trunk/ChangeLog, trunk/Rakefile, trunk/VERSION: package readme was + wonky. Looks like no one reads this stuff. + +2009-01-10 rockyb + + * tags/release-0.3.0/AUTHORS, tags/release-0.3.0/COPYING, + tags/release-0.3.0/ChangeLog, tags/release-0.3.0/NEWS, + tags/release-0.3.0/README, tags/release-0.3.0/Rakefile, + tags/release-0.3.0/VERSION, tags/release-0.3.0/lib/columnize.rb, + tags/release-0.3.0/test/test-columnize.rb: Release 0.3.0 + +2009-01-10 rockyb + + * trunk/ChangeLog, trunk/NEWS: Get ready for release + +2009-01-08 rockyb + + * trunk/ChangeLog, trunk/NEWS, trunk/VERSION, + trunk/lib/columnize.rb, trunk/test/test-columnize.rb: Fix bad bug in + arranging horizontally + +2009-01-01 rockyb + + * columnize/trunk/AUTHORS, columnize/trunk/COPYING, + columnize/trunk/ChangeLog, columnize/trunk/NEWS, + columnize/trunk/README, columnize/trunk/Rakefile, + columnize/trunk/VERSION, columnize/trunk/lib/columnize.rb, + columnize/trunk/test/test-columnize.rb: Remove hacky + columnize/columnize + +2009-01-01 rockyb + + * tags/columnize-0.2/AUTHORS, tags/columnize-0.2/COPYING, + tags/columnize-0.2/ChangeLog, tags/columnize-0.2/NEWS, + tags/columnize-0.2/README, tags/columnize-0.2/Rakefile, + tags/columnize-0.2/VERSION, tags/columnize-0.2/lib/columnize.rb, + tags/columnize-0.2/test/test-columnize.rb: Regularize tags names + better + +2009-01-01 rockyb + + * tags/release-0.2.1/AUTHORS, tags/release-0.2.1/COPYING, + tags/release-0.2.1/ChangeLog, tags/release-0.2.1/NEWS, + tags/release-0.2.1/README, tags/release-0.2.1/Rakefile, + tags/release-0.2.1/VERSION, tags/release-0.2.1/lib/columnize.rb, + tags/release-0.2.1/test/test-columnize.rb: Release 0.2.1 + +2009-01-01 rockyb + + * trunk/NEWS: Merge NEWS + +2009-01-01 rockyb + + * columnize/tags/columnize-0.2/AUTHORS, + columnize/tags/columnize-0.2/COPYING, + columnize/tags/columnize-0.2/ChangeLog, + columnize/tags/columnize-0.2/NEWS, + columnize/tags/columnize-0.2/README, + columnize/tags/columnize-0.2/Rakefile, + columnize/tags/columnize-0.2/VERSION, + columnize/tags/columnize-0.2/lib/columnize.rb, + columnize/tags/columnize-0.2/test/test-columnize.rb, + tags/columnize-0.2/AUTHORS, tags/columnize-0.2/COPYING, + tags/columnize-0.2/ChangeLog, tags/columnize-0.2/NEWS, + tags/columnize-0.2/README, tags/columnize-0.2/Rakefile, + tags/columnize-0.2/VERSION, tags/columnize-0.2/lib/columnize.rb, + tags/columnize-0.2/test/test-columnize.rb: Cleanup of + columnize/columnize crap + +2009-01-01 rockyb + + * : Add directory for releases + +2009-01-01 rockyb + + * trunk/NEWS, trunk/VERSION: Ooops 0.2 release done. Go for 0.2.1 + +2009-01-01 rockyb + + * trunk/ChangeLog: Get ready for release 0.2 + +2009-01-01 rockyb + + * trunk/ChangeLog, trunk/NEWS, trunk/VERSION, + trunk/lib/columnize.rb, trunk/test/test-columnize.rb: Get ready for + release 0.2 + +2008-09-22 rockyb + + * columnize/tags/columnize-0.2/AUTHORS, + columnize/tags/columnize-0.2/COPYING, + columnize/tags/columnize-0.2/ChangeLog, + columnize/tags/columnize-0.2/NEWS, + columnize/tags/columnize-0.2/README, + columnize/tags/columnize-0.2/Rakefile, + columnize/tags/columnize-0.2/VERSION, + columnize/tags/columnize-0.2/lib/columnize.rb, + columnize/tags/columnize-0.2/test/test-columnize.rb: Tag 0.2 + release. + +2008-09-22 rockyb + + * : Add tags directory for release + +2008-09-22 rockyb + + * columnize/trunk/ChangeLog, columnize/trunk/NEWS: Add directory for + tagging releases. Other Administrivia. + +2008-09-22 rockyb + + * columnize/trunk/VERSION, columnize/trunk/lib/columnize.rb: Get rid + of hacky $0 test. + +2008-03-16 rockyb + + * trunk/lib/columnize.rb: [no log message] + +2008-03-16 rockyb + + * trunk/lib/columnize.rb: Simplify __FILE__ == $0. (rdebug now + changes $0 and rcov has an option) + +2008-02-11 rockyb + + * trunk/lib/columnize.rb: Remove 1.9's shadow warning + +2007-12-10 rockyb + + * columnize/trunk/AUTHORS, columnize/trunk/COPYING, + columnize/trunk/ChangeLog, columnize/trunk/NEWS, + columnize/trunk/README, columnize/trunk/Rakefile, + columnize/trunk/VERSION, columnize/trunk/lib/columnize.rb, + columnize/trunk/test/test-columnize.rb: release 0.1 + +2007-12-09 rockyb + + * trunk/README, trunk/Rakefile: Fix up doc a little. Make the + default rake task "test". + +2007-12-09 rockyb + + * trunk/lib/columnize.rb: Doc fix. + +2007-12-09 rockyb + + * trunk/ChangeLog, trunk/lib/columnize.rb, + trunk/test/test-columnize.rb: columnize.rb: Allow one to specify a + separator string. Remove restriction that all entries in the array + have to be a string. test-columnize.rb: more tests - invalid list, + empty list, with separator string parameter. + +2007-12-09 rockyb + + * trunk/test/test-columnize.rb: Typo. + +2007-12-09 rockyb + + * : Property changes for Id lines and to make test-columnize.rb + executable. + +2007-12-09 rockyb + + * Initial release of Columnize, a module to print an Array in + column-sorted order. + diff --git a/vendor/bundle/gems/columnize-0.8.9/Gemfile b/vendor/bundle/gems/columnize-0.8.9/Gemfile new file mode 100644 index 0000000..fa75df1 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gemspec diff --git a/vendor/bundle/gems/columnize-0.8.9/Makefile b/vendor/bundle/gems/columnize-0.8.9/Makefile new file mode 100644 index 0000000..7f690e9 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/Makefile @@ -0,0 +1,15 @@ +# I'll admit it -- I'm an absent-minded old-timer who has trouble +# learning new tricks. + +RUBY ?= ruby +RAKE ?= rake + +test: check + +#: Default target; same as "make check" +all: check + true + +#: Same as corresponding rake task +%: + $(RAKE) $@ diff --git a/vendor/bundle/gems/columnize-0.8.9/NEWS b/vendor/bundle/gems/columnize-0.8.9/NEWS new file mode 100644 index 0000000..303c211 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/NEWS @@ -0,0 +1,58 @@ +0.8.9 Apr 19, 2014 +- Add columnize method to Array class and a place to set its default options +- Add option :colfmt to allow a format specifier to use (e.g. '%02d') in stringifying + list items +- Add option linesuffix (default is "\n") +- When using arrange_array each line now has trailing "," + +0.3.6 Dec 17, 2011 +- rename version.rb columnize/version.rb so as not to conflict with + another package called version +- Administrivia - shorten gemcutter description + +0.3.5 Nov 24, 2011 +- Handle situation where an array element is larger than the display width. + +0.3.4 July 4, 2011 + +- Change to Ruby License +- Add option 'term_adjust' to ignore terminal sequences in text +- Add :ljust => :auto to decide whether or not to automatically + left or right justify. When passing a hash parameter, the default + is :auto. + +0.3.3 June 12, 2011 Fleetwood release + +- More general but simpler inteface using an options + hash. Compatibility is maintaind though. + +0.3.2 + +- Mostly Administrivia. + * Add .gemspec, correct description field and add a summary. + * Add Columnize::VERSION + * Simplify Rakefile + * Add stub Makefiles + +0.3.1 (01-07-26) + +- Correct for Ruby 1.9 (Mark Moseley) + +- add optional lineprefix parameter + +0.3.0 (01-10-09) - Sam Woodward Release + +- Fix bad bug in arranging horizontally + +0.2.1 (12-31-08) + +- Add ability to run columns horizontally + +0.2 + +- Minor - get rid of hacky $0 test + +0.1 + +- Initial release of Columnize, a module to print an Array in + column-sorted order diff --git a/vendor/bundle/gems/columnize-0.8.9/README.md b/vendor/bundle/gems/columnize-0.8.9/README.md new file mode 100644 index 0000000..027f525 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/README.md @@ -0,0 +1,108 @@ +[![Build Status](https://travis-ci.org/rocky/columnize.png)](https://travis-ci.org/rocky/columnize) + +Columnize - Format an Array as a Column-aligned String +============================================================================ + +In showing a long lists, sometimes one would prefer to see the value +arranged aligned in columns. Some examples include listing methods of +an object, listing debugger commands, or showing a numeric array with data +aligned. + +Setup +----- + + $ irb + >> require 'columnize' + => true + +With numeric data +----------------- + + >> a = (1..10).to_a + => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + + >> a.columnize + => "1 2 3 4 5 6 7 8 9 10" + + >> puts a.columnize :arrange_array => true, :displaywidth => 10 + [1, 2, 3, + 4, 5, 6, + 7, 8, 9, + 10] + => nil + + >> puts a.columnize :arrange_array => true, :displaywidth => 20 + [1, 2, 3, 4, 5, 6, + 7, 8, 9, 10] + => nil + +With String data +---------------- + + >> g = %w(bibrons golden madascar leopard mourning suras tokay) + => ["bibrons", "golden", "madascar", "leopard", "mourning", "suras", "tokay"] + + >> puts g.columnize :displaywidth => 15 + bibrons suras + golden tokay + madascar + leopard + mourning + => nil + + >> puts g.columnize :displaywidth => 19, :colsep => ' | ' + bibrons | suras + golden | tokay + madascar + leopard + mourning + => nil + + >> puts g.columnize :displaywidth => 18, :colsep => ' | ', :ljust => false + bibrons | mourning + golden | suras + madascar | tokay + leopard + => nil + +Using Columnize.columnize +------------------------- + + >> Columnize.columnize(a) + => "1 2 3 4 5 6 7 8 9 10" + + >> puts Columnize.columnize(a, :displaywidth => 10) + 1 5 9 + 2 6 10 + 3 7 + 4 8 + => nil + + >> Columnize.columnize(g) + => "bibrons golden madascar leopard mourning suras tokay" + + >> puts Columnize.columnize(g, :displaywidth => 19, :colsep => ' | ') + bibrons | mourning + golden | suras + madascar | tokay + leopard + => nil + + +Credits +------- + +This is adapted from a method of the same name from Python's cmd module. + +Other stuff +----------- + +Authors: Rocky Bernstein [![endorse](https://api.coderwall.com/rocky/endorsecount.png)](https://coderwall.com/rocky) and [Martin Davis](https://github.com/waslogic) + +License: Copyright (c) 2011,2013 Rocky Bernstein + +Warranty +-------- + +You can redistribute it and/or modify it under either the terms of the GPL +version 2 or the conditions listed in COPYING diff --git a/vendor/bundle/gems/columnize-0.8.9/Rakefile b/vendor/bundle/gems/columnize-0.8.9/Rakefile new file mode 100644 index 0000000..f3f55de --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/Rakefile @@ -0,0 +1,105 @@ +#!/usr/bin/env rake +# -*- Ruby -*- +require 'rubygems' +require 'fileutils' + +ROOT_DIR = File.dirname(__FILE__) +Gemspec_filename = 'columnize.gemspec' +require File.join %W(#{ROOT_DIR} lib columnize version) + +def gemspec + @gemspec ||= eval(File.read(Gemspec_filename), binding, Gemspec_filename) +end + +require 'rubygems/package_task' +desc "Build the gem" +task :package=>:gem +task :gem=>:gemspec do + Dir.chdir(ROOT_DIR) do + sh "gem build columnize.gemspec" + FileUtils.mkdir_p 'pkg' + FileUtils.mv gemspec.file_name, 'pkg' + end +end + +desc "Install the gem locally" +task :install => :gem do + Dir.chdir(ROOT_DIR) do + sh %{gem install --local pkg/#{gemspec.file_name}} + end +end + +require 'rake/testtask' +desc "Test everything." +Rake::TestTask.new(:test) do |t| + t.libs << './lib' + t.test_files = FileList['test/test-*.rb'] + t.verbose = true +end +task :test => :lib + +desc "same as test" +task :check => :test + +desc "same as test" +task :columnize => :test + +desc 'Create a GNU-style ChangeLog via git2cl' +task :ChangeLog do + system('git log --pretty --numstat --summary | git2cl > ChangeLog') +end + +task :default => [:test] + +desc 'Create a GNU-style ChangeLog via git2cl' +task :ChangeLog do + system('git log --pretty --numstat --summary | git2cl > ChangeLog') +end + +desc "Generate the gemspec" +task :generate do + puts gemspec.to_ruby +end + +desc "Validate the gemspec" +task :gemspec do + gemspec.validate +end + +# --------- RDoc Documentation ------ +require 'rdoc/task' +desc "Generate rdoc documentation" +Rake::RDocTask.new("rdoc") do |rdoc| + rdoc.rdoc_dir = 'doc' + rdoc.title = "Columnize #{Columnize::VERSION} Documentation" + + # Make the README file the start page for the generated html + rdoc.options += %w(--main README.md) + + rdoc.rdoc_files.include('lib/*.rb', 'README.md', 'COPYING') +end + +desc "Same as rdoc" +task :doc => :rdoc + +task :clobber_package do + FileUtils.rm_rf File.join(ROOT_DIR, 'pkg') +end + +task :clobber_rdoc do + FileUtils.rm_rf File.join(ROOT_DIR, 'doc') +end + +desc 'Remove residue from running patch' +task :rm_patch_residue do + FileUtils.rm_rf Dir.glob('**/*.{rej,orig}'), :verbose => true +end + +desc 'Remove ~ backup files' +task :rm_tilde_backups do + FileUtils.rm_rf Dir.glob('**/*~'), :verbose => true +end + +desc 'Remove built files' +task :clean => [:clobber_package, :clobber_rdoc, :rm_patch_residue, + :rm_tilde_backups] diff --git a/vendor/bundle/gems/columnize-0.8.9/THANKS b/vendor/bundle/gems/columnize-0.8.9/THANKS new file mode 100644 index 0000000..56e07f8 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/THANKS @@ -0,0 +1,8 @@ +I am indebted to: + +Mark Moseley: + the initial port from 1.8 to 1.9 +Martin Davis: + how to extend into Array classes and set options from there +David Rodríguez de Dios: + Miscellaneous portability fixes and doggedness to get out a new release diff --git a/vendor/bundle/gems/columnize-0.8.9/columnize.gemspec b/vendor/bundle/gems/columnize-0.8.9/columnize.gemspec new file mode 100644 index 0000000..6ad5267 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/columnize.gemspec @@ -0,0 +1,38 @@ +# -*- Ruby -*- +# -*- encoding: utf-8 -*- +require 'rake' +require 'rubygems' unless + Object.const_defined?(:Gem) +require File.dirname(__FILE__) + "/lib/columnize/version" unless + Object.const_defined?(:'Columnize') + +Gem::Specification.new do |spec| + spec.authors = ['Rocky Bernstein'] + spec.date = Time.now + spec.description = ' +In showing a long lists, sometimes one would prefer to see the value +arranged aligned in columns. Some examples include listing methods +of an object or debugger commands. +See Examples in the rdoc documentation for examples. +' + spec.email = 'rockyb@rubyforge.net' + spec.files = `git ls-files`.split("\n") + spec.homepage = 'https://github.com/rocky/columnize' + spec.name = 'columnize' + spec.licenses = ['Ruby', 'GPL2'] + spec.platform = Gem::Platform::RUBY + spec.require_path = 'lib' + spec.required_ruby_version = '>= 1.8.2' + spec.rubyforge_project = 'columnize' + spec.summary = 'Module to format an Array as an Array of String aligned in columns' + spec.version = Columnize::VERSION + spec.has_rdoc = true + spec.extra_rdoc_files = %w(README.md lib/columnize.rb COPYING THANKS) + + # Make the readme file the start page for the generated html + spec.rdoc_options += %w(--main README) + spec.rdoc_options += ['--title', "Columnize #{Columnize::VERSION} Documentation"] + + spec.add_development_dependency 'rdoc' + spec.add_development_dependency 'rake' +end diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/Makefile b/vendor/bundle/gems/columnize-0.8.9/lib/Makefile new file mode 100644 index 0000000..b1a10e5 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/Makefile @@ -0,0 +1,10 @@ +# Whatever it is you want to do, it should be handled by the main +# (parent) Makefile. So reissue make from there. +PHONY=check all + +#: Default target - the parent's testing or "check" target +all: check + +#: Whatever it is you want to do, it should be handled by the parent +%: + $(MAKE) -C .. $@ diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/columnize.rb b/vendor/bundle/gems/columnize-0.8.9/lib/columnize.rb new file mode 100644 index 0000000..3469ae4 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/columnize.rb @@ -0,0 +1,137 @@ +# Module to format an Array into a single string with embedded +# newlines, On printing the string, the columns are aligned. +# +# == Summary +# +# Return a string from an array with embedded newlines formatted so +# that when printed the columns are aligned. +# See below for examples and options to the main method +columnize+. +# +# +# == License +# +# Columnize is copyright (C) 2007-2011, 2013 Rocky Bernstein +# +# +# All rights reserved. You can redistribute and/or modify it under +# the same terms as Ruby. +# +# Also available in Python (columnize), and Perl (Array::Columnize) + +module Columnize + # Pull in the rest of my pieces + ROOT_DIR = File.dirname(__FILE__) + %w(opts columnize version).each do |submod| + require File.join %W(#{ROOT_DIR} columnize #{submod}) + end + + # Add +columnize_opts+ instance variable to classes that mix in this module. The type should be a kind of hash in file +columnize/opts+. + attr_accessor :columnize_opts + + # Columnize.columize([args]) => String + # + # Return a string from an array with embedded newlines formatted so + # that when printed the columns are aligned. + # + # For example, for a line width of 4 characters (arranged vertically): + # a = (1..4).to_a + # Columnize.columnize(a) => '1 3\n2 4\n' + # + # Alternatively: + # a.columnize => '1 3\n2 4\n' + # + # Arranged horizontally: + # a.columnize(:arrange_vertical => false) => + # ['1', '2,', '3', '4'] => '1 2\n3 4\n' + # + # Formatted as an array using format specifier '%02d': + # puts (1..10).to_a.columnize(:arrange_array => true, :colfmt => '%02d', + # :displaywidth => 10) => + # [01, 02, + # 03, 04, + # 05, 06, + # 07, 08, + # 09, 10, + # ] + # + # Each column is only as wide as necessary. By default, columns are + # separated by two spaces. Options are available for setting + # * the line display width + # * a column separator + # * a line prefix + # * a line suffix + # * A format specify for formatting each item each array item to a string + # * whether to ignore terminal codes in text size calculation + # * whether to left justify text instead of right justify + # * whether to format as an array - with surrounding [] and + # separating ', ' + def self.columnize(*args) + list = args.shift + opts = parse_columnize_options(args) + Columnizer.new(list, opts).columnize + end + + # Adds columnize_opts to the singleton level of included class + def self.included(base) + # screw class variables, we'll use an instance variable on the class singleton + class << base + attr_accessor :columnize_opts + end + base.columnize_opts = DEFAULT_OPTS.dup + end + + def columnize(*args) + return Columnize.columnize(*args) if args.length > 1 + opts = args.empty? ? {} : args.pop + @columnize_opts ||= self.class.columnize_opts.dup + @columnizer ||= Columnizer.new(self, @columnize_opts) + # make sure that any changes to list or opts get passed to columnizer + @columnizer.list = self unless @columnizer.list == self + @columnizer.opts = @columnize_opts.merge(opts) unless @columnizer.opts == @columnize_opts and opts.empty? + @columnizer.columnize + end +end + +# Mix Columnize into Array +Array.send :include, Columnize + +# Demo this sucker +if __FILE__ == $0 + # include Columnize + + a = (1..80).to_a + puts a.columnize :arrange_array => true + puts '=' * 50 + + b = (1..10).to_a + puts b.columnize(:displaywidth => 10) + + puts '-' * 50 + puts b.columnize(:arrange_array => true, :colfmt => '%02d', :displaywidth => 10) + + [[4, 4], [4, 7], [100, 80]].each do |width, num| + data = (1..num).map{|i| i } + [[false, 'horizontal'], [true, 'vertical']].each do |bool, dir| + puts "Width: #{width}, direction: #{dir}" + print Columnize.columnize(data, :displaywidth => width, :colsep => ' ', :arrange_vertical => bool, :ljust => :auto) + end + end + + puts Columnize.columnize(5) + puts Columnize.columnize([]) + puts Columnize.columnize(["a", 2, "c"], :displaywidth =>10, :colsep => ', ') + puts Columnize.columnize(["oneitem"]) + puts Columnize.columnize(["one", "two", "three"]) + data = ["one", "two", "three", + "for", "five", "six", + "seven", "eight", "nine", + "ten", "eleven", "twelve", + "thirteen", "fourteen", "fifteen", + "sixteen", "seventeen", "eightteen", + "nineteen", "twenty", "twentyone", + "twentytwo", "twentythree", "twentyfour", + "twentyfive","twentysix", "twentyseven"] + + puts Columnize.columnize(data) + puts Columnize.columnize(data, 80, ' ', false) +end diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/columnize/Makefile b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/Makefile new file mode 100644 index 0000000..aa4f784 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/Makefile @@ -0,0 +1,11 @@ +# Whatever it is you want to do, it should be handled by the main +# (parent) Makefile. So reissue make from there. +PHONY=check all + +#: Default target - the parent's testing or "check" target +all: check + true + +#: Whatever it is you want to do, it should be handled by the parent +%: + $(MAKE) -C ../.. $@ diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/columnize/columnize.rb b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/columnize.rb new file mode 100644 index 0000000..fd394ea --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/columnize.rb @@ -0,0 +1,159 @@ +# Copyright (C) 2007-2011, 2013 Rocky Bernstein +# +# +# Part of Columnize to format in either direction +module Columnize + class Columnizer + ARRANGE_ARRAY_OPTS = {:array_prefix => '[', :line_prefix => ' ', :line_suffix => ',', :array_suffix => ']', :colsep => ', ', :arrange_vertical => false} + OLD_AND_NEW_KEYS = {:lineprefix => :line_prefix, :linesuffix => :line_suffix} + # TODO: change colfmt to cell_format; change colsep to something else + ATTRS = [:arrange_vertical, :array_prefix, :array_suffix, :line_prefix, :line_suffix, :colfmt, :colsep, :displaywidth, :ljust] + + attr_reader :list, :opts + + def initialize(list=[], opts={}) + self.list = list + self.opts = DEFAULT_OPTS.merge(opts) + end + + def list=(list) + @list = list + if @list.is_a? Array + @short_circuit = @list.empty? ? "\n" : nil + else + @short_circuit = '' + @list = [] + end + end + + # TODO: freeze @opts + def opts=(opts) + @opts = opts + OLD_AND_NEW_KEYS.each {|old, new| @opts[new] = @opts.delete(old) if @opts.keys.include?(old) and !@opts.keys.include?(new) } + @opts.merge!(ARRANGE_ARRAY_OPTS) if @opts[:arrange_array] + set_attrs_from_opts + end + + def update_opts(opts) + self.opts = @opts.merge(opts) + end + + def columnize + return @short_circuit if @short_circuit + + rows, colwidths = min_rows_and_colwidths + ncols = colwidths.length + justify = lambda {|t, c| + @ljust ? t.ljust(colwidths[c]) : t.rjust(colwidths[c]) + } + textify = lambda do |row| + row.map!.with_index(&justify) unless ncols == 1 && @ljust + "#{@line_prefix}#{row.join(@colsep)}#{@line_suffix}" + end + + text = rows.map(&textify) + text.first.sub!(/^#{@line_prefix}/, @array_prefix) unless @array_prefix.empty? + text.last.sub!(/#{@line_suffix}$/, @array_suffix) unless @array_suffix.empty? + text.join("\n") # + "\n" # if we want extra separation + end + + # TODO: make this a method, rather than a function (?) + # compute the smallest number of rows and the max widths for each column + def min_rows_and_colwidths + list = @list.map &@stringify + cell_widths = list.map(&@term_adjuster).map(&:size) + + # Set default arrangement: one atom per row + cell_width_max = cell_widths.max + result = [arrange_by_row(list, list.size, 1), [cell_width_max]] + + # If any atom > @displaywidth, stop and use one atom per row. + return result if cell_width_max > @displaywidth + + # For horizontal arrangement, we want to *maximize* the number + # of columns. Thus the candidate number of rows (+sizes+) starts + # at the minumum number of rows, 1, and increases. + + # For vertical arrangement, we want to *minimize* the number of + # rows. So here the candidate number of columns (+sizes+) starts + # at the maximum number of columns, list.length, and + # decreases. Also the roles of columns and rows are reversed + # from horizontal arrangement. + + # Loop from most compact arrangement to least compact, stopping + # at the first successful packing. The below code is tricky, + # but very cool. + # + # FIXME: In the below code could be DRY'd. (The duplication got + # introduced when I revised the code - rocky) + if @arrange_vertical + (1..list.length).each do |size| + other_size = (list.size + size - 1) / size + colwidths = arrange_by_row(cell_widths, other_size, size).map(&:max) + totwidth = colwidths.inject(&:+) + ((colwidths.length-1) * @colsep.length) + return [arrange_by_column(list, other_size, size), colwidths] if + totwidth <= @displaywidth + end + else + list.length.downto(1).each do |size| + other_size = (list.size + size - 1) / size + colwidths = arrange_by_column(cell_widths, other_size, size).map(&:max) + totwidth = colwidths.inject(&:+) + ((colwidths.length-1) * @colsep.length) + return [arrange_by_row(list, other_size, size), colwidths] if + totwidth <= @displaywidth + end + end + result + end + + # Given +list+, +ncols+, +nrows+, arrange the one-dimensional + # array into a 2-dimensional lists of lists organized by rows. + # + # In either horizontal or vertical arrangement, we will need to + # access this for the list data or for the width + # information. + # + # Here is an example: + # arrange_by_row((1..5).to_a, 3, 2) => + # [[1,2], [3,4], [5]], + def arrange_by_row(list, nrows, ncols) + (0...nrows).map {|r| list[r*ncols, ncols] }.compact + end + + # Given +list+, +ncols+, +nrows+, arrange the one-dimensional + # array into a 2-dimensional lists of lists organized by columns. + # + # In either horizontal or vertical arrangement, we will need to + # access this for the list data or for the width + # information. + # + # Here is an example: + # arrange_by_column((1..5).to_a, 2, 3) => + # [[1,3,5], [2,4]] + def arrange_by_column(list, nrows, ncols) + (0...ncols).map do |i| + (0..nrows-1).inject([]) do |row, j| + k = i + (j * ncols) + k < list.length ? row << list[k] : row + end + end + end + + def set_attrs_from_opts + ATTRS.each {|attr| self.instance_variable_set "@#{attr}", @opts[attr] } + + @ljust = !@list.all? {|datum| datum.kind_of?(Numeric)} if @ljust == :auto + @displaywidth -= @line_prefix.length + @displaywidth = @line_prefix.length + 4 if @displaywidth < 4 + @stringify = @colfmt ? lambda {|li| @colfmt % li } : lambda {|li| li.to_s } + @term_adjuster = @opts[:term_adjust] ? lambda {|c| c.gsub(/\e\[.*?m/, '') } : lambda {|c| c } + end + end +end + +# Demo +if __FILE__ == $0 + Columnize::DEFAULT_OPTS = {:line_prefix => '', :displaywidth => 80} + puts Columnize::Columnizer.new.arrange_by_row((1..5).to_a, 2, 3).inspect + puts Columnize::Columnizer.new.arrange_by_column((1..5).to_a, 2, 3).inspect +end diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/columnize/opts.rb b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/opts.rb new file mode 100644 index 0000000..81e4c20 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/opts.rb @@ -0,0 +1,35 @@ +module Columnize + computed_displaywidth = (ENV['COLUMNS'] || '80').to_i + computed_displaywidth = 80 unless computed_displaywidth >= 10 + + # When an option is not specified for the below keys, these are the defaults. + DEFAULT_OPTS = { + :arrange_array => false, + :arrange_vertical => true, + :array_prefix => '', + :array_suffix => '', + :colfmt => nil, + :colsep => ' ', + :displaywidth => computed_displaywidth, + :line_prefix => '', + :line_suffix => '', + :ljust => :auto, + :term_adjust => false + } + + # Options parsing routine for Columnize::columnize. In the preferred + # newer style, +args+ is a hash where each key is one of the option names. + # + # In the older style positional arguments are used and the positions + # are in the order: +displaywidth+, +colsep+, +arrange_vertical+, + # +ljust+, and +line_prefix+. + def self.parse_columnize_options(args) + if 1 == args.size && args[0].kind_of?(Hash) # explicitly passed as a hash + args[0] + elsif !args.empty? # passed as ugly positional parameters. + Hash[args.zip([:displaywidth, :colsep, :arrange_vertical, :ljust, :line_prefix]).map(&:reverse)] + else + {} + end + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/lib/columnize/version.rb b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/version.rb new file mode 100644 index 0000000..598a9ad --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/lib/columnize/version.rb @@ -0,0 +1,7 @@ +# Sets constant Columnize::VERSION, the version number of +# this package. It is used in Gem creation but can also be consulted after +# require'ing 'columnize'. +module Columnize + # The current version of this package + VERSION = '0.8.9' +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-columnize-array.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-columnize-array.rb new file mode 100755 index 0000000..2231fba --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-columnize-array.rb @@ -0,0 +1,48 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnize module +class TestColumnizeArray < Test::Unit::TestCase + # Ruby 1.8 form of require_relative + TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + ENV['COLUMNS'] = '80' + require File.join(TOP_SRC_DIR, 'columnize.rb') + + # test columnize + def test_arrange_array + data = (1..80).to_a + expect = "[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,\n" + + " 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n" + + " 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,\n" + + " 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80]" + assert_equal(expect, + data.columnize(:arrange_array => true, :displaywidth => 80), + "columnize_opts -> arrange_array") + end + + def test_displaywidth + expect = "1 5 9\n" + + "2 6 10\n" + + "3 7\n" + + "4 8" + data = (1..10).to_a + assert_equal(expect, data.columnize(:displaywidth => 10), "displaywidth") + end + + def test_colfmt + expect = "[01, 02,\n" + + " 03, 04,\n" + + " 05, 06,\n" + + " 07, 08,\n" + + " 09, 10]" + data = (1..10).to_a + assert_equal(expect, data.columnize(:arrange_array => true, :colfmt => '%02d', :displaywidth => 10), "arrange_array, colfmt, displaywidth") + end + + def test_backwards_compatiblity + foo = [] + data = (1..11).to_a + expect = " 1 2 3\n 4 5 6\n 7 8 9\n10 11" + assert_equal expect, foo.columnize(data, :displaywidth => 10, :arrange_vertical => false) + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-columnize.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-columnize.rb new file mode 100755 index 0000000..7963b42 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-columnize.rb @@ -0,0 +1,74 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnize module +class TestColumnize < Test::Unit::TestCase + # Ruby 1.8 form of require_relative + TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + require File.join(TOP_SRC_DIR, 'columnize.rb') + + # test columnize + def test_basic + assert_equal("1, 2, 3", Columnize::columnize([1, 2, 3], 10, ', ')) + assert_equal("", Columnize::columnize(5)) + assert_equal("1 3\n2 4", Columnize::columnize(['1', '2', '3', '4'], 4)) + assert_equal("1 2\n3 4", Columnize::columnize(['1', '2', '3', '4'], 4, ' ', false)) + assert_equal("\n", Columnize::columnize([])) + + assert_equal("oneitem", Columnize::columnize(["oneitem"])) + + data = (0..54).map{|i| i.to_s} + assert_equal( + "0, 6, 12, 18, 24, 30, 36, 42, 48, 54\n" + + "1, 7, 13, 19, 25, 31, 37, 43, 49\n" + + "2, 8, 14, 20, 26, 32, 38, 44, 50\n" + + "3, 9, 15, 21, 27, 33, 39, 45, 51\n" + + "4, 10, 16, 22, 28, 34, 40, 46, 52\n" + + "5, 11, 17, 23, 29, 35, 41, 47, 53", + Columnize::columnize(data, 39, ', ', true, false)) + + assert_equal( + " 0, 1, 2, 3, 4, 5, 6, 7, 8, 9\n" + + "10, 11, 12, 13, 14, 15, 16, 17, 18, 19\n" + + "20, 21, 22, 23, 24, 25, 26, 27, 28, 29\n" + + "30, 31, 32, 33, 34, 35, 36, 37, 38, 39\n" + + "40, 41, 42, 43, 44, 45, 46, 47, 48, 49\n" + + "50, 51, 52, 53, 54", + Columnize::columnize(data, 39, ', ', false, false)) + + + assert_equal( + " 0, 1, 2, 3, 4, 5, 6, 7, 8\n" + + " 9, 10, 11, 12, 13, 14, 15, 16, 17\n" + + " 18, 19, 20, 21, 22, 23, 24, 25, 26\n" + + " 27, 28, 29, 30, 31, 32, 33, 34, 35\n" + + " 36, 37, 38, 39, 40, 41, 42, 43, 44\n" + + " 45, 46, 47, 48, 49, 50, 51, 52, 53\n" + + " 54", + Columnize::columnize(data, 39, ', ', false, false, ' ')) + + + data = ["one", "two", "three", + "for", "five", "six", + "seven", "eight", "nine", + "ten", "eleven", "twelve", + "thirteen", "fourteen", "fifteen", + "sixteen", "seventeen", "eightteen", + "nineteen", "twenty", "twentyone", + "twentytwo", "twentythree", "twentyfour", + "twentyfive","twentysix", "twentyseven"] + + assert_equal( +"one two three for five six \n" + +"seven eight nine ten eleven twelve \n" + +"thirteen fourteen fifteen sixteen seventeen eightteen \n" + +"nineteen twenty twentyone twentytwo twentythree twentyfour\n" + +"twentyfive twentysix twentyseven", Columnize::columnize(data, 80, ' ', false)) + + assert_equal( +"one five nine thirteen seventeen twentyone twentyfive \n" + +"two six ten fourteen eightteen twentytwo twentysix \n" + +"three seven eleven fifteen nineteen twentythree twentyseven\n" + +"for eight twelve sixteen twenty twentyfour ", Columnize::columnize(data, 80)) + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-columnizer.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-columnizer.rb new file mode 100755 index 0000000..fe27f73 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-columnizer.rb @@ -0,0 +1,112 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnizer class +class TestColumnizer < Test::Unit::TestCase + TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + require File.join(TOP_SRC_DIR, 'columnize.rb') + + Columnize::Columnizer.class_eval 'attr_reader :stringify, :short_circuit, :term_adjuster' + Columnize::Columnizer.class_eval 'attr_reader *ATTRS' + + # SETTING OPTS IN INITIALIZE + def test_passed_in_opts + # passed in opts should be merged with DEFAULT_OPTS + c = Columnize::Columnizer.new([], :displaywidth => 15) + assert_equal false, c.opts[:term_adjust], 'term_adjust comes from DEFAULT_OPTS' + assert_equal 15, c.opts[:displaywidth], 'displaywidth should override DEFAULT_OPTS' + end + + def test_ljust_attr + c = Columnize::Columnizer.new([1,2,3], {:ljust => :auto}) + assert_equal false, c.ljust, 'ljust: :auto should transform to false when all values are numeric' + c = Columnize::Columnizer.new(['1', 2, 3], {:ljust => :auto}) + assert_equal true, c.ljust, 'ljust: :auto should transform to true when not all values are numeric' + c = Columnize::Columnizer.new([], {:ljust => false}) + assert_equal false, c.ljust, 'ljust: false should stay false' + c = Columnize::Columnizer.new([], {:ljust => true}) + assert_equal true, c.ljust, 'ljust: true should stay true' + end + + def test_stringify_attr + c = Columnize::Columnizer.new + assert_equal '1.0', c.stringify[1.0], 'without colfmt, should be to_s' + c.update_opts :colfmt => '%02d' + assert_equal '01', c.stringify[1.0], 'without colfmt, should be to_s' + end + + def test_short_circuit_attr + c = Columnize::Columnizer.new + assert_equal "\n", c.short_circuit, 'should explicitly state when empty' + c.list = 1 + assert_equal '', c.short_circuit, 'should be an empty string when not an array' + c.list = [1] + assert_equal nil, c.short_circuit, 'should be nil when list is good' + end + + def test_term_adjuster_attr + c = Columnize::Columnizer.new + assert_equal 'abc', c.term_adjuster['abc'] + assert_equal "\e[0;31mObject\e[0;4m", c.term_adjuster["\e[0;31mObject\e[0;4m"] + c.update_opts :term_adjust => true + assert_equal 'abc', c.term_adjuster['abc'] + assert_equal 'Object', c.term_adjuster["\e[0;31mObject\e[0;4m"] + end + + def test_displaywidth_attr + c = Columnize::Columnizer.new [], :displaywidth => 10, :line_prefix => ' ' + assert_equal 12, c.displaywidth, 'displaywidth within 4 of line_prefix.length' + c.update_opts :line_prefix => ' ' + assert_equal 8, c.displaywidth, 'displaywidth not within 4 of line_prefix.length' + end + + # COLUMNIZE + def test_columnize_with_short_circuit + msg = 'Johnny 5 is alive!' + c = Columnize::Columnizer.new + c.instance_variable_set(:@short_circuit, msg) + assert_equal msg, c.columnize, 'columnize should return short_circuit message if set' + end + + def test_columnize_applies_ljust + c = Columnize::Columnizer.new [1,2,3,10,20,30], :displaywidth => 10, :ljust => false, :arrange_vertical => false + assert_equal " 1 2 3\n10 20 30", c.columnize, "ljust: #{c.ljust}" + c.update_opts :ljust => true + assert_equal "1 2 3 \n10 20 30", c.columnize, "ljust: #{c.ljust}" + end + + def no_test_columnize_applies_colsep_and_prefix_and_suffix + c = Columnize::Columnizer.new [1,2,3] + assert_equal "1 2 3", c.columnize + c.update_opts :line_prefix => '>', :colsep => '-', :line_suffix => '<' + assert_equal ">1-2-3<", c.columnize + end + + def test_columnize_applies_array_prefix_and_suffix + c = Columnize::Columnizer.new [1,2,3] + assert_equal "1 2 3", c.columnize + c.update_opts :array_prefix => '>', :array_suffix => '<' + assert_equal ">1 2 3<", c.columnize + end + + # NOTE: min_rows_and_colwidths tested in test-min_rows_and_colwidths.rb + + # arrange_rows_and_cols + def test_arrange_rows_and_cols + rows = Columnize::Columnizer.new.arrange_by_row((1..9).to_a, 3, 3) + assert_equal [[1,2,3],[4,5,6],[7,8,9]], rows, 'rows for (1..9), 3, 3' + + cols = Columnize::Columnizer.new.arrange_by_column((1..9).to_a, 3, 3) + assert_equal [[1,4,7],[2,5,8],[3,6,9]], cols, 'cols for (1..9), 3, 3' + + rows = Columnize::Columnizer.new.arrange_by_row((1..5).to_a, 3, 2) + assert_equal [[1,2],[3,4],[5]], rows, 'rows for (1..5, 2, 3)' + + cols = Columnize::Columnizer.new.arrange_by_column((1..5).to_a, 3, 2) + assert_equal [[1,3,5],[2,4]], cols, 'cols for (1..5, 2, 3)' + end + + def test_set_attrs_from_opts + assert(true, 'test set_attrs_from_opts') + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-hashparm.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-hashparm.rb new file mode 100755 index 0000000..f2a8f40 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-hashparm.rb @@ -0,0 +1,43 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnize module +class TestHashFormat < Test::Unit::TestCase + TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + require File.join(TOP_SRC_DIR, 'columnize.rb') + + def test_parse_columnize_options + assert Columnize.parse_columnize_options([{}]).kind_of?(Hash) + assert_equal 90, Columnize.parse_columnize_options([90])[:displaywidth] + opts = Columnize.parse_columnize_options([70, '|']) + assert_equal 70, opts[:displaywidth] + assert_equal '|', opts[:colsep] + end + + def test_new_hash + hash = {:displaywidth => 40, :colsep => ', ', :term_adjust => true,} + assert_equal(hash, Columnize.parse_columnize_options([hash]), "parse_columnize_options returns same hash it was passed") + end + + def test_array + data = (0..54).to_a + expected = "[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n" + + " 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n" + + " 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n" + + " 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n" + + " 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\n" + + " 50, 51, 52, 53, 54]" + assert_equal(expected, Columnize.columnize(data, :arrange_array => true, :ljust => false, :displaywidth => 39)) + end + + def test_justify + data = (0..54).to_a + expected = "[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,\n" + + " 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\n" + + " 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,\n" + + " 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\n" + + " 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,\n" + + " 50, 51, 52, 53, 54]" + assert_equal(expected, Columnize.columnize(data, :arrange_array => true, :displaywidth => 39)) + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-issue3.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-issue3.rb new file mode 100755 index 0000000..11034d5 --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-issue3.rb @@ -0,0 +1,24 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnize module for github issue #3 +class TestIssue3 < Test::Unit::TestCase + @@TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + require File.join(@@TOP_SRC_DIR, 'columnize.rb') + + # test columnize + def test_long_column + data = ["what's", "upppppppppppppppppp"] + data.columnize_opts = Columnize::DEFAULT_OPTS.merge :displaywidth => 7, :arrange_vertical => false + assert_equal("what's\nupppppppppppppppppp", data.columnize) + assert_equal("what's\nupppppppppppppppppp", data.columnize(:arrange_vertical => true)) + end + + def test_long_column_with_ljust + data = ["whaaaaaat's", "up"] + data.columnize_opts = Columnize::DEFAULT_OPTS.merge :displaywidth => 7, :arrange_vertical => false, :ljust => true + assert_equal("whaaaaaat's\nup", data.columnize) + assert_equal("whaaaaaat's\n up", data.columnize(:ljust => false)) + assert_equal("whaaaaaat's\nup", data.columnize(:arrange_vertical => true)) + end +end diff --git a/vendor/bundle/gems/columnize-0.8.9/test/test-min_rows_and_colwidths.rb b/vendor/bundle/gems/columnize-0.8.9/test/test-min_rows_and_colwidths.rb new file mode 100755 index 0000000..cf2b57d --- /dev/null +++ b/vendor/bundle/gems/columnize-0.8.9/test/test-min_rows_and_colwidths.rb @@ -0,0 +1,65 @@ +#!/usr/bin/env ruby +require 'test/unit' + +# Test of Columnize#min_rows_and_colwidths +class TestComputeRowsAndColwidths < Test::Unit::TestCase + # Ruby 1.8 form of require_relative + TOP_SRC_DIR = File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib') + require File.join(TOP_SRC_DIR, 'columnize.rb') + + VOPTS = Columnize::DEFAULT_OPTS.merge(:displaywidth => 80) + HOPTS = VOPTS.merge(:arrange_vertical => false) + + def min_rows_and_colwidths(list, opts) + Columnize::Columnizer.new(list, opts).min_rows_and_colwidths + end + + def test_colwidths + data = ["one", "two", "three", + "four", "five", "six", + "seven", "eight", "nine", + "ten", "eleven", "twelve", + "thirteen", "fourteen", "fifteen", + "sixteen", "seventeen", "eightteen", + "nineteen", "twenty", "twentyone", + "twentytwo", "twentythree", "twentyfour", + "twentyfive","twentysix", "twentyseven"] + + [['horizontal', HOPTS, [10, 9, 11, 9, 11, 10], 5, 6], + ['vertical' , VOPTS, [5, 5, 6, 8, 9, 11, 11], 4, 7]].each do + |direction, opts, expect_colwidths, expect_rows, expect_cols| + rows, colwidths = min_rows_and_colwidths(data, opts) + assert_equal(expect_colwidths, colwidths, "colwidths - #{direction}") + assert_equal(expect_rows, rows.length, + "number of rows - #{direction}") + assert_equal(expect_cols, rows.first.length, + "number of cols - #{direction}") + end + end + + def test_horizontal_vs_vertical + data = (0..54).map{|i| i.to_s} + + [['horizontal', HOPTS.merge(:displaywidth => 39), [2,2,2,2,2,2,2,2,2,2]], + ['vertical' , VOPTS.merge(:displaywidth => 39), [1,2,2,2,2,2,2,2,2,2]]].each do + |direction, opts, expect| + rows, colwidths = min_rows_and_colwidths(data, opts) + assert_equal(expect, colwidths, "colwidths #{direction}") + assert_equal(6, rows.length, "number of rows - #{direction}") + assert_equal(10, rows.first.length, "number of cols - #{direction}") + end + end + + def test_displaywidth_smaller_than_largest_atom + data = ['a' * 100, 'b', 'c', 'd', 'e'] + + [['horizontal', HOPTS], + ['vertical' , VOPTS]].each do + |direction, opts| + rows, colwidths = min_rows_and_colwidths(data, opts) + assert_equal([100], colwidths, "colwidths #{direction}") + assert_equal(5, rows.length, "number of rows - #{direction}") + assert_equal(1, rows.first.length, "number of cols - #{direction}") + end + end +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/.travis.yml b/vendor/bundle/gems/debugger-linecache-1.2.0/.travis.yml new file mode 100644 index 0000000..fa2eee6 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/.travis.yml @@ -0,0 +1,5 @@ +before_install: bundle init --gemspec=debugger-linecache.gemspec +rvm: +- 1.9.2 +- 1.9.3 +- 2.0.0 diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/CHANGELOG.md b/vendor/bundle/gems/debugger-linecache-1.2.0/CHANGELOG.md new file mode 100644 index 0000000..671b891 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/CHANGELOG.md @@ -0,0 +1,54 @@ +## 1.2.0 +* Replace C extension with ruby +* No more debugger-ruby_core_source dependency + +## 1.1.2 +* Fix rdoc/ri warning + +## 1.1.1 +* Depend on working version of debugger-ruby-core-source + +## 1.1.0 +* Point to new debugger-ruby_core_source API +* rename trace_nums19 ext to trace_nums +* Renable Rakefile and tests +* General cleanup + +## 1.0.1 +* Point to debugger-ruby_core_source as dependency + +## 1.0.0 +* Initial release - fork and release latest linecache + +## From previous gem's NEWS file + +0.5 (7/23/09) +- updated for Ruby 1.9 + +0.43 +06-12-08 +- tolerance for finding windows extension in lib rather than ext. + +0.41 +- add test/data/* to gem. + +0.4 +- Credit Ryan Davis and ParseTree. + +0.3 +- Add tracelines: get line numbers that can be stopped at. + +- Add routines to allow line-number + remapping and filename remapping. + +- Add access methods to get the number of lines in a file. + +0.2 +- Make this work with ruby-debug-base. Add reload-on-change parameters. + add checkcache, cache, cached? sha1, and stat methods. + +- Use SCRIPT_LINES__. + +0.1 + +- Initial release of LineCache, a module for reading and caching lines. diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/CONTRIBUTING.md b/vendor/bundle/gems/debugger-linecache-1.2.0/CONTRIBUTING.md new file mode 100644 index 0000000..c796c4f --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/CONTRIBUTING.md @@ -0,0 +1 @@ +Thanks for trying out this project! [See here for contribution guidelines.](http://tagaholic.me/contributing.html) diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/LICENSE.txt b/vendor/bundle/gems/debugger-linecache-1.2.0/LICENSE.txt new file mode 100644 index 0000000..b0b7edc --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/LICENSE.txt @@ -0,0 +1,22 @@ +The MIT LICENSE + +Copyright (c) 2012 Gabriel Horner + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_CHANGELOG b/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_CHANGELOG new file mode 100644 index 0000000..ca74b9c --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_CHANGELOG @@ -0,0 +1,68 @@ +2009-07-23 13:15 mark-moseley + + * Updated for Ruby 1.9 + +2008-06-12 00:04 rockyb + + * .: Look in lib as well as ext for trace_nums. Win32 puts it in + lib. + +2008-04-11 02:54 rockyb + + * .: Wasn't listing extension to for C compilation? + +2008-04-10 20:02 rockyb + + * .: Forgot to add test/data to the gem. + +2008-03-09 23:24 rockyb + + * .: Deal with Depricated win32. + +2008-02-10 13:59 rockyb + + * .: Go over Rakefile and doc for 0.3 release. + +2008-01-28 15:35 rockyb + + * .: Change line number return from a Set to an Array. + +2008-01-23 16:06 rockyb + + * .: Show add_lines level, nicer formatting including \n for end. + +2008-01-20 16:31 rockyb + + * .: Add module TraceLineNumbers for extracting the stoppable lines + in a + Ruby program. + +2008-01-14 12:27 rockyb + + * .: Add parameter to getline and getlines to reload file on + change. Add + option on clear_file_cache to clear out SCRIPT_LINES__ as well. + TESTS ARE NEEDED. + Update to version 0.2. + +2007-12-10 16:24 rockyb + + * : release 0.1 + +2007-12-09 17:17 rockyb + + * : Better tests mean more bugs found. "rake" defaults now to + "test". + +2007-12-09 13:15 rockyb + + * : NEWS, README, linecache.rb: Add $Id$ line + test-linecache.rb: make executable + Rakefile: Correct documentation + +2007-12-09 12:58 rockyb + + * : Initial import of LineCache, a module for reading and caching + lines. + This time to trunk. + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_README b/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_README new file mode 100644 index 0000000..2e5e180 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/OLD_README @@ -0,0 +1,50 @@ += LineCache - A module to read and cache file information of a Ruby program. + +== SYNOPSIS + +The LineCache module allows one to get any line from any file, caching +the lines and file information on first access to the file. Although +the file may be any file, the common use is when the file is a Ruby +script since parsing of the file is done to figure out where the +statement boundaries are. + +The routines here may be is useful when a small random sets of lines +are read from a single file, in particular in a debugger to show +source lines. + +== Summary + + require 'linecache' + lines = LineCache::getlines('/tmp/myruby.rb') + # The following lines have same effect as the above. + $: << '/tmp' + Dir.chdir('/tmp') {lines = LineCache::getlines('myruby.rb') + + line = LineCache::getline('/tmp/myruby.rb', 6) + # Note lines[6] == line (if /tmp/myruby.rb has 6 lines) + + LineCache::clear_file_cache + LineCache::clear_file_cache('/tmp/myruby.rb') + LineCache::update_cache # Check for modifications of all cached files. + +== Credits + + This is a port of the module of the same name from the Python distribution. + + The idea for how TraceLineNumbers works, and some code was taken + from ParseTree by Ryan Davis. + +== Other stuff + +Author:: Rocky Bernstein +License:: Copyright (c) 2007, 2008 Rocky Bernstein + Released under the GNU GPL 2 license + +== Warranty + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +$Id$ diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/README.md b/vendor/bundle/gems/debugger-linecache-1.2.0/README.md new file mode 100644 index 0000000..d133aac --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/README.md @@ -0,0 +1,20 @@ +## Description +Fork of linecache for [debugger](http://github.com/cldwalker/debugger) +For more info see OLD\_README. + +[![Build Status](https://secure.travis-ci.org/cldwalker/debugger-linecache.png?branch=master)](http://travis-ci.org/cldwalker/debugger-linecache) + +## Credits + +* Original authors: R. Bernstein, Mark Moseley +* @ko1 - replace C extension with ruby + +## TODO +* Fix todo test + +## Contributing +[See here](http://tagaholic.me/contributing.html) + +## LICENSE + +This library is licensed under LICENSE.txt. Original was GNU. diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/Rakefile b/vendor/bundle/gems/debugger-linecache-1.2.0/Rakefile new file mode 100644 index 0000000..c925c88 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/Rakefile @@ -0,0 +1,28 @@ +# -*- Ruby -*- + +require 'rubygems/package_task' +require 'rake/testtask' + +desc "Test everything." +test_task = task :test => :lib do + Rake::TestTask.new(:test) do |t| + # TODO: fix test-lnum + t.test_files = Dir['test/test-*.rb'] - ['test/test-lnum.rb'] + t.verbose = true + end +end + +desc "Test everything - same as test." +task :check => :test + +base_spec = eval(File.read('debugger-linecache.gemspec'), binding, 'debugger-linecache.gemspec') + +Gem::PackageTask.new(base_spec) do |pkg| + pkg.need_tar = true +end + +desc "Remove built files" +task :clean => [:clobber_package] do +end + +task :default => [:test] diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/debugger-linecache.gemspec b/vendor/bundle/gems/debugger-linecache-1.2.0/debugger-linecache.gemspec new file mode 100644 index 0000000..83f5942 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/debugger-linecache.gemspec @@ -0,0 +1,20 @@ +# -*- encoding: utf-8 -*- +require 'rubygems' unless defined? Gem +require File.dirname(__FILE__) + "/lib/debugger/linecache" + +Gem::Specification.new do |s| + s.name = "debugger-linecache" + s.version = Debugger::Linecache::VERSION + s.authors = ["R. Bernstein", "Mark Moseley", "Gabriel Horner"] + s.email = "gabriel.horner@gmail.com" + s.homepage = "http://github.com/cldwalker/debugger-linecache" + s.summary = %q{Read file with caching} + s.description = %q{Linecache is a module for reading and caching lines. This may be useful for +example in a debugger where the same lines are shown many times. +} + s.required_rubygems_version = ">= 1.3.6" + s.extra_rdoc_files = ["README.md"] + s.files = `git ls-files`.split("\n") + s.add_development_dependency 'rake', '~> 0.9.2.2' + s.license = "MIT" +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/lib/debugger/linecache.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/debugger/linecache.rb new file mode 100644 index 0000000..d35255e --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/debugger/linecache.rb @@ -0,0 +1,5 @@ +module Debugger + module Linecache + VERSION = '1.2.0' + end +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/lib/linecache19.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/linecache19.rb new file mode 100755 index 0000000..41674ce --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/linecache19.rb @@ -0,0 +1,407 @@ +# $Id$ +# +# Copyright (C) 2007, 2008 Rocky Bernstein +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 USA. +# + +# Author:: Rocky Bernstein (mailto:rockyb@rubyforge.net) +# +# = linecache +# A module to read and cache lines of a Ruby program. + +# == SYNOPSIS +# +# The LineCache module allows one to get any line from any file, +# caching lines of the file on first access to the file. Although the +# file may be any file, the common use is when the file is a Ruby +# script since parsing of the file is done to figure out where the +# statement boundaries are. +# +# The routines here may be is useful when a small random sets of lines +# are read from a single file, in particular in a debugger to show +# source lines. +# +# +# require 'linecache19' +# lines = LineCache::getlines('/tmp/myruby.rb') +# # The following lines have same effect as the above. +# $: << '/tmp' +# Dir.chdir('/tmp') {lines = LineCache::getlines('myruby.rb') +# +# line = LineCache::getline('/tmp/myruby.rb', 6) +# # Note lines[6] == line (if /tmp/myruby.rb has 6 lines) +# +# LineCache::clear_file_cache +# LineCache::clear_file_cache('/tmp/myruby.rb') +# LineCache::update_cache # Check for modifications of all cached files. +# +# Some parts of the interface is derived from the Python module of the +# same name. +# + +# Defining SCRIPT_LINES__ causes Ruby to cache the lines of files +# it reads. The key the setting of __FILE__ at the time when Ruby does +# its read. LineCache keeps a separate copy of the lines elsewhere +# and never destroys SCRIPT_LINES__ +SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ + +require 'digest/sha1' +require 'set' + +require 'tracelines19' + +# = module LineCache +# A module to read and cache lines of a Ruby program. +module LineCache + LineCacheInfo = Struct.new(:stat, :line_numbers, :lines, :path, :sha1) unless + defined?(LineCacheInfo) + + # The file cache. The key is a name as would be given by Ruby for + # __FILE__. The value is a LineCacheInfo object. + @@file_cache = {} + + # Maps a string filename (a String) to a key in @@file_cache (a + # String). + # + # One important use of @@file2file_remap is mapping the a full path + # of a file into the name stored in @@file_cache or given by Ruby's + # __FILE__. Applications such as those that get input from users, + # may want canonicalize a file name before looking it up. This map + # gives a way to do that. + # + # Another related use is when a template system is used. Here we'll + # probably want to remap not only the file name but also line + # ranges. Will probably use this for that, but I'm not sure. + @@file2file_remap = {} + @@file2file_remap_lines = {} + + # Clear the file cache entirely. + def clear_file_cache() + @@file_cache = {} + @@file2file_remap = {} + @@file2file_remap_lines = {} + end + module_function :clear_file_cache + + # Return an array of cached file names + def cached_files() + @@file_cache.keys + end + module_function :cached_files + + # Discard cache entries that are out of date. If +filename+ is +nil+ + # all entries in the file cache +@@file_cache+ are checked. + # If we don't have stat information about a file, which can happen + # if the file was read from SCRIPT_LINES__ but no corresponding file + # is found, it will be kept. Return a list of invalidated filenames. + # nil is returned if a filename was given but not found cached. + def checkcache(filename=nil, use_script_lines=false) + + if !filename + filenames = @@file_cache.keys() + elsif @@file_cache.member?(filename) + filenames = [filename] + else + return nil + end + + result = [] + for filename in filenames + next unless @@file_cache.member?(filename) + path = @@file_cache[filename].path + if File.exist?(path) + cache_info = @@file_cache[filename].stat + stat = File.stat(path) + if stat && + (cache_info.size != stat.size or cache_info.mtime != stat.mtime) + result << filename + update_cache(filename, use_script_lines) + end + end + end + return result + end + module_function :checkcache + + # Cache filename if it's not already cached. + # Return the expanded filename for it in the cache + # or nil if we can't find the file. + def cache(filename, reload_on_change=false) + if @@file_cache.member?(filename) + checkcache(filename) if reload_on_change + else + update_cache(filename, true) + end + if @@file_cache.member?(filename) + @@file_cache[filename].path + else + nil + end + end + module_function :cache + + # Return true if filename is cached + def cached?(filename) + @@file_cache.member?(unmap_file(filename)) + end + module_function :cached? + + def cached_script?(filename) + # In 1.8.6, the SCRIPT_LINES__ filename key can be unqualified + # In 1.9.1 it's the fully qualified name + if RUBY_VERSION < "1.9" + SCRIPT_LINES__.member?(unmap_file(filename)) + else + SCRIPT_LINES__.member?(File.expand_path(unmap_file(filename))) + end + end + module_function :cached_script? + + def empty?(filename) + filename=unmap_file(filename) + @@file_cache[filename].lines.empty? + end + module_function :empty? + + # Get line +line_number+ from file named +filename+. Return nil if + # there was a problem. If a file named filename is not found, the + # function will look for it in the $: array. + # + # Examples: + # + # lines = LineCache::getline('/tmp/myfile.rb') + # # Same as above + # $: << '/tmp' + # lines = LineCache.getlines('myfile.rb') + # + def getline(filename, line_number, reload_on_change=true) + filename = unmap_file(filename) + filename, line_number = unmap_file_line(filename, line_number) + lines = getlines(filename, reload_on_change) + if lines and (1..lines.size) === line_number + return lines[line_number-1] + else + return nil + end + end + module_function :getline + + # Read lines of +filename+ and cache the results. However +filename+ was + # previously cached use the results from the cache. Return nil + # if we can't get lines + def getlines(filename, reload_on_change=false) + filename = unmap_file(filename) + checkcache(filename) if reload_on_change + if @@file_cache.member?(filename) + return @@file_cache[filename].lines + else + update_cache(filename, true) + return @@file_cache[filename].lines if @@file_cache.member?(filename) + end + end + module_function :getlines + + # Return full filename path for filename + def path(filename) + filename = unmap_file(filename) + return nil unless @@file_cache.member?(filename) + @@file_cache[filename].path + end + module_function :path + + def remap_file(from_file, to_file) + @@file2file_remap[to_file] = from_file + end + module_function :remap_file + + def remap_file_lines(from_file, to_file, range, start) + range = (range..range) if range.is_a?(Fixnum) + to_file = from_file unless to_file + if @@file2file_remap_lines[to_file] + # FIXME: need to check for overwriting ranges: whether + # they intersect or one encompasses another. + @@file2file_remap_lines[to_file] << [from_file, range, start] + else + @@file2file_remap_lines[to_file] = [[from_file, range, start]] + end + end + module_function :remap_file_lines + + # Return SHA1 of filename. + def sha1(filename) + filename = unmap_file(filename) + return nil unless @@file_cache.member?(filename) + return @@file_cache[filename].sha1.hexdigest if + @@file_cache[filename].sha1 + sha1 = Digest::SHA1.new + @@file_cache[filename].lines.each do |line| + sha1 << line + end + @@file_cache[filename].sha1 = sha1 + sha1.hexdigest + end + module_function :sha1 + + # Return the number of lines in filename + def size(filename) + filename = unmap_file(filename) + return nil unless @@file_cache.member?(filename) + @@file_cache[filename].lines.length + end + module_function :size + + # Return File.stat in the cache for filename. + def stat(filename) + return nil unless @@file_cache.member?(filename) + @@file_cache[filename].stat + end + module_function :stat + + # Return an Array of breakpoints in filename. + # The list will contain an entry for each distinct line event call + # so it is possible (and possibly useful) for a line number appear more + # than once. + def trace_line_numbers(filename, reload_on_change=false) + fullname = cache(filename, reload_on_change) + return nil unless fullname + e = @@file_cache[filename] + unless e.line_numbers + e.line_numbers = + TraceLineNumbers.lnums_for_str_array(e.lines) + e.line_numbers = false unless e.line_numbers + end + e.line_numbers + end + module_function :trace_line_numbers + + def unmap_file(file) + @@file2file_remap[file] ? @@file2file_remap[file] : file + end + module_function :unmap_file + + def unmap_file_line(file, line) + if @@file2file_remap_lines[file] + @@file2file_remap_lines[file].each do |from_file, range, start| + if range === line + from_file = from_file || file + return [from_file, start+line-range.begin] + end + end + end + return [file, line] + end + module_function :unmap_file_line + + # Update a cache entry. If something's + # wrong, return nil. Return true if the cache was updated and false + # if not. If use_script_lines is true, use that as the source for the + # lines of the file + def update_cache(filename, use_script_lines=false) + + return nil unless filename + + @@file_cache.delete(filename) + path = File.expand_path(filename) + + if use_script_lines + list = [filename] + list << @@file2file_remap[path] if @@file2file_remap[path] + list.each do |name| + if !SCRIPT_LINES__[name].nil? && SCRIPT_LINES__[name] != true + begin + stat = File.stat(name) + rescue + stat = nil + end + lines = SCRIPT_LINES__[name] + if "ruby19".respond_to?(:force_encoding) + lines.each{|l| l.force_encoding(Encoding.default_external) } + end + @@file_cache[filename] = LineCacheInfo.new(stat, nil, lines, path, nil) + @@file2file_remap[path] = filename + return true + end + end + end + + if File.exist?(path) + stat = File.stat(path) + elsif File.basename(filename) == filename + # try looking through the search path. + stat = nil + for dirname in $: + path = File.join(dirname, filename) + if File.exist?(path) + stat = File.stat(path) + break + end + end + return false unless stat + end + begin + fp = File.open(path, 'r') + lines = fp.readlines() + fp.close() + rescue + ## print '*** cannot open', path, ':', msg + return nil + end + @@file_cache[filename] = LineCacheInfo.new(File.stat(path), nil, lines, + path, nil) + @@file2file_remap[path] = filename + return true + end + + module_function :update_cache + +end + +# example usage +if __FILE__ == $0 + def yes_no(var) + return var ? "" : "not " + end + + lines = LineCache::getlines(__FILE__) + puts "#{__FILE__} has #{LineCache.size(__FILE__)} lines" + line = LineCache::getline(__FILE__, 6) + puts "The 6th line is\n#{line}" + line = LineCache::remap_file(__FILE__, 'another_name') + puts LineCache::getline('another_name', 7) + + puts("Files cached: #{LineCache::cached_files.inspect}") + LineCache::update_cache(__FILE__) + LineCache::checkcache(__FILE__) + puts "#{__FILE__} has #{LineCache::size(__FILE__)} lines" + puts "#{__FILE__} trace line numbers:\n" + + "#{LineCache::trace_line_numbers(__FILE__).to_a.sort.inspect}" + puts("#{__FILE__} is %scached." % + yes_no(LineCache::cached?(__FILE__))) + puts LineCache::stat(__FILE__).inspect + puts "Full path: #{LineCache::path(__FILE__)}" + LineCache::checkcache # Check all files in the cache + LineCache::clear_file_cache + puts("#{__FILE__} is now %scached." % + yes_no(LineCache::cached?(__FILE__))) + digest = SCRIPT_LINES__.select{|k,v| k =~ /digest.rb$/} + puts digest.first[0] if digest + line = LineCache::getline(__FILE__, 7) + puts "The 7th line is\n#{line}" + LineCache::remap_file_lines(__FILE__, 'test2', (10..20), 6) + puts LineCache::getline('test2', 10) + puts "Remapped 10th line of test2 is\n#{line}" +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/lib/tracelines19.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/tracelines19.rb new file mode 100755 index 0000000..92f20c4 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/lib/tracelines19.rb @@ -0,0 +1,54 @@ +#!/usr/bin/env ruby +# $Id$ + +module TraceLineNumbers + # Return an array of lines numbers that could be + # stopped at given a file name of a Ruby program. + + def self.lnums_for_str src + name = "#{Time.new.to_i}_#{rand(2**31)}" + iseq = RubyVM::InstructionSequence.compile(src, name) + lines = {} + iseq.disasm.each_line{|line| + if /^\d+ (\w+)\s+.+\(\s*(\d+)\)$/ =~ line + insn = $1 + lineno = $2.to_i + next unless insn == 'trace' + lines[lineno] = true + # p [lineno, line] + end + } + lines.keys + end + + def lnums_for_file(file) + lnums_for_str(File.read(file)) + end + module_function :lnums_for_file + + # Return an array of lines numbers that could be + # stopped at given a file name of a Ruby program. + # We assume the each line has \n at the end. If not + # set the newline parameters to \n. + def lnums_for_str_array(string_array, newline='') + lnums_for_str(string_array.join(newline)) + end + module_function :lnums_for_str_array +end + +if __FILE__ == $0 + SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ + # test_file = '../test/rcov-bug.rb' + test_file = '../test/lnum-data/begin1.rb' + if File.exists?(test_file) + puts TraceLineNumbers.lnums_for_file(test_file).inspect + load(test_file, 0) # for later + end + puts TraceLineNumbers.lnums_for_file(__FILE__).inspect + unless SCRIPT_LINES__.empty? + key = SCRIPT_LINES__.keys.first + puts key + puts SCRIPT_LINES__[key] + puts TraceLineNumbers.lnums_for_str_array(SCRIPT_LINES__[key]).inspect + end +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin1.rb new file mode 100644 index 0000000..94950b9 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin1.rb @@ -0,0 +1,3 @@ +# [ 2 ] +begin +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin2.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin2.rb new file mode 100644 index 0000000..d92a227 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin2.rb @@ -0,0 +1,3 @@ +# [ 2, 2 ] +begin begin end end + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin3.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin3.rb new file mode 100644 index 0000000..c1b95b6 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/begin3.rb @@ -0,0 +1,6 @@ +# [ 2, 3 ] +begin + begin + end +end + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block1.rb new file mode 100755 index 0000000..9435794 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block1.rb @@ -0,0 +1,7 @@ +# [2, 2, 3, 4, 6, 6] +if true + puts '3' + puts '4' +end +if true +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block2.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block2.rb new file mode 100644 index 0000000..b358763 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/block2.rb @@ -0,0 +1,4 @@ +# [2, 4, 4] +def foo(&block) +end +foo{4} diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case1.rb new file mode 100644 index 0000000..ae7d167 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case1.rb @@ -0,0 +1,6 @@ +# [ 2, 3, 4 ] +case 2 +when 3 +when 4 +else +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case2.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case2.rb new file mode 100644 index 0000000..a7f42ff --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case2.rb @@ -0,0 +1,5 @@ +# [ 5, 3, 4 ] +case +when 3 != 3 +when 4 != 4 +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case3.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case3.rb new file mode 100644 index 0000000..bd43172 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case3.rb @@ -0,0 +1,5 @@ +# [2, 3, 4] +case "2" +when Array +when Fixnum +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case4.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case4.rb new file mode 100644 index 0000000..852dc9b --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case4.rb @@ -0,0 +1,4 @@ +# [2, 3, 3] +case "2" +when Array, Fixnum +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case5.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case5.rb new file mode 100644 index 0000000..8e43138 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/case5.rb @@ -0,0 +1,10 @@ +# [3, 4, 5, 6, 7, 9] +# Note: lines 5 and 7 won't appear in a trace. +case '3' +when '4' + x = 5 +when '6' + x = 7 +else + x = 9 +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/class1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/class1.rb new file mode 100644 index 0000000..89075e1 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/class1.rb @@ -0,0 +1,5 @@ +# [3, 4] +class + A + class B ; + end end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/comments1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/comments1.rb new file mode 100644 index 0000000..3e28eec --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/comments1.rb @@ -0,0 +1,6 @@ +# [] + + # space here and in next line + + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/def1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/def1.rb new file mode 100644 index 0000000..88f6ea4 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/def1.rb @@ -0,0 +1,9 @@ +# [3, 4, 8] +def + a ; end +def b +end +def c( + a=7, + b=8) +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/each1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/each1.rb new file mode 100644 index 0000000..bb6b621 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/each1.rb @@ -0,0 +1,3 @@ +# [ 2 ] +[2].each { } + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/end.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/end.rb new file mode 100644 index 0000000..0562f12 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/end.rb @@ -0,0 +1,3 @@ +# [ 3 ] +# POSTEXE +END { } diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/for1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/for1.rb new file mode 100644 index 0000000..1034ae0 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/for1.rb @@ -0,0 +1,4 @@ +# [ 2, 3 ] +for i in [2] + i +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if1.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if1.rb new file mode 100644 index 0000000..bd7eaa2 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if1.rb @@ -0,0 +1,4 @@ +# [ 2, 2 ] +x = true ? 1 : 2 + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if2.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if2.rb new file mode 100644 index 0000000..af18e07 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if2.rb @@ -0,0 +1,4 @@ +# [ 2, 2 ] +x = 2 if false + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if3.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if3.rb new file mode 100644 index 0000000..fa4edf3 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if3.rb @@ -0,0 +1,9 @@ +# [ 2, 3, 4, 4, 5, 6] +lines = '' +opts = {:print_source => true} +if opts[:print_source] + puts 5 + puts lines +end + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if4.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if4.rb new file mode 100644 index 0000000..737b229 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if4.rb @@ -0,0 +1,14 @@ +# [ 6, 7, 7, 10, 8] + +# Running through Tracer will not give the line numbers in the same +# order. Also note 9 before 7. This is because in the parse tree +# != has been turned into == with the branches switched. +[true, false].each do |t| + if t != true + 8 + else + 10 + end +end + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if5.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if5.rb new file mode 100644 index 0000000..4a07391 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if5.rb @@ -0,0 +1,7 @@ +# [2, 4, 4] +x=2 +x=3 if x='a' or + false +# What's weird here is we get two stops on line 4 and both times x is +# 4. In Ruby 1.9 we don't get *any* line traces. + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if6.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if6.rb new file mode 100644 index 0000000..61fe636 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if6.rb @@ -0,0 +1,4 @@ +# [ 2, 2 ] +x = 2 if x=3 + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if7.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if7.rb new file mode 100644 index 0000000..6efb5d6 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/if7.rb @@ -0,0 +1,8 @@ +# [ 2, 3, 4, 6, 6 ] +def f() + y=1 + true +end +x = 2 if f() + + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match.rb new file mode 100644 index 0000000..74bab80 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match.rb @@ -0,0 +1,3 @@ +# [ 3 ] +# MATCH -- FIXME we are not getting a match token. +/.*/ diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3.rb new file mode 100644 index 0000000..ef5c049 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3.rb @@ -0,0 +1,5 @@ +# [ 5 ] +# MATCH3 +3 =~ / + x* +/ diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3a.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3a.rb new file mode 100644 index 0000000..fa124a3 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/match3a.rb @@ -0,0 +1,6 @@ +# [ 3, 6 ] +# MATCH3 +y = 3 +4 =~ / + #{y}* +/ diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/not-lit.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/not-lit.rb new file mode 100644 index 0000000..c5d2b30 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/data/not-lit.rb @@ -0,0 +1,6 @@ +# [ 4, 6 ] +# not and lit +3 +not 4 +not + 6 diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/lnum-diag.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/lnum-diag.rb new file mode 100755 index 0000000..2c63d2a --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/lnum-diag.rb @@ -0,0 +1,127 @@ +#!/usr/bin/env ruby + +TEST_DIR = File.expand_path(File.dirname(__FILE__)) +TOP_SRC_DIR = File.join(TEST_DIR, '..') +require File.join(TOP_SRC_DIR, 'lib', 'tracelines19.rb') + +def dump_file(file, opts) + puts file + begin + fp = File.open(file, 'r') + rescue Errno::ENOENT + puts "File #{file} is not readable." + return + end + lines = fp.read + if opts[:print_source] + puts '=' * 80 + puts lines + end + if opts[:print_parse] + puts '=' * 80 + cmd = "#{File.join(TEST_DIR, 'parse-show.rb')} #{file}" + system(cmd) + end + if opts[:print_trace] + require 'tracer' + puts '=' * 80 + tracer = Tracer.new + tracer.add_filter lambda {|event, f, line, id, binding, klass| + __FILE__ != f && event == 'line' + } + tracer.on{load(file)} + end + expected_lnums = nil + if opts[:expect_line] + fp.rewind + first_line = fp.readline.chomp + expected_str = first_line[1..-1] + begin + expected_lnums = eval(expected_str, binding, __FILE__, __LINE__) + rescue SyntaxError + puts '=' * 80 + puts "Failed reading expected values from #{file}" + end + end + fp.close() + got_lnums = TraceLineNumbers.lnums_for_str(lines) + if expected_lnums + puts "expecting: #{expected_lnums.inspect}" + puts '-' * 80 + if expected_lnums + if got_lnums != expected_lnums + puts "mismatch: #{got_lnums.inspect}" + else + puts 'Got what was expected.' + end + else + puts got_lnums.inspect + end + else + puts got_lnums.inspect + end +end + +require 'getoptlong' +program = File.basename($0) +opts = { + :print_source => true, # Print source file? + :print_trace => true, # Run Tracer over file? + :expect_line => true, # Source file has expected (correct) list of lines? + :print_parse => true, # Show ParseTree output? +} + +getopts = GetoptLong.new( + [ '--expect', '-e', GetoptLong::NO_ARGUMENT ], + [ '--no-expect', '-E', GetoptLong::NO_ARGUMENT ], + [ '--help', '-h', GetoptLong::NO_ARGUMENT ], + [ '--parse', '-p', GetoptLong::NO_ARGUMENT ], + [ '--no-parse', '-P', GetoptLong::NO_ARGUMENT ], + [ '--source', '-s', GetoptLong::NO_ARGUMENT ], + [ '--no-source', '-S', GetoptLong::NO_ARGUMENT ], + [ '--trace', '-t', GetoptLong::NO_ARGUMENT ], + [ '--no-trace', '-T', GetoptLong::NO_ARGUMENT ]) + +getopts.each do |opt, arg| + case opt + when '--help' + puts "usage +Usage: #{$program} [options] file1 file2 ... + +Diagnostic program to make see what TraceLineNumbers does and compare +against other output. + +options: + -e --expect Read source file expected comment (default) + -E --no-expect Don't look for source file expected comment + -p --parse Show ParseTree Output (default) + -P --no-parse Don't show ParseTree output + -s --source Show source file (default) + -S --no-source Don't print source + -t --trace Show Tracer output (default) + -T --no-trace Don't show Tracer output +" + when '--expect' + opts[:expect_line] = true + when '--no-expect' + opts[:expect_line] = false + when '--parse' + opts[:print_parse] = true + when '--no-parse' + opts[:print_parse] = false + when '--source' + opts[:print_source] = true + when '--no-source' + opts[:print_source] = false + when '--trace' + opts[:print_trace] = true + when '--no-trace' + opts[:print_trace] = false + else + puts "Unknown and ignored option #{opt}" + end +end + +ARGV.each do |file| + dump_file(file, opts) +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/parse-show.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/parse-show.rb new file mode 100755 index 0000000..4e79426 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/parse-show.rb @@ -0,0 +1,13 @@ +#!/usr/bin/env ruby + +require 'pp' +require 'parse_tree' + +ARGV.push "-" if ARGV.empty? + +parse_tree = ParseTree.new(true) + +ARGV.each do |file| + ruby = file == "-" ? $stdin.read : File.read(file) + pp parse_tree.parse_tree_for_string(ruby, file).first +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/rcov-bug.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/rcov-bug.rb new file mode 100644 index 0000000..a6e73f2 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/rcov-bug.rb @@ -0,0 +1,10 @@ +# [3, 10] +# Some rcov bugs. +z = " +Now is the time +" + +z =~ + / + 5 + /ix diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/short-file b/vendor/bundle/gems/debugger-linecache-1.2.0/test/short-file new file mode 100644 index 0000000..68cb346 --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/short-file @@ -0,0 +1,2 @@ +# This is a small test file. + diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-linecache.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-linecache.rb new file mode 100755 index 0000000..ad8335c --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-linecache.rb @@ -0,0 +1,148 @@ +#!/usr/bin/env ruby +require 'test/unit' +require 'fileutils' +require 'tempfile' +require 'set' + +# Test LineCache module +class TestLineCache < Test::Unit::TestCase + @@TEST_DIR = File.expand_path(File.dirname(__FILE__)) + @@TOP_SRC_DIR = File.join(@@TEST_DIR, '..', 'lib') + require File.join(@@TOP_SRC_DIR, 'linecache19.rb') + + def setup + LineCache::clear_file_cache + end + + def test_basic + fp = File.open(__FILE__, 'r') + compare_lines = fp.readlines() + fp.close + + # Test getlines to read this file. + lines = LineCache::getlines(__FILE__) + assert_equal(compare_lines, lines, + 'We should get exactly the same lines as reading this file.') + + # Test getline to read this file. The file should now be cached, + # so internally a different set of routines are used. + test_line = 1 + line = LineCache::getline(__FILE__, test_line) + assert_equal(compare_lines[test_line-1], line, + 'We should get exactly the same line as reading this file.') + + # Test getting the line via a relative file name + Dir.chdir(File.dirname(__FILE__)) do + short_file = File.basename(__FILE__) + test_line = 10 + line = LineCache::getline(short_file, test_line) + assert_equal(compare_lines[test_line-1], line, + 'Short filename lookup should work') + end + + # Write a temporary file; read contents, rewrite it and check that + # we get a change when calling getline. + tf = Tempfile.new("testing") + test_string = "Now is the time.\n" + tf.puts(test_string) + tf.close + line = LineCache::getline(tf.path, 1) + assert_equal(test_string, line, + "C'mon - a simple line test like this worked before.") + tf.open + test_string = "Now is another time.\n" + tf.puts(test_string) + tf.close + LineCache::checkcache + line = LineCache::getline(tf.path, 1) + assert_equal(test_string, line, + "checkcache should have reread the temporary file.") + FileUtils.rm tf.path + + LineCache::update_cache(__FILE__) + LineCache::clear_file_cache + end + + def test_cached + assert_equal(false, LineCache::cached?(__FILE__), + "file #{__FILE__} shouldn't be cached - just cleared cache.") + line = LineCache::getline(__FILE__, 1) + assert line + assert_equal(true, LineCache::cached?(__FILE__), + "file #{__FILE__} should now be cached") + assert_equal(false, LineCache::cached_script?('./short-file'), + "Should not find './short-file' in SCRIPT_LINES__") + assert_equal(true, 78 < LineCache.size(__FILE__)) + Dir.chdir(File.dirname(__FILE__)) do + load('./short-file', 0) + assert_equal(true, LineCache::cached_script?('./short-file'), + "Should be able to find './short-file' in SCRIPT_LINES__") + end + end + + def test_remap + LineCache::remap_file(__FILE__, 'another-name') + line1 = LineCache::getline('another-name', 1) + line2 = LineCache::getline(__FILE__, 1) + assert_equal(line1, line2, 'Both lines should be the same via remap_file') + end + + def test_remap_lines + LineCache::remap_file_lines(__FILE__, 'test2', (10..11), 6) + + line5 = LineCache::getline(__FILE__, 5) + LineCache::remap_file_lines(__FILE__, 'test2', 9, 5) + rline9 = LineCache::getline('test2', 9) + assert_equal(line5, rline9, + 'lines should be the same via remap_file_line - remap integer') + + line6 = LineCache::getline(__FILE__, 6) + rline10 = LineCache::getline('test2', 10) + assert_equal(line6, rline10, + 'lines should be the same via remap_file_line - range') + + line7 = LineCache::getline(__FILE__, 7) + rline11 = LineCache::getline('test2', 11) + assert_equal(line7, rline11, + 'lines should be the same via remap_file_line - range') + + line8 = LineCache::getline(__FILE__, 8) + LineCache::remap_file_lines(__FILE__, nil, 20, 8) + rline20 = LineCache::getline(__FILE__, 20) + assert_equal(line8, rline20, + 'lines should be the same via remap_file_line - nil file') + end + + def test_stat + assert_equal(nil, LineCache::stat(__FILE__), + "stat for #{__FILE__} shouldn't be nil - just cleared cache.") + line = LineCache::getline(__FILE__, 1) + assert line + assert(LineCache::stat(__FILE__), + "file #{__FILE__} should now have a stat") + end + + def test_path + assert_equal(nil, LineCache::path(__FILE__), + "path for #{__FILE__} should be nil - just cleared cache.") + path = LineCache::cache(__FILE__) + assert path + assert_equal(path, LineCache::path(__FILE__), + "path of #{__FILE__} should be the same as we got before") + end + + def test_trace_line_numbers + test_file = File.join(@@TEST_DIR, 'short-file') + assert_equal([], LineCache::trace_line_numbers(test_file)) + test_file = File.join(@@TEST_DIR, 'rcov-bug.rb') + assert_equal([3, 10], LineCache::trace_line_numbers(test_file)) + end + + def test_sha1 + test_file = File.join(@@TEST_DIR, 'short-file') + LineCache::cache(test_file) + assert_equal('1134f95ea84a3dcc67d7d1bf41390ee1a03af6d2', + LineCache::sha1(test_file)) + end + +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-lnum.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-lnum.rb new file mode 100755 index 0000000..c64338a --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-lnum.rb @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby +# $Id$ +require 'test/unit' + +# Test TraceLineNumbers module +class TestLineNumbers2 < Test::Unit::TestCase + @@TEST_DIR = File.expand_path(File.dirname(__FILE__)) + @@TOP_SRC_DIR = File.join(@@TEST_DIR, '..') + require File.join(@@TOP_SRC_DIR, 'lib', 'tracelines19.rb') + + def test_all_lnum_data + test_dir = File.join(@@TEST_DIR, 'data') + Dir.chdir(test_dir) do + Dir.glob('*.rb').sort.each do |f| + puts f + fp = File.open(f, 'r') + lines = fp.read + fp.rewind + first_line = fp.readline.chomp + fp.close() + expected_str = first_line[1..-1] + begin + expected_lnums = eval(expected_str, binding, __FILE__, __LINE__) + rescue + assert nil, "Failed reading expected values from #{f}" + else + got_lnums = TraceLineNumbers.lnums_for_str(lines) + assert_equal(expected_lnums, got_lnums) + end + end + end + end +end diff --git a/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-tracelines.rb b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-tracelines.rb new file mode 100755 index 0000000..a74566c --- /dev/null +++ b/vendor/bundle/gems/debugger-linecache-1.2.0/test/test-tracelines.rb @@ -0,0 +1,38 @@ +#!/usr/bin/env ruby +# $Id$ +require 'test/unit' +require 'fileutils' +require 'tempfile' + +SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__ +# Test TestLineNumbers module +class TestLineNumbers1 < Test::Unit::TestCase + + @@TEST_DIR = File.expand_path(File.dirname(__FILE__)) + @@TOP_SRC_DIR = File.join(@@TEST_DIR, '..', 'lib') + require File.join(@@TOP_SRC_DIR, 'tracelines19.rb') + + @@rcov_file = File.join(@@TEST_DIR, 'rcov-bug.rb') + File.open(@@rcov_file, 'r') {|fp| + first_line = fp.readline[1..-2] + @@rcov_lnums = eval(first_line, binding, __FILE__, __LINE__) + } + + def test_for_file + rcov_lines = TraceLineNumbers.lnums_for_file(@@rcov_file) + assert_equal(@@rcov_lnums, rcov_lines) + end + + def test_for_string + string = "# Some rcov bugs.\nz = \"\nNow is the time\n\"\n\nz =~ \n /\n 5\n /ix\n" + rcov_lines = TraceLineNumbers.lnums_for_str(string) + assert_equal([2, 9], rcov_lines) + end + + def test_for_string_array + load(@@rcov_file, 0) + rcov_lines = + TraceLineNumbers.lnums_for_str_array(SCRIPT_LINES__[@@rcov_file]) + assert_equal(@@rcov_lnums, rcov_lines) + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/.gemtest b/vendor/bundle/gems/method_source-0.8.2/.gemtest new file mode 100644 index 0000000..e69de29 diff --git a/vendor/bundle/gems/method_source-0.8.2/.travis.yml b/vendor/bundle/gems/method_source-0.8.2/.travis.yml new file mode 100644 index 0000000..2349f06 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/.travis.yml @@ -0,0 +1,13 @@ +rvm: + - 1.8.7 + - 1.9.2 + - 1.9.3 + - ree + - rbx-18mode + - rbx-19mode + - jruby + +notifications: + irc: "irc.freenode.org#pry" + recipients: + - jrmair@gmail.com diff --git a/vendor/bundle/gems/method_source-0.8.2/.yardopts b/vendor/bundle/gems/method_source-0.8.2/.yardopts new file mode 100644 index 0000000..a4e7838 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/.yardopts @@ -0,0 +1 @@ +-m markdown diff --git a/vendor/bundle/gems/method_source-0.8.2/Gemfile b/vendor/bundle/gems/method_source-0.8.2/Gemfile new file mode 100644 index 0000000..e45e65f --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/Gemfile @@ -0,0 +1,2 @@ +source :rubygems +gemspec diff --git a/vendor/bundle/gems/method_source-0.8.2/LICENSE b/vendor/bundle/gems/method_source-0.8.2/LICENSE new file mode 100644 index 0000000..d1a50d6 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/LICENSE @@ -0,0 +1,25 @@ +License +------- + +(The MIT License) + +Copyright (c) 2011 John Mair (banisterfiend) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/gems/method_source-0.8.2/README.markdown b/vendor/bundle/gems/method_source-0.8.2/README.markdown new file mode 100644 index 0000000..d91b810 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/README.markdown @@ -0,0 +1,91 @@ +method_source +============= + +(C) John Mair (banisterfiend) 2011 + +_retrieve the sourcecode for a method_ + +*NOTE:* This simply utilizes `Method#source_location`; it + does not access the live AST. + +`method_source` is a utility to return a method's sourcecode as a +Ruby string. Also returns `Proc` and `Lambda` sourcecode. + +Method comments can also be extracted using the `comment` method. + +It is written in pure Ruby (no C). + +* Some Ruby 1.8 support now available. +* Support for MRI, RBX, JRuby, REE + +`method_source` provides the `source` and `comment` methods to the `Method` and +`UnboundMethod` and `Proc` classes. + +* Install the [gem](https://rubygems.org/gems/method_source): `gem install method_source` +* Read the [documentation](http://rdoc.info/github/banister/method_source/master/file/README.markdown) +* See the [source code](http://github.com/banister/method_source) + +Example: display method source +------------------------------ + + Set.instance_method(:merge).source.display + # => + def merge(enum) + if enum.instance_of?(self.class) + @hash.update(enum.instance_variable_get(:@hash)) + else + do_with_enum(enum) { |o| add(o) } + end + + self + end + +Example: display method comments +-------------------------------- + + Set.instance_method(:merge).comment.display + # => + # Merges the elements of the given enumerable object to the set and + # returns self. + +Limitations: +------------ + +* Occasional strange behaviour in Ruby 1.8 +* Cannot return source for C methods. +* Cannot return source for dynamically defined methods. + +Special Thanks +-------------- + +[Adam Sanderson](https://github.com/adamsanderson) for `comment` functionality. + +[Dmitry Elastic](https://github.com/dmitryelastic) for the brilliant Ruby 1.8 `source_location` hack. + +[Samuel Kadolph](https://github.com/samuelkadolph) for the JRuby 1.8 `source_location`. + +License +------- + +(The MIT License) + +Copyright (c) 2011 John Mair (banisterfiend) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/gems/method_source-0.8.2/Rakefile b/vendor/bundle/gems/method_source-0.8.2/Rakefile new file mode 100644 index 0000000..7dad800 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/Rakefile @@ -0,0 +1,79 @@ +dlext = RbConfig::CONFIG['DLEXT'] +direc = File.dirname(__FILE__) + +require 'rake/clean' +require 'rubygems/package_task' +require "#{direc}/lib/method_source/version" + +CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o") +CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o", + "ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "**/*.rbc", + "ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake") + +def apply_spec_defaults(s) + s.name = "method_source" + s.summary = "retrieve the sourcecode for a method" + s.version = MethodSource::VERSION + s.date = Time.now.strftime '%Y-%m-%d' + s.author = "John Mair (banisterfiend)" + s.email = 'jrmair@gmail.com' + s.description = s.summary + s.require_path = 'lib' + + s.add_development_dependency("bacon","~>1.1.0") + s.add_development_dependency("rake", "~>0.9") + s.homepage = "http://banisterfiend.wordpress.com" + s.has_rdoc = 'yard' + s.files = `git ls-files`.split("\n") + s.test_files = `git ls-files -- test/*`.split("\n") +end + +task :test do + sh "bacon -q #{direc}/test/test.rb #{direc}/test/test_code_helpers.rb" +end + +desc "reinstall gem" +task :reinstall => :gems do + sh "gem uninstall method_source" rescue nil + sh "gem install #{direc}/pkg/method_source-#{MethodSource::VERSION}.gem" +end + +desc "Set up and run tests" +task :default => [:test] + +desc "Build the gemspec file" +task :gemspec => "ruby:gemspec" + +namespace :ruby do + spec = Gem::Specification.new do |s| + apply_spec_defaults(s) + s.platform = Gem::Platform::RUBY + end + + Gem::PackageTask.new(spec) do |pkg| + pkg.need_zip = false + pkg.need_tar = false + end + + desc "Generate gemspec file" + task :gemspec do + File.open("#{spec.name}.gemspec", "w") do |f| + f << spec.to_ruby + end + end +end + +desc "build all platform gems at once" +task :gems => [:rmgems, "ruby:gem"] + +desc "remove all platform gems" +task :rmgems => ["ruby:clobber_package"] + +desc "build and push latest gems" +task :pushgems => :gems do + chdir("#{direc}/pkg") do + Dir["*.gem"].each do |gemfile| + sh "gem push #{gemfile}" + end + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/lib/method_source.rb b/vendor/bundle/gems/method_source-0.8.2/lib/method_source.rb new file mode 100644 index 0000000..7d16c3b --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/lib/method_source.rb @@ -0,0 +1,141 @@ +# (C) John Mair (banisterfiend) 2011 +# MIT License + +direc = File.dirname(__FILE__) + +require "#{direc}/method_source/version" +require "#{direc}/method_source/source_location" +require "#{direc}/method_source/code_helpers" + +module MethodSource + extend MethodSource::CodeHelpers + + # An Exception to mark errors that were raised trying to find the source from + # a given source_location. + # + class SourceNotFoundError < StandardError; end + + # Helper method responsible for extracting method body. + # Defined here to avoid polluting `Method` class. + # @param [Array] source_location The array returned by Method#source_location + # @param [String] method_name + # @return [String] The method body + def self.source_helper(source_location, name=nil) + raise SourceNotFoundError, "Could not locate source for #{name}!" unless source_location + file, line = *source_location + + expression_at(lines_for(file), line) + rescue SyntaxError => e + raise SourceNotFoundError, "Could not parse source for #{name}: #{e.message}" + end + + # Helper method responsible for opening source file and buffering up + # the comments for a specified method. Defined here to avoid polluting + # `Method` class. + # @param [Array] source_location The array returned by Method#source_location + # @param [String] method_name + # @return [String] The comments up to the point of the method. + def self.comment_helper(source_location, name=nil) + raise SourceNotFoundError, "Could not locate source for #{name}!" unless source_location + file, line = *source_location + + comment_describing(lines_for(file), line) + end + + # Load a memoized copy of the lines in a file. + # + # @param [String] file_name + # @param [String] method_name + # @return [Array] the contents of the file + # @raise [SourceNotFoundError] + def self.lines_for(file_name, name=nil) + @lines_for_file ||= {} + @lines_for_file[file_name] ||= File.readlines(file_name) + rescue Errno::ENOENT => e + raise SourceNotFoundError, "Could not load source for #{name}: #{e.message}" + end + + # @deprecated — use MethodSource::CodeHelpers#complete_expression? + def self.valid_expression?(str) + complete_expression?(str) + rescue SyntaxError + false + end + + # @deprecated — use MethodSource::CodeHelpers#expression_at + def self.extract_code(source_location) + source_helper(source_location) + end + + # This module is to be included by `Method` and `UnboundMethod` and + # provides the `#source` functionality + module MethodExtensions + + # We use the included hook to patch Method#source on rubinius. + # We need to use the included hook as Rubinius defines a `source` + # on Method so including a module will have no effect (as it's + # higher up the MRO). + # @param [Class] klass The class that includes the module. + def self.included(klass) + if klass.method_defined?(:source) && Object.const_defined?(:RUBY_ENGINE) && + RUBY_ENGINE =~ /rbx/ + + klass.class_eval do + orig_source = instance_method(:source) + + define_method(:source) do + begin + super + rescue + orig_source.bind(self).call + end + end + + end + end + end + + # Return the sourcecode for the method as a string + # @return [String] The method sourcecode as a string + # @raise SourceNotFoundException + # + # @example + # Set.instance_method(:clear).source.display + # => + # def clear + # @hash.clear + # self + # end + def source + MethodSource.source_helper(source_location, defined?(name) ? name : inspect) + end + + # Return the comments associated with the method as a string. + # @return [String] The method's comments as a string + # @raise SourceNotFoundException + # + # @example + # Set.instance_method(:clear).comment.display + # => + # # Removes all elements and returns self. + def comment + MethodSource.comment_helper(source_location, defined?(name) ? name : inspect) + end + end +end + +class Method + include MethodSource::SourceLocation::MethodExtensions + include MethodSource::MethodExtensions +end + +class UnboundMethod + include MethodSource::SourceLocation::UnboundMethodExtensions + include MethodSource::MethodExtensions +end + +class Proc + include MethodSource::SourceLocation::ProcExtensions + include MethodSource::MethodExtensions +end + diff --git a/vendor/bundle/gems/method_source-0.8.2/lib/method_source/code_helpers.rb b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/code_helpers.rb new file mode 100644 index 0000000..6c1d53e --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/code_helpers.rb @@ -0,0 +1,154 @@ +module MethodSource + + module CodeHelpers + # Retrieve the first expression starting on the given line of the given file. + # + # This is useful to get module or method source code. + # + # @param [Array, File, String] file The file to parse, either as a File or as + # @param [Fixnum] line_number The line number at which to look. + # NOTE: The first line in a file is + # line 1! + # @param [Hash] options The optional configuration parameters. + # @option options [Boolean] :strict If set to true, then only completely + # valid expressions are returned. Otherwise heuristics are used to extract + # expressions that may have been valid inside an eval. + # @option options [Fixnum] :consume A number of lines to automatically + # consume (add to the expression buffer) without checking for validity. + # @return [String] The first complete expression + # @raise [SyntaxError] If the first complete expression can't be identified + def expression_at(file, line_number, options={}) + options = { + :strict => false, + :consume => 0 + }.merge!(options) + + lines = file.is_a?(Array) ? file : file.each_line.to_a + + relevant_lines = lines[(line_number - 1)..-1] || [] + + extract_first_expression(relevant_lines, options[:consume]) + rescue SyntaxError => e + raise if options[:strict] + + begin + extract_first_expression(relevant_lines) do |code| + code.gsub(/\#\{.*?\}/, "temp") + end + rescue SyntaxError + raise e + end + end + + # Retrieve the comment describing the expression on the given line of the given file. + # + # This is useful to get module or method documentation. + # + # @param [Array, File, String] file The file to parse, either as a File or as + # a String or an Array of lines. + # @param [Fixnum] line_number The line number at which to look. + # NOTE: The first line in a file is line 1! + # @return [String] The comment + def comment_describing(file, line_number) + lines = file.is_a?(Array) ? file : file.each_line.to_a + + extract_last_comment(lines[0..(line_number - 2)]) + end + + # Determine if a string of code is a complete Ruby expression. + # @param [String] code The code to validate. + # @return [Boolean] Whether or not the code is a complete Ruby expression. + # @raise [SyntaxError] Any SyntaxError that does not represent incompleteness. + # @example + # complete_expression?("class Hello") #=> false + # complete_expression?("class Hello; end") #=> true + # complete_expression?("class 123") #=> SyntaxError: unexpected tINTEGER + def complete_expression?(str) + old_verbose = $VERBOSE + $VERBOSE = nil + + catch(:valid) do + eval("BEGIN{throw :valid}\n#{str}") + end + + # Assert that a line which ends with a , or \ is incomplete. + str !~ /[,\\]\s*\z/ + rescue IncompleteExpression + false + ensure + $VERBOSE = old_verbose + end + + private + + # Get the first expression from the input. + # + # @param [Array] lines + # @param [Fixnum] consume A number of lines to automatically + # consume (add to the expression buffer) without checking for validity. + # @yield a clean-up function to run before checking for complete_expression + # @return [String] a valid ruby expression + # @raise [SyntaxError] + def extract_first_expression(lines, consume=0, &block) + code = consume.zero? ? "" : lines.slice!(0..(consume - 1)).join + + lines.each do |v| + code << v + return code if complete_expression?(block ? block.call(code) : code) + end + raise SyntaxError, "unexpected $end" + end + + # Get the last comment from the input. + # + # @param [Array] lines + # @return [String] + def extract_last_comment(lines) + buffer = "" + + lines.each do |line| + # Add any line that is a valid ruby comment, + # but clear as soon as we hit a non comment line. + if (line =~ /^\s*#/) || (line =~ /^\s*$/) + buffer << line.lstrip + else + buffer.replace("") + end + end + + buffer + end + + # An exception matcher that matches only subsets of SyntaxErrors that can be + # fixed by adding more input to the buffer. + module IncompleteExpression + GENERIC_REGEXPS = [ + /unexpected (\$end|end-of-file|end-of-input|END_OF_FILE)/, # mri, jruby, ruby-2.0, ironruby + /embedded document meets end of file/, # =begin + /unterminated (quoted string|string|regexp) meets end of file/, # "quoted string" is ironruby + /can't find string ".*" anywhere before EOF/, # rbx and jruby + /missing 'end' for/, /expecting kWHEN/ # rbx + ] + + RBX_ONLY_REGEXPS = [ + /expecting '[})\]]'(?:$|:)/, /expecting keyword_end/ + ] + + def self.===(ex) + return false unless SyntaxError === ex + case ex.message + when *GENERIC_REGEXPS + true + when *RBX_ONLY_REGEXPS + rbx? + else + false + end + end + + def self.rbx? + RbConfig::CONFIG['ruby_install_name'] == 'rbx' + end + end + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/lib/method_source/source_location.rb b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/source_location.rb new file mode 100644 index 0000000..1e2a22a --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/source_location.rb @@ -0,0 +1,138 @@ +module MethodSource + module ReeSourceLocation + # Ruby enterprise edition provides all the information that's + # needed, in a slightly different way. + def source_location + [__file__, __line__] rescue nil + end + end + + module SourceLocation + module MethodExtensions + if Proc.method_defined? :__file__ + include ReeSourceLocation + + elsif defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/ + require 'java' + + # JRuby version source_location hack + # @return [Array] A two element array containing the source location of the method + def source_location + to_java.source_location(Thread.current.to_java.getContext()) + end + else + + + def trace_func(event, file, line, id, binding, classname) + return unless event == 'call' + set_trace_func nil + + @file, @line = file, line + raise :found + end + + private :trace_func + + # Return the source location of a method for Ruby 1.8. + # @return [Array] A two element array. First element is the + # file, second element is the line in the file where the + # method definition is found. + def source_location + if @file.nil? + args =[*(1..(arity<-1 ? -arity-1 : arity ))] + + set_trace_func method(:trace_func).to_proc + call(*args) rescue nil + set_trace_func nil + @file = File.expand_path(@file) if @file && File.exist?(File.expand_path(@file)) + end + [@file, @line] if @file + end + end + end + + module ProcExtensions + if Proc.method_defined? :__file__ + include ReeSourceLocation + + elsif defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /rbx/ + + # Return the source location for a Proc (Rubinius only) + # @return [Array] A two element array. First element is the + # file, second element is the line in the file where the + # proc definition is found. + def source_location + [block.file.to_s, block.line] + end + else + + # Return the source location for a Proc (in implementations + # without Proc#source_location) + # @return [Array] A two element array. First element is the + # file, second element is the line in the file where the + # proc definition is found. + def source_location + self.to_s =~ /@(.*):(\d+)/ + [$1, $2.to_i] + end + end + end + + module UnboundMethodExtensions + if Proc.method_defined? :__file__ + include ReeSourceLocation + + elsif defined?(RUBY_ENGINE) && RUBY_ENGINE =~ /jruby/ + require 'java' + + # JRuby version source_location hack + # @return [Array] A two element array containing the source location of the method + def source_location + to_java.source_location(Thread.current.to_java.getContext()) + end + + else + + + # Return the source location of an instance method for Ruby 1.8. + # @return [Array] A two element array. First element is the + # file, second element is the line in the file where the + # method definition is found. + def source_location + klass = case owner + when Class + owner + when Module + method_owner = owner + Class.new { include(method_owner) } + end + + # deal with immediate values + case + when klass == Symbol + return :a.method(name).source_location + when klass == Fixnum + return 0.method(name).source_location + when klass == TrueClass + return true.method(name).source_location + when klass == FalseClass + return false.method(name).source_location + when klass == NilClass + return nil.method(name).source_location + end + + begin + Object.instance_method(:method).bind(klass.allocate).call(name).source_location + rescue TypeError + + # Assume we are dealing with a Singleton Class: + # 1. Get the instance object + # 2. Forward the source_location lookup to the instance + instance ||= ObjectSpace.each_object(owner).first + Object.instance_method(:method).bind(instance).call(name).source_location + end + end + end + end + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/lib/method_source/version.rb b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/version.rb new file mode 100644 index 0000000..7a91c7d --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/lib/method_source/version.rb @@ -0,0 +1,3 @@ +module MethodSource + VERSION = "0.8.2" +end diff --git a/vendor/bundle/gems/method_source-0.8.2/method_source.gemspec b/vendor/bundle/gems/method_source-0.8.2/method_source.gemspec new file mode 100644 index 0000000..d24b3d9 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/method_source.gemspec @@ -0,0 +1,33 @@ +# -*- encoding: utf-8 -*- + +Gem::Specification.new do |s| + s.name = "method_source" + s.version = "0.8.1" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.authors = ["John Mair (banisterfiend)"] + s.date = "2012-10-17" + s.description = "retrieve the sourcecode for a method" + s.email = "jrmair@gmail.com" + s.files = [".gemtest", ".travis.yml", ".yardopts", "Gemfile", "LICENSE", "README.markdown", "Rakefile", "lib/method_source.rb", "lib/method_source/code_helpers.rb", "lib/method_source/source_location.rb", "lib/method_source/version.rb", "method_source.gemspec", "test/test.rb", "test/test_code_helpers.rb", "test/test_helper.rb"] + s.homepage = "http://banisterfiend.wordpress.com" + s.require_paths = ["lib"] + s.rubygems_version = "1.8.23" + s.summary = "retrieve the sourcecode for a method" + s.test_files = ["test/test.rb", "test/test_code_helpers.rb", "test/test_helper.rb"] + + if s.respond_to? :specification_version then + s.specification_version = 3 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_development_dependency(%q, ["~> 1.1.0"]) + s.add_development_dependency(%q, ["~> 0.9"]) + else + s.add_dependency(%q, ["~> 1.1.0"]) + s.add_dependency(%q, ["~> 0.9"]) + end + else + s.add_dependency(%q, ["~> 1.1.0"]) + s.add_dependency(%q, ["~> 0.9"]) + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/test/test.rb b/vendor/bundle/gems/method_source-0.8.2/test/test.rb new file mode 100644 index 0000000..4743a50 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/test/test.rb @@ -0,0 +1,138 @@ +direc = File.expand_path(File.dirname(__FILE__)) + +require 'rubygems' +require 'bacon' +require "#{direc}/../lib/method_source" +require "#{direc}/test_helper" + +describe MethodSource do + + describe "source_location (testing 1.8 implementation)" do + it 'should return correct source_location for a method' do + method(:hello).source_location.first.should =~ /test_helper/ + end + + it 'should not raise for immediate instance methods' do + [Symbol, Fixnum, TrueClass, FalseClass, NilClass].each do |immediate_class| + lambda { immediate_class.instance_method(:to_s).source_location }.should.not.raise + end + end + + it 'should not raise for immediate methods' do + [:a, 1, true, false, nil].each do |immediate| + lambda { immediate.method(:to_s).source_location }.should.not.raise + end + end + end + + before do + @hello_module_source = " def hello; :hello_module; end\n" + @hello_singleton_source = "def $o.hello; :hello_singleton; end\n" + @hello_source = "def hello; :hello; end\n" + @hello_comment = "# A comment for hello\n# It spans two lines and is indented by 2 spaces\n" + @lambda_comment = "# This is a comment for MyLambda\n" + @lambda_source = "MyLambda = lambda { :lambda }\n" + @proc_source = "MyProc = Proc.new { :proc }\n" + @hello_instance_evaled_source = " def hello_\#{name}(*args)\n send_mesg(:\#{name}, *args)\n end\n" + @hello_instance_evaled_source_2 = " def \#{name}_two()\n if 44\n 45\n end\n end\n" + @hello_class_evaled_source = " def hello_\#{name}(*args)\n send_mesg(:\#{name}, *args)\n end\n" + @hi_module_evaled_source = " def hi_\#{name}\n @var = \#{name}\n end\n" + end + + it 'should define methods on Method and UnboundMethod and Proc' do + Method.method_defined?(:source).should == true + UnboundMethod.method_defined?(:source).should == true + Proc.method_defined?(:source).should == true + end + + describe "Methods" do + it 'should return source for method' do + method(:hello).source.should == @hello_source + end + + it 'should return source for a method defined in a module' do + M.instance_method(:hello).source.should == @hello_module_source + end + + it 'should return source for a singleton method as an instance method' do + class << $o; self; end.instance_method(:hello).source.should == @hello_singleton_source + end + + it 'should return source for a singleton method' do + $o.method(:hello).source.should == @hello_singleton_source + end + + it 'should return a comment for method' do + method(:hello).comment.should == @hello_comment + end + + # These tests fail because of http://jira.codehaus.org/browse/JRUBY-4576 + unless defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby" + it 'should return source for an *_evaled method' do + M.method(:hello_name).source.should == @hello_instance_evaled_source + M.method(:name_two).source.should == @hello_instance_evaled_source_2 + M.instance_method(:hello_name).source.should == @hello_class_evaled_source + M.instance_method(:hi_name).source.should == @hi_module_evaled_source + end + end + + it "should raise error for evaled methods that do not pass __FILE__ and __LINE__ + 1 as its arguments" do + lambda { M.instance_method(:name_three).source }.should.raise MethodSource::SourceNotFoundError + end + + if !is_rbx? + it 'should raise for C methods' do + lambda { method(:puts).source }.should.raise MethodSource::SourceNotFoundError + end + end + end + + # if RUBY_VERSION =~ /1.9/ || is_rbx? + describe "Lambdas and Procs" do + it 'should return source for proc' do + MyProc.source.should == @proc_source + end + + it 'should return an empty string if there is no comment' do + MyProc.comment.should == '' + end + + it 'should return source for lambda' do + MyLambda.source.should == @lambda_source + end + + it 'should return comment for lambda' do + MyLambda.comment.should == @lambda_comment + end + end + # end + describe "Comment tests" do + before do + @comment1 = "# a\n# b\n" + @comment2 = "# a\n# b\n" + @comment3 = "# a\n#\n# b\n" + @comment4 = "# a\n# b\n" + @comment5 = "# a\n# b\n# c\n# d\n" + end + + it "should correctly extract multi-line comments" do + method(:comment_test1).comment.should == @comment1 + end + + it "should correctly strip leading whitespace before comments" do + method(:comment_test2).comment.should == @comment2 + end + + it "should keep empty comment lines" do + method(:comment_test3).comment.should == @comment3 + end + + it "should ignore blank lines between comments" do + method(:comment_test4).comment.should == @comment4 + end + + it "should align all comments to same indent level" do + method(:comment_test5).comment.should == @comment5 + end + end +end diff --git a/vendor/bundle/gems/method_source-0.8.2/test/test_code_helpers.rb b/vendor/bundle/gems/method_source-0.8.2/test/test_code_helpers.rb new file mode 100644 index 0000000..ba83a63 --- /dev/null +++ b/vendor/bundle/gems/method_source-0.8.2/test/test_code_helpers.rb @@ -0,0 +1,41 @@ +describe MethodSource::CodeHelpers do + before do + @tester = Object.new.extend(MethodSource::CodeHelpers) + end + + [ + ["p = '", "'"], + ["def", "a", "(); end"], + ["p = < 1.1.0` +* Remove deprecated hooks API ([#1209](https://github.com/pry/pry/pull/1209)) +* Add 64-bit windows support. + +#### Bug fixes, etc. +* The `gem-install` command can require gems like `net-ssh` thanks to better + logic for guessing what path to require. (#1188) +* `toggle-color` command toggles the local `_pry_.color` setting instead of the + global `Pry.color`. +* Update `Pry::CLIPPED_PRINT` to include a hex representation of object ID when + printing a return value. (#1162) +* Wrap exceptions in a proxy instead of adding singleton methods. (#1145) + * `Pry#last_exception=` now supports exception objects that have been frozen. +* `binding.pry` inside `.pryrc` file now works, with some limitations (@richo / #1118) +* Add support for BasicObjects to `ls` (#984) +* Allow `ls -c ` (#891) +* Fix indentation not working if the `mathn` stdlib was loaded (#872) +* Fix `hist`'s `--exclude-pry` switch (#874) +* Fix `gem-install` on JRuby (#870) +* Fix source lookup for instrumented classes (#923) +* Improved thread safety when multiple instances are running (#944) +* Make `edit` ignore `-n`/`--no-reload` flag and `disable_auto_reload` config + in cases where the user was editing a tempfile +* Make `gem-cd` use the most recent gem, not the oldest +* Make `install-command` honor `.gemrc` switches (#666) +* Make `hist` with no parameters show just the current session's history (#205) + * `hist --all` shows older history +* Make `-s`/`--super` flag of `show-source`/`show-doc` work when method name is + being inferred from context (#877) +* Rename `--installed-plugins` flag to `--plugins` +* Strip ANSI codes from prompt before measuring length for indentation (#493) +* Fix bug in `edit` regarding recognition of file names without suffix. +* Reduced download size by removing tests etc. from distributed gem. + +#### Dev-facing changes +* `CommandSet#commands`, sometimes referenced through `Pry.commands.commands`, + renamed to `CommandSet#to_hash`. It returns a duplicate of the internal hash + a CommandSet uses. +* `CommandSet#keys` is now an alias of `CommandSet#list_commands`. +* All commands should now reference configuration values via `_pry_.config` + (local) and not `Pry.config` (global). (#1096) + * This change improves support for concurrent environments and + context-specific Pry sessions. `_pry_.config` inherits default values from + `Pry.config` but can override them locally. +* `rake pry` now accepts switches prefixed with `_` (e.g., `rake pry _v`) +* Pagers now act like `IO`s and accept streaming output + * See `_pry_.pager.page` and `_pry_.pager.open`. +* The `Pry` class has been broken up into two smaller classes. + * `Pry` represents non-UI-specific session state, including the eval string + * `Pry::REPL` controls the user-facing interface + * This should make it easier to drive Pry from alternative interfaces + * `Pry.start` now has a `:driver` option that defaults to `Pry::REPL` + * This involved a lot of refactoring and may break plugins that depend on + the old layout +* Add `ColorPrinter` subclass of `PP` for colorized object inspection +* Add `[]` and `[]=` methods to `CommandSet`, which find and replace commands + * Example: `Pry.commands["help"] = MyHelpCommand` +* The completion API has been refactored (see fdb703a8de4ef3) +* `Pry.config.input_stack` (and the input stack concept in general) no longer + exists +* There's a new `Pry::Terminal` class that implements a number of different + methods of determining the terminal's dimensions +* Add `ReplTester` class for high-level simulation of Pry sessions in tests +* Add `Pry.main`. Returns the special instance of Object referenced by self of + `TOPLEVEL_BINDING`: "main". +* Changed second argument of `Pry.view_clip()` from Fixnum to Hash to support + returning a string with or without a hex representation of object ID. (#1162) +* The `output` and `pager` objects will now strip color-codes, so commands should + always print in color. +* Commands now have a `state` hash that is persistent across invocations of the command + in the same pry session. + +### 0.9.12.6 (2014/01/28) +* Don't fail if Bond is not installed (#1106) + +### 0.9.12.5 (2014/01/27) +* Fix early readline errors by deferring require of readline (#1081, #1095) + +### 0.9.12.4 (2013/11/23) +* Fix issue with Coderay colors being black, even when on a black background (#1016) + +### 0.9.12.3 (2013/09/11) +* Bump Coderay dependency (#987) +* Fix consecutive newlines in heredocs being collapsed (#962) +* Fix pager not working in JRuby > 1.7.5 (#992) + +### 0.9.12.2 (2013/05/10) +* Make `reload-code` with no args reload "current" file (#920) + +### 0.9.12.1 (2013/04/21) +* Add workaround for JRuby crashing bug (#890) + * Related to http://jira.codehaus.org/browse/JRUBY-7114 + +### 0.9.12 (2013/02/12) +#### Features +* `pry --gem` (see 19bfc13aa) +* `show-source` now works on commands created with `create_command` +* `whereami` now has `-m` (method), `-c` (class), and `-f` (file) options +* `show-source` now falls back to superclass (and displays warning) if it + can't find class code +* `show-source`/`show-doc` now indicate when `-a` option is available + +#### Bug fixes, etc. +* Fix commands breaking due to Slop looking at `ARGV` instead of command + parameters (#828) +* Fix pager breaking in some situations (#845) +* Fix broken rendering of some docs (#795) +* Silence warnings during failed tab-completion attempts +* Fix broken prompt when prompt is colored (#822 / #823) +* Added `reload-method` as alias for `reload-code` (for backwards + compatibility) +* Reopen `Readline.output` if it is not a tty (see 1538bc0990) + +### 0.9.11.4 (2013/01/20) +* Fix pager not rendering color codes in some circumstances +* Add `Pry.last_internal_error`, useful for devs debugging commands + +### 0.9.11.3 (2013/01/17) +* Fix `Pry.run_command` +* Improve `ls` output +* Add `:requires_gem => "jist"` to `gist` command (so dependencies can be + installed via `install-command`) +* Improve help for `edit` command + +### 0.9.11.2 (2013/01/16) +* Fix minor bug in `gist` on Windows: rescue `Jist::ClipboardError` rather + than letting the scary error spill out to users and potentially having them + think the gist didn't post. + +### 0.9.11.1 (2013/01/16) +* Fix minor bug in `gist` command where I neglected to remove + a call to a non-existent method (`no_arg`) which was called when + `gist` is invoked with no parameters + +### 0.9.11 (2013/01/16) +#### Dependency changes +* Upgrade `slop` to `~> 3.4` +* New optional dependency: `bond` + * You'll need to perform `gem install bond` + * It improves autocompletion if you use Readline + * Does not work for libedit + (More info: https://github.com/pry/pry/wiki/FAQ#wiki-readline) + * Big thanks to cldwalker + +#### Features +* Basic Ruby 2.0 support (#738) +* JRuby 1.7.0+ support (#732) +* New `reload-code` command + * Reload code for methods, classes, commands, objects and so on + * Examples: `reload-code MyClass`, `reload-code my_method`, + `reload-code my_obj` +* Bond tab completion (see "Dependency changes") +* Consolidate "show" commands into `show-source` + * `show-source` can now extract source for: + * Classes + * Methods + * Procs + * Pry commands + * Arbitrary objects (it shows the source for the class of the object) + * As a result, `show-command` is now removed +* `gist`, `play`, and `save-file` now infer object type without requiring flags + * Examples: `play MyClass`, `play my_file.rb`, `play my_method` +* Consolidate editing commands into `edit` + * `edit` can now edit: + * Files + * Methods + * Classes + * Pry commands + * As a result, `edit-method` is now removed + * Examples: `edit MyClass`, `edit my_file.rb`, `edit my_method` +* `amend-line` and `play` now properly indent code added to input buffer +* Support for multiple require switches (`pry -rubygems -r./a.rb`) (#674) +* Support for multiple exec switches (`pry -e ':one' -e ':two'`) +* Ability to customize the name displayed in the prompt (#695) +* `--patch` switch for `edit --ex` command (#716) +* Respect the `$PAGER` environment variable (#736) +* `disable-pry` command (#497) +* Two new hooks, `before_eval` and `after_eval` +* Tab completion for `Array#` in `show-source` and `show-doc` +* `gem-install` immediately requires gems +* `-l` switch for `ls` command (displays local variables) +* `gem-open` command +* `fix-indent` command +* Subcommands API +* Public test API for plugin writers (see d1489a) +* Tabular `ls` output +* `--no-line-numbers` switch for `whereami` command +* `--lines` switch for `play` command + +#### Bug fixes, etc. +* Use single escape instead of double in `find-method` (#652) +* Fix blank string delimiters (#657) +* Fix unwanted `binding_impl_method` local in scratch bindings (#622) +* Fix `edit-method -p` changing constant lookup (#645) +* Fix `.pryrc` loading twice when invoked from `$HOME` directory (#682) +* Fix Pry not remembering initial `pwd` (#675) +* Fix multiline object coloring (#717) +* Fix `show-method` not supporting `String::new` notation (#719) +* Fix `whereami` command not showing correct line numbers (#754) +* Fix buggy Cucumber AST output (#751) +* Fix `while/until do` loops indentation (#787) +* Fix `--no-plugins` switch (#526) +* Ensure all errors go to the error handler (#774) +* Fix `.pryrc` loading with wrong `__FILE__` +* Fix pager not working if `less` is not available +* Fix `^D` in nested REPL +* Many small improvements to error message clarity and documentation formatting + +### 0.9.10 (2012/07/04) +#### Dependency changes +* Upgrade `slop` to version 3 (#561) +* Switch from `gist` gem to `jist` (#590) +* Upgrade `method_source` to 0.8 + +#### Features +* Add `--hist`, `-o` and `-k` flags to `gist` command (#572) +* Support `show-source`/`show-doc` on methods defined in `class_eval` (#584) +* Support `show-source`/`show-doc` on gem methods defined in C (#585) +* Add `--disable-plugin` and `--select-plugin` options (#596) +* Allow `cd -` to switch between bindings (#597) +* Add `Pry.config.should_load_local_rc` to turn off `./.pryrc` (#612) +* Allow running a file of Pry input with `pry ` +* Support colours in `ri` command +* Add `before_eval` hook +* The prompt proc now gets a lot more data when its arity is 1 + +#### Bug fixes, etc. +* Removed the `req` command (#554) +* Fix rendering bugs when starting Pry (#567) +* Fix `Array#pretty_print` on Jruby (#568) +* Fix `edit` on Windows (#575) +* Fix `find-method` in the presence of badly behaved objects (#576) +* Fix `whereami` in ERb files on Rails (#580) +* Raise fewer exceptions while tab completing (#632) +* Don't immediately quit Pry when an error happens in Readline (#605) +* Support for `ansicon` to give JRuby Windows users colour (#606) +* Massive speed improvements to `show-source` for modules (#613) +* Improve `whereami` command when not in a `binding.pry` (#620) +* Support embedded documents (`=begin` ... `=end`) (#622) +* Support editing files with spaces in the name (#627) +* Renamed `__binding_impl__` to `__pry__` +* Support for absolute paths in `$EDITOR` +* Fix `cat` command on files with unknown extensions +* Many, many internal refactorings and tidyings + +### 0.9.9.6 (2012/05/09) +* Fix `ZeroDivisionError` in `correct_indentation` (#558) + +### 0.9.9.5 (2012/05/09) +* Fix `ZeroDivisionError` in `correct_indentation` (#558) +* Fix double highlighting in RDoc (#562) +* Automatically create configuration for plugins (#548) + +### 0.9.9.4 (2012/04/26) +* Fix `NoMethodError: undefined method `winsize' for #>` (#549) +* Fixes for JRuby +* Fix syntax error on `exit` (550) +* Heredoc content no longer auto-indented + +### 0.9.9.3 (2012/04/19) +* Fix `show-doc` failing on some core classes, like `Bignum` + +### 0.9.9.2 (2012/04/18) +* Make `correct_indentation`'s auto-colorization respect `Pry.color` + +### 0.9.9.1 (2012/04/18) +* Clear up confusion in `show-source`/`show-doc` docs + * `-a` switch applies to classes as well as modules + +### 0.9.9 (2012/04/18) +#### New features +* Lines of input are syntax highlighted upon Enter keypress +* `show-source` command can now show class/module source code + * Use `-a` to see all monkeypatches + * Hard dependency on `ruby18_source_location` gem in MRI 1.8 +* `show-doc` command can now show class/module docs + * Use `-a` to see docs for all monkeypatches + * Hard dependency on `ruby18_source_location` gem in MRI 1.8 +* New `find-method` command + * Performs a recursive search in a namespace for the existence of methods + * Can find methods whose names match a regex or methods which contain + provided code + * This command is like a ruby-aware `grep`, very cool (thanks swarley) +* [`pry-coolline`](https://github.com/pry/pry-coolline) now works properly +* `alias_command` method now much more powerful + * Example: `alias_command "lM", "ls -M"` +* `whereami` is now more intelligent + * Automatically shows entire source code of current method if current + context is a method (thanks robgleeson) +* New `raise-up` command + * Allows you to raise an exception that will bubble out of pry (ending the + session) and escape into enclosing program + +#### Bug fixes, etc. +* Fixed crash when paging under Windows +* Lines ending with `\` are incomplete (kudos to fowl) +* `edit-method -n` no longer blocks (thanks misfo) +* Show instance methods of modules by default in `ls` +* Docs for REPL-defined methods can now be displayed using `show-doc` +* Autoload `ruby18_source_location` on MRI 1.8, when available + * See https://github.com/conradirwin/ruby18_source_location +* Tab completion should work on first line now (historic bug fixed) +* `:quiet => true` option added to `Pry.start`, turns off `whereami` +* Another easter egg added +* Show unloaded constants in yellow for `ls` +* Improved documentation for `Pry.config` options +* Improved auto-indentation +* JRuby: heuristics used to clean up `ls` output + * Fewer internal methods polluting output + +### 0.9.8.4 (2012/6/3) +* ~/.pry_history wasnt being created (if it did not exist)! FIXED +* `hist --save` saved colors! FIXED +* added Pry#add_sticky_local API for adding sticky locals to individual pry instances + +### 0.9.8.3 (2012/3/2) +* various tweaks to improve rbx support +* commands now support optional block arguments +* much improved help command +* updated method_source dependencya +* added wtf command +* jruby should now work in windows (though without color) + +### 0.9.8.2 (2012/2/9) +* fixed bugs related to --super +* upgraded slop dependency +* added edit -c (edit current line) +* edit now respects Pry.config.disable_autoreload option + +### 0.9.8.1 (2012/1/30) +* fixed broken --no-plugins option +* Ensure ARGV is not mutated during option parsing. +* Use a more rbx-friendly test for unicodeness +* Use rbx-{18,19}mode as indicated http://about.travis-ci.org/docs/user/languages/ruby/ +* Don't explode in gem-list [Fixes #453, #454] +* Check for command-name collision on assignment [Fixes #450] + +### 0.9.8 (2012/1/25) + +MAJOR NEW FEATURES +- upgraded command api, https://github.com/pry/pry/wiki/Custom-commands +- added a system of hooks for customizing pry behaviour +- changed syntax checking to use eval() for improved accuracy +- added save-file command +- added gist command (removed gist-method, new gist command is more general) + +complete CHANGELOG: +* CommandError's no longer cause the current input to be disgarded +* Better syntax highlighting for rbx code code +* added cat --in to show pry input history +* prefixed temporary file names with 'pry' +* show-doc now supports -l and -b options (line numbers) +* play now supports -i and -d options +* moved UserCommandAPI command-set to pry-developer_tools plugin +* added :when_started event for hooks, called in Pry.start +* added a man page +* added rename method to Pry::CommandSet (commands can be renamed) +* added CommandSet#{before_command,after_command} for enhancing builtin commands +* added checking for namespace collisions with pry commands, set Pry.config.collision_warning +* work around namespace collisions by ensuring lines starting with a space are executed as +* ruby.work around namespace collisions by prensuring lines starting with a space are executed as ruby +* added handlers for Ctrl+C (SIGINT) on jruby, these are now caught as in other ruby versions +* removed dependency on ruby_parser +* prevented colours leaking across the pry prompt +* fixed edge cases in Pry::Method, for methods with crazy names and methods that have been 'undef'd +* refactored history handling code for clarity and correctness +* added Pry::WrappedModule as a counterpart to Pry::Method +* made a trailing , cause pry to wait for further input +* removed gist-method command, added gist command +* added pry-backtrace command to show history of current session +* fixed whereami within 'super' methods +* replaced inline version guards by Pry::Helpers::BaseHelpers.{rbx?,jruby?,windows?} etc. +* removed the CommandProcessor, its functionality is part of the new Command class +* changed cd .. at the top level so it doesn't quit pry. +* changed edit-command to no-longer need a command set argument +* fixed empty lines so that they don't replace _ by nil +* fixed SyntaxErrors at the REPL level so they don't replace _ex_. + +### 0.9.7.4 (2011/11/5) +* ls -M now works in modules (bugfix) +* added exception msg for bad cd object/path +* no longer die when encounter exceptions in .pryrc +* baked in CoolLine support +* Pry.config.input in .pryrc now respected + +### 0.9.7.3 (2011/10/28) +* really fixed indentation for 'super if' and friends +* Fixed indentation for tmux +* added Pry.config.correct_indent option (to toggle whether indentation +* corrected optional param behaviour for method signatures: e.g Signature meth(param1=?, param2=?) + +### 0.9.7.2 (2011/10/27) +* fixed indentation for 'super if' and 'ensure', 'next if', etc +* refactored Pry#run_command so it can accept an eval_string parameter (so amend-line and so on can work with it) +* changed ^D so it no longer resets indent level automatically + +### 0.9.7.1 (2011/10/26) +* fixed gem dependecy issues + +### 0.9.7 (2011/10/25) + +MAJOR NEW FEATURES: +- upgraded ls command to have a more intuitive interface +- added automatic indentation (thanks YorickPeterse!) +- added Pry::Method wrapper class to encapsulate method-related functionality + +complete CHANGELOG: +* fixed syntax highlighting for object literals +* fixed ActiveSupport method-naming conflict with "in?" +* added --super option to edit-method, show-method, and friends - making it easier to operate on superclass methods +* officially added edit --in to open previous expressions in an editor +* whereami now works for REPL-defined code +* started using JRuby parser for input validation in JRuby (thanks pangloss!) +* fixed bug where ~/.pryrc could be loaded more than once (thanks kelseyjudson!) +* added parse_options! helper to pull option parsing out of commands +* Pry now respects the terminal's input encoding +* moved some requires out of the startup process for improved speed +* added input_array info to DEFAULT_PROMPT, e.g [1] pry(main)> +* added --no-history option to pry binary (prevent history being LOADED, history will still be saved) + +### 0.9.6.2 (2011/9/27) +* downgrading to CodeRay 0.9.8 due to problems with 1.0 and rails (autoloading problem) see #280 on pry and #6 on CodeRay +* also added (as a minor feature) cirwin's implementation of edit --in +* added early break/exit for objectpath errors (the 'cd 34/@hello/bad_path/23') + +### 0.9.6 (2011/9/19) +* restored previous behavior of command-line switches (allowing "-rfilename") +* removed -p option (--play) from edit command +* `edit` with no arguments now edits the current or most recent expression +* `edit` auto-reloads .rb files (need to specify -n to suppress) +* added -p option (--patch) to edit-method command, which allows + monkeypatching methods without touching the original file +* edit-method can now edit REPL-defined methods +* cat --ex now works on exceptions in REPL-defined code +* play -m now uses eval_string.replace() +* play -m --open uses show-input to show play'd code +* added "unindent" helper to make adding help to commands easier +* local ./.pryrc now loaded after ~/.pryrc if it exists +* cat --ex N and edit --ex N now can navigate through backtrace, where cat --ex (with no args) moves throuh successive levels of the backtrace automatically with state stored on the exceptino object itself +* new option Pry.config.exception_window_size determines window size for cat --ex +* input_stack now implemented - pushing objects onto a pry instance's input_stack causes the instance to read from those objects in turn as it encounters EOF on the previous object. On finishing the input_stack the input object for the pry instance is set back to Pry.config.input, if this fails, pry breaks out of the REPL (throw(:breakout)) with an error message +* Pry.config.system() defines how pry runs system commands +* now injecting target_self method into command scope +* play now performs 'show-input' always unless eval_string contains a valid expression (i.e it's about to be eval'd) +* play and hist --replay now push the current input object onto the input_stack before redirecting input to a StringIO (works much better with pry-remote now) + +### 0.9.5 (2011/9/8) + +MAJOR NEW FEATURES: +- JRuby support, including show-method/edit-method and editor integration on both 1.8 and 1.9 versions +- extended cd syntax: cd ../@x/y +- play command now works much better with _in_ array (this is a very powerful feature, esp with Pry::NAV_PROMPT) +- history saving/loading is now lightning fast +- 'edit' (entered by itself) now opens current lines in input buffer in an editor, and evals on exit +- 'edit' command is also, in general more intelligent +- ls output no longer in array format, and colors can be configured, e.g: Pry.config.ls.ivar_color = :bright_blue +- new switch-to command for moving around the binding stack without exiting out of sessions +- more sophisticated prompts, Pry::NAV_PROMPT to ease deep spelunking of code +- major bug fix for windows systems +- much better support for huge objects, should no longer hang pry (see #245) +- cat --ex and edit --ex now work better + +complete CHANGELOG: +* tempfile should end in .rb (for edit -t) +* ls output should not be in array format +* fix history saving (should not save all of Readline::HISTORY, but only what changed) +* prevent blank lines going to Readline::HISTORY (thanks cirwin!) +* ensure that cat --ex emulates the `whereami` format - includes line numbers and formatted the same, etc +* fixed bug #200 ( https://github.com/pry/pry/issues/200 )- string interpolation bug (thanks to ryanf) +* show-doc and stat now display method visibility (update WIKI) +* got rid of warnings caused by stricter ruby 1.9.3 rules +* remove interpolation of command names and fix interpolation error messag (update WIKI) (thanks ryanf!) +* 'nested sessions' now use binding stacks (so each instance manages its own collection of bindings without spawning other instances) +* 'cd ..' just pops a binding off the binding_stack with special behaviour when only one binding in stack - it breaks out of the repl loop +* added switch-to command (like jump-to but doesnt unwind the stack) +* show-method and show-doc now accept multiple method names +* control_d hook added (Pry.config.control_d_handler) +* behaviour of ^d is now to break out of current expr if in multi-line expr, or break out of current context if nested, or break out of pry repl loop if at top-level +* can no longer interpolate command name itself e.g #{x}-#{y} where x = "show" and y = "doc" +* ^C no longer captured +* got rid of Pry.active_instance, Pry.last_exception and friends. +* also special locals now shared among bindings in a pry instance (i.e _ex_ (and friends) re-injected into new binding entered with 'cd') +* renamed inp and out to _in_ and _out_ (to avoid collisions with actual locals in debugging scope) +* added third parameter to prompts, the pry instance itself (_pry) see https://github.com/pry/pry/issues/233 for why it's important +* cd behaviour when no args performs the same as `cd /` +* commands with keep_retval can now return nil (to suppress output now return 'void' instead) +* Pry::CommandProcessor::Result introduced +* Pry.view_clip() modified to be more robust and properly display Class#name +* edit command when invoked with no args now works like edit -t +* when edit is invoked (with no args or with -t) inside a multi-line expression input buffer, it dumps that buffer into a temp file and takes you to it +* got rid of Pry#null_input? since all that was needed was eval_string.empty? +* cd command now supports complex syntax: cd ../@y/y/../z +* JRuby is no longer a 2nd class citizen, almost full JRuby support, passing 100% tests +* added Pry::NAV_PROMPT (great new navigation prompt, per robgleeson) and Pry::SIMPLE_PRINT for simple (IRB-style) print output (just using inspect) +* _pry_ now passed as 3rd parameter to :before_session hook +* ls colors now configurable via Pry.config.ls.local_var_color = :bright_red etc +* ls separator configurable via, e.g Pry.config.ls.separator = " " +* Pry.view_clip() now only calls inspect on a few immediates, otherwise uses the #<> syntax, which has been truncated further to exclude teh mem address, again related to #245 + +### 0.9.3 (2011/7/27) +* cat --ex (cats 5 lines above and below line in file where exception was raised) +* edit --ex (edits line in file where exception was raised) +* edit -t (opens a temporary file and evals it in current context when closed) +* `pry -r` requires now happen after plugin loading (so as not to interfere with +* new Pry.config.disable_auto_reload option, for turning off auto reloading by edit-method and related (thanks ryanf) +* add better error messages for `cd` command +* fixed exotic object regression - BasicObject.new etc now return "=> unknown" +* added reload-method command (reloads the associated file of a method) +* converted: import => import-set, version => pry-version, install => install-command +* Pry.config.command_prefix support (thanks ryanf!) +* fixed indentation for simple-prompt +* hist command now excludes last line of input (the command invocation itself) +* hist now has `history` alias +* missing plugins no longer raise exception, just print a warning to $stderr +* fixed jedit editor support + +### 0.9.2 (2011/6/21) +* fixed string interpolation bug (caused valid ruby code not to execute, sorry!) +* fixed `ls` command, so it can properly display members of Object and classes, and BasicObject, etc +* added a few git related commands to experimental command set, blame and diff + +### 0.9.0 (2011/6/17) +* plugin system +* regex commands +* show-method works on methods defined in REPL +* new command system/API +* rubinius core support +* more backports to ruby 1.8 +* inp/out special locals +* _ex_ backtrace navigation object (_ex_.line, _ex_.file) +* readline history saving/loading +* prompt stack +* more hooks +* amend-line +* play +* show-input +* edit +* much more comprehensive test suite +* support for new and old rubygems API +* changed -s behaviour of ls (now excludes Object methods) +* removed eval-file, lls, lcd, and a few other commands + + +### 0.7.6.1 (2011/3/26) +* added slightly better support for YARD +* now @param and @return tags are colored green and markdown `code` is syntax highlighted using coderay + +### 0.7.6 (2011/3/26) +* `whereami` command now accepts parameter AROUND, to display AROUND lines on eitherside of invocation line. +* made it so `whereami` is invoked even if no method exists in current context (i.e in rspec tests) +* added rubinius support for `whereami` invocation in HOOKS by checking for __unknown__.rb rather than just
+ +### 0.7.0 (2011/3/15) +* add pry-doc support with syntax highlighting for docs +* add 'mj' option to ls (restrict to singleton methods) +* add _ex_ local to hold last exception raised in an exception + +### 0.6.8 (2011/3/6) +* add whereami command, a la the `ir_b` gem +* make whereami run at the start of every session +* make .pryrc be loaded by run-time pry sessions + +### 0.6.7 (2011/3/4) +* color support +* --simple-prompt for pry commandline +* -I mode for pry commandline +* --color mode for pry commandline +* clean up requires (put them all in one place) +* simple-prompt command and toggle-color commandd. + +### 0.6.3 (2011/2/28) +* Using MethodSource 0.3.4 so 1.8 show-method support provided +* `Set` class added to list of classes that are inspected + +### 0.6.1 (2011/2/26) +* !@ command alias for exit_all +* `cd /` for breaking out to pry top level (jump-to 0) +* made `-e` option work in a more effective way for `pry` command line invocation +* exit and exit-all commands now accept a parameter, this parameter becomes the return value of repl() +* `command` method from CommandBase now accepts a :keep_retval arg that determines if command value is returned to pry session or just `nil` (`nil` was old behaviour) +* tests for new :keep_retval and exit-all/exit behaviour; :keep_retval will remain undocumented. + +### 0.5.8 (2011/2/22) +* Added -c (context) option to show-doc, show-methods and eval-file +* Fixed up ordering issue of -c and -r parameters to command line pry + +### 0.5.7 (2011/2/21) +* Added pry executable, auto-loads .pryrc in user's home directory, if it + exists. + +### 0.5.5 (2011/2/19) +* Added Pry.run_command +* More useful error messages +* Easter eggs (game and cohen-poem) + +### 0.5.0 (2011/2/17) +* Use clipped version of Pry.view() for large objects +* Exit Pry session on ^d +* Use Shellwords for breaking up parameters to pry commands +* Use OptionParser to parse options for default pry commands +* Add version command +* Refactor 'status' command: add current method info +* Add meth_name_from_binding utility lambda to commands.rb +* Add -M, -m, -v(erbose), -a(ll), -s(uper), -l(ocals), -i(ivars), -k(klass + vars), etc options to ls +* add -M(instance method) options to show-method and show-doc +* add --help option to most commands +* Get rid of ls_method and ls_imethods (subsumed by more powerful ls) +* Get rid of show_idoc and show_imethod +* Add special eval-file command that evals target file in current context + +### 0.4.5 (2011/1/27) +* fixed show_method (though fragile as it references __binding_impl__ + directly, making a name change to that method difficult + +### 0.4.4 (2011/1/27) +* oops, added examples/ directory + +### 0.4.3 (2011/1/26) +* added alias_command and desc methods to Pry::CommandBase +* changed behaviour of ls_methods and ls_imethods to return sorted lists + of methods + +### 0.4.1 (2011/1/23) +* made it so a 'def meth;end' in an object Pry session defines singleton + methods, not methods on the class (except in the case of + immediates) +* reorganized documentation, moving customization to a separate wiki file +* storing wiki in a nested git repo, as github wiki pages have their own + repo +* added more tests for new method definition behaviour + +### 0.4.0 (2011/1/21) +* added command API +* added many new commands, i.e ls_methods and friends +* modified other commands +* now accepts greater customization, can modify: input, output, hooks, + prompt, print object +* added tab completion (even completes commands) +* added extensive tests +* added examples +* many more changes + +### 0.1.3 (2010/12/9) +* Got rid of rubygems dependency, refactored some code. + +### 0.1.2 (2010/12/8) +* now rescuing SyntaxError as well as Racc::Parser error in valid_expression? + +### 0.1.0 (2010/12/8) +* release! diff --git a/vendor/bundle/gems/pry-0.10.0/LICENSE b/vendor/bundle/gems/pry-0.10.0/LICENSE new file mode 100644 index 0000000..1258004 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/LICENSE @@ -0,0 +1,25 @@ +License +------- + +(The MIT License) + +Copyright (c) 2013 John Mair (banisterfiend) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/gems/pry-0.10.0/README.md b/vendor/bundle/gems/pry-0.10.0/README.md new file mode 100644 index 0000000..9668562 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/README.md @@ -0,0 +1,406 @@ +[![Build Status](https://img.shields.io/travis/pry/pry.svg)](https://travis-ci.org/pry/pry) +[![Code Climate](https://img.shields.io/codeclimate/github/pry/pry.svg)](https://codeclimate.com/github/pry/pry) +[![Inline docs](http://inch-pages.github.io/github/pry/pry.svg)](http://inch-pages.github.io/github/pry/pry) + +
+![The Pry Logo](https://dl.dropbox.com/u/26521875/pry%20stuff/logo/pry_logo_350.png) + +© John Mair ([banisterfiend](https://twitter.com/banisterfiend)) 2013
+ +**Please** [DONATE](http://www.pledgie.com/campaigns/15899) to the Pry project - Pry was a **huge** amount of work and every donation received is encouraging and supports Pry's continued development! + +**Sponsors** + +[Tealeaf Academy](http://www.gotealeaf.com)
+[Atomic Object](http://www.atomicobject.com/)
+[Hashrocket](http://hashrocket.com/)
+[Intridea](http://intridea.com/)
+[Gaslight](http://gaslight.co/home)
+ +**Other Resources** + +[Skip to the website (recommended)](http://pry.github.com)
+[Skip to the wiki](https://github.com/pry/pry/wiki) +
+ +Pry is a powerful alternative to the standard IRB shell for Ruby. It is +written from scratch to provide a number of advanced features, +including: + +* Source code browsing (including core C source with the pry-doc gem) +* Documentation browsing +* Live help system +* Open methods in editors (`edit Class#method`) +* Syntax highlighting +* Command shell integration (start editors, run git, and rake from within Pry) +* Gist integration +* Navigation around state (`cd`, `ls` and friends) +* Runtime invocation (use Pry as a developer console or debugger) +* Exotic object support (BasicObject instances, IClasses, ...) +* A Powerful and flexible command system +* Ability to view and replay history +* Many convenience commands inspired by IPython, Smalltalk and other advanced REPLs +* A wide-range number of [plugins](https://github.com/pry/pry/wiki/Available-plugins) that provide remote sessions, full debugging functionality, and more. + +Pry also aims to be more than an IRB replacement; it is an +attempt to bring REPL driven programming to the Ruby language. It is +currently not as powerful as tools like [SLIME](http://en.wikipedia.org/wiki/SLIME) for lisp, but that is the +general direction Pry is heading. + +Pry is also fairly flexible and allows significant user +[customization](https://github.com/pry/pry/wiki/Customization-and-configuration) +is trivial to set it to read from any object that has a `readline` method and write to any object that has a +`puts` method - many other aspects of Pry are also configurable making +it a good choice for implementing custom shells. + +Pry comes with an executable so it can be invoked at the command line. +Just enter `pry` to start. A `.pryrc` file in the user's home directory will +be loaded if it exists. Type `pry --help` at the command line for more +information. + +Try `gem install pry-doc` for additional documentation on Ruby Core +methods. The additional docs are accessed through the `show-doc` and +`show-method` commands. + +* Install the [gem](https://rubygems.org/gems/pry): `gem install pry` +* Browse the comprehensive [documentation at the official Pry wiki](https://github.com/pry/pry/wiki) +* Read the [YARD API documentation](http://rdoc.info/github/pry/pry/master/file/README.markdown) +* See the [source code](http://github.com/pry/pry) + +### Commands + +Nearly every piece of functionality in a Pry session is implemented as +a command. Commands are not methods and must start at the beginning of a line, with no +whitespace in between. Commands support a flexible syntax and allow +'options' in the same way as shell commands, for example the following +Pry command will show a list of all private instance methods (in +scope) that begin with 'pa' + + pry(YARD::Parser::SourceParser):5> ls -Mp --grep ^pa + YARD::Parser::SourceParser#methods: parse parser_class parser_type parser_type= parser_type_for_filename + +### Navigating around state + +Pry allows us to pop in and out of different scopes (objects) using +the `cd` command. This enables us to explore the run-time view of a +program or library. To view which variables and methods are available +within a particular scope we use the versatile [ls command.](https://gist.github.com/c0fc686ef923c8b87715) + +Here we will begin Pry at top-level, then Pry on a class and then on +an instance variable inside that class: + + pry(main)> class Hello + pry(main)* @x = 20 + pry(main)* end + => 20 + pry(main)> cd Hello + pry(Hello):1> ls -i + instance variables: @x + pry(Hello):1> cd @x + pry(20):2> self + 10 + => 30 + pry(20):2> cd .. + pry(Hello):1> cd .. + pry(main)> cd .. + +The number after the `:` in the pry prompt indicates the nesting +level. To display more information about nesting, use the `nesting` +command. E.g + + pry("friend"):3> nesting + Nesting status: + 0. main (Pry top level) + 1. Hello + 2. 100 + 3. "friend" + => nil + +We can then jump back to any of the previous nesting levels by using +the `jump-to` command: + + pry("friend"):3> jump-to 1 + => 100 + pry(Hello):1> + +### Runtime invocation + +Pry can be invoked in the middle of a running program. It opens a Pry +session at the point it's called and makes all program state at that +point available. It can be invoked on any object using the +`my_object.pry` syntax or on the current binding (or any binding) +using `binding.pry`. The Pry session will then begin within the scope +of the object (or binding). When the session ends the program continues with any +modifications you made to it. + +This functionality can be used for such things as: debugging, +implementing developer consoles and applying hot patches. + +code: + + # test.rb + require 'pry' + + class A + def hello() puts "hello world!" end + end + + a = A.new + + # start a REPL session + binding.pry + + # program resumes here (after pry session) + puts "program resumes here." + +Pry session: + + pry(main)> a.hello + hello world! + => nil + pry(main)> def a.goodbye + pry(main)* puts "goodbye cruel world!" + pry(main)* end + => nil + pry(main)> a.goodbye + goodbye cruel world! + => nil + pry(main)> exit + + program resumes here. + +### Command Shell Integration + +A line of input that begins with a '.' will be forwarded to the +command shell. This enables us to navigate the file system, spawn +editors, and run git and rake directly from within Pry. + +Further, we can use the `shell-mode` command to incorporate the +present working directory into the Pry prompt and bring in (limited at this stage, sorry) file name completion. +We can also interpolate Ruby code directly into the shell by +using the normal `#{}` string interpolation syntax. + +In the code below we're going to switch to `shell-mode` and edit the +`.pryrc` file in the home directory. We'll then cat its contents and +reload the file. + + pry(main)> shell-mode + pry main:/home/john/ruby/projects/pry $ .cd ~ + pry main:/home/john $ .emacsclient .pryrc + pry main:/home/john $ .cat .pryrc + def hello_world + puts "hello world!" + end + pry main:/home/john $ load ".pryrc" + => true + pry main:/home/john $ hello_world + hello world! + +We can also interpolate Ruby code into the shell. In the +example below we use the shell command `cat` on a random file from the +current directory and count the number of lines in that file with +`wc`: + + pry main:/home/john $ .cat #{Dir['*.*'].sample} | wc -l + 44 + +### Code Browsing + +You can browse method source code with the `show-method` command. Nearly all Ruby methods (and some C methods, with the pry-doc +gem) can have their source viewed. Code that is longer than a page is +sent through a pager (such as less), and all code is properly syntax +highlighted (even C code). + +The `show-method` command accepts two syntaxes, the typical ri +`Class#method` syntax and also simply the name of a method that's in +scope. You can optionally pass the `-l` option to show-method to +include line numbers in the output. + +In the following example we will enter the `Pry` class, list the +instance methods beginning with 're' and display the source code for the `rep` method: + + pry(main)> cd Pry + pry(Pry):1> ls -M --grep re + Pry#methods: re readline refresh rep repl repl_epilogue repl_prologue retrieve_line + pry(Pry):1> show-method rep -l + + From: /home/john/ruby/projects/pry/lib/pry/pry_instance.rb @ line 143: + Number of lines: 6 + + 143: def rep(target=TOPLEVEL_BINDING) + 144: target = Pry.binding_for(target) + 145: result = re(target) + 146: + 147: show_result(result) if should_print? + 148: end + +Note that we can also view C methods (from Ruby Core) using the +`pry-doc` plugin; we also show off the alternate syntax for +`show-method`: + + pry(main)> show-method Array#select + + From: array.c in Ruby Core (C Method): + Number of lines: 15 + + static VALUE + rb_ary_select(VALUE ary) + { + VALUE result; + long i; + + RETURN_ENUMERATOR(ary, 0, 0); + result = rb_ary_new2(RARRAY_LEN(ary)); + for (i = 0; i < RARRAY_LEN(ary); i++) { + if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) { + rb_ary_push(result, rb_ary_elt(ary, i)); + } + } + return result; + } + +### Documentation Browsing + +One use-case for Pry is to explore a program at run-time by `cd`-ing +in and out of objects and viewing and invoking methods. In the course +of exploring it may be useful to read the documentation for a +specific method that you come across. Like `show-method` the `show-doc` command supports +two syntaxes - the normal `ri` syntax as well as accepting the name of +any method that is currently in scope. + +The Pry documentation system does not rely on pre-generated `rdoc` or +`ri`, instead it grabs the comments directly above the method on +demand. This results in speedier documentation retrieval and allows +the Pry system to retrieve documentation for methods that would not be +picked up by `rdoc`. Pry also has a basic understanding of both the +rdoc and yard formats and will attempt to syntax highlight the +documentation appropriately. + +Nonetheless, the `ri` functionality is very good and +has an advantage over Pry's system in that it allows documentation +lookup for classes as well as methods. Pry therefore has good +integration with `ri` through the `ri` command. The syntax +for the command is exactly as it would be in command-line - +so it is not necessary to quote strings. + +In our example we will enter the `Gem` class and view the +documentation for the `try_activate` method: + + pry(main)> cd Gem + pry(Gem):1> show-doc try_activate + + From: /Users/john/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/site_ruby/1.9.1/rubygems.rb @ line 201: + Number of lines: 3 + + Try to activate a gem containing path. Returns true if + activation succeeded or wasn't needed because it was already + activated. Returns false if it can't find the path in a gem. + pry(Gem):1> + +We can also use `ri` in the normal way: + + pry(main) ri Array#each + ----------------------------------------------------------- Array#each + array.each {|item| block } -> array + ------------------------------------------------------------------------ + Calls _block_ once for each element in _self_, passing that element + as a parameter. + + a = [ "a", "b", "c" ] + a.each {|x| print x, " -- " } + + produces: + + a -- b -- c -- + +### Gist integration + +If the `gist` gem is installed then method source or documentation can be gisted to github with the +`gist` command. The `gist` command is capable of gisting [almost any REPL content](https://gist.github.com/cae143e4533416529726), including methods, documentation, +input expressions, command source, and so on. In the example below we will gist the C source +code for the `Symbol#to_proc` method to github: + + pry(main)> gist -m Symbol#to_proc + Gist created at https://gist.github.com/5332c38afc46d902ce46 and added to clipboard. + pry(main)> + +You can see the actual gist generated here: [https://gist.github.com/5332c38afc46d902ce46](https://gist.github.com/5332c38afc46d902ce46) + +### Edit methods + +You can use `edit Class#method` or `edit my_method` +(if the method is in scope) to open a method for editing directly in +your favorite editor. Pry has knowledge of a few different editors and +will attempt to open the file at the line the method is defined. + +You can set the editor to use by assigning to the `Pry.editor` +accessor. `Pry.editor` will default to `$EDITOR` or failing that will +use `nano` as the backup default. The file that is edited will be +automatically reloaded after exiting the editor - reloading can be +suppressed by passing the `--no-reload` option to `edit` + +In the example below we will set our default editor to "emacsclient" +and open the `Pry#repl` method for editing: + + pry(main)> Pry.editor = "emacsclient" + pry(main)> edit Pry#repl + +### Live Help System + +Many other commands are available in Pry; to see the full list type +`help` at the prompt. A short description of each command is provided +with basic instructions for use; some commands have a more extensive +help that can be accessed via typing `command_name --help`. A command +will typically say in its description if the `--help` option is +avaiable. + +### Use Pry as your Rails Console + +The recommended way to use Pry as your Rails console is to add +[the `pry-rails` gem](https://github.com/rweng/pry-rails) to +your Gemfile. This replaces the default console with Pry, in +addition to loading the Rails console helpers and adding some +useful Rails-specific commands. + +If you don't want to change your Gemfile, you can still run a Pry +console in your app's environment using Pry's `-r` flag: + + pry -r ./config/environment + +Also check out the [wiki](https://github.com/pry/pry/wiki/Setting-up-Rails-or-Heroku-to-use-Pry) +for more information about integrating Pry with Rails. + +### Limitations: + +* Tab completion is currently a bit broken/limited this will have a + major overhaul in a future version. + +### Syntax Highlighting + +Syntax highlighting is on by default in Pry. If you want to change +the colors, check out the [pry-theme](https://github.com/kyrylo/pry-theme) +gem. + +You can toggle the syntax highlighting on and off in a session by +using the `toggle-color` command. Alternatively, you can turn it off +permanently by putting the line `Pry.color = false` in your `~/.pryrc` +file. + +### Future Directions + +Many new features are planned such as: + +* Increase modularity (rely more on plugin system) +* Much improved documentation system, better support for YARD +* Better support for code and method reloading and saving code +* Extended and more sophisticated command system, allowing piping +between commands and running commands in background + +### Contact + +Problems or questions? file an issue at [github](https://github.com/pry/pry/issues) + +### Contributors + +Pry is primarily the work of [John Mair (banisterfiend)](http://github.com/banister), for full list +of contributors see the +[CONTRIBUTORS](https://github.com/pry/pry/blob/master/CONTRIBUTORS) file. diff --git a/vendor/bundle/gems/pry-0.10.0/bin/pry b/vendor/bundle/gems/pry-0.10.0/bin/pry new file mode 100755 index 0000000..3904fe9 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/bin/pry @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby + +# (C) John Mair (banisterfiend) +# MIT license + +$0 = 'pry' + +begin + require 'pry' +rescue LoadError + require 'rubygems' + require 'pry' +end + +# Process command line options and run Pry +Pry::CLI.parse_options diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry.rb new file mode 100644 index 0000000..a8e81c0 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry.rb @@ -0,0 +1,161 @@ +# (C) John Mair (banisterfiend) 2013 +# MIT License +# +require 'pp' + +require 'pry/input_lock' +require 'pry/exceptions' +require 'pry/helpers/base_helpers' +require 'pry/hooks' +require 'forwardable' + +class Pry + # The default hooks - display messages when beginning and ending Pry sessions. + DEFAULT_HOOKS = Pry::Hooks.new.add_hook(:before_session, :default) do |out, target, _pry_| + next if _pry_.quiet? + _pry_.run_command("whereami --quiet") + end + + # The default print + DEFAULT_PRINT = proc do |output, value, _pry_| + _pry_.pager.open do |pager| + pager.print _pry_.config.output_prefix + Pry::ColorPrinter.pp(value, pager, Pry::Terminal.width! - 1) + end + end + + # may be convenient when working with enormous objects and + # pretty_print is too slow + SIMPLE_PRINT = proc do |output, value| + begin + output.puts value.inspect + rescue RescuableException + output.puts "unknown" + end + end + + # useful when playing with truly enormous objects + CLIPPED_PRINT = proc do |output, value| + output.puts Pry.view_clip(value, id: true) + end + + # Will only show the first line of the backtrace + DEFAULT_EXCEPTION_HANDLER = proc do |output, exception, _| + if UserError === exception && SyntaxError === exception + output.puts "SyntaxError: #{exception.message.sub(/.*syntax error, */m, '')}" + else + output.puts "#{exception.class}: #{exception.message}" + output.puts "from #{exception.backtrace.first}" + end + end + + DEFAULT_PROMPT_NAME = 'pry' + + # The default prompt; includes the target and nesting level + DEFAULT_PROMPT = [ + proc { |target_self, nest_level, pry| + "[#{pry.input_array.size}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}> " + }, + + proc { |target_self, nest_level, pry| + "[#{pry.input_array.size}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}* " + } + ] + + DEFAULT_PROMPT_SAFE_OBJECTS = [String, Numeric, Symbol, nil, true, false] + + # A simple prompt - doesn't display target or nesting level + SIMPLE_PROMPT = [proc { ">> " }, proc { " | " }] + + NO_PROMPT = [proc { '' }, proc { '' }] + + SHELL_PROMPT = [ + proc { |target_self, _, _pry_| "#{_pry_.config.prompt_name} #{Pry.view_clip(target_self)}:#{Dir.pwd} $ " }, + proc { |target_self, _, _pry_| "#{_pry_.config.prompt_name} #{Pry.view_clip(target_self)}:#{Dir.pwd} * " } + ] + + # A prompt that includes the full object path as well as + # input/output (_in_ and _out_) information. Good for navigation. + NAV_PROMPT = [ + proc do |_, _, _pry_| + tree = _pry_.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / " + "[#{_pry_.input_array.count}] (#{_pry_.config.prompt_name}) #{tree}: #{_pry_.binding_stack.size - 1}> " + end, + proc do |_, _, _pry_| + tree = _pry_.binding_stack.map { |b| Pry.view_clip(b.eval("self")) }.join " / " + "[#{_pry_.input_array.count}] (#{ _pry_.config.prompt_name}) #{tree}: #{_pry_.binding_stack.size - 1}* " + end, + ] + + # Deal with the ^D key being pressed. Different behaviour in different cases: + # 1. In an expression behave like `!` command. + # 2. At top-level session behave like `exit` command. + # 3. In a nested session behave like `cd ..`. + DEFAULT_CONTROL_D_HANDLER = proc do |eval_string, _pry_| + if !eval_string.empty? + eval_string.replace('') # Clear input buffer. + elsif _pry_.binding_stack.one? + _pry_.binding_stack.clear + throw(:breakout) + else + # Otherwise, saves current binding stack as old stack and pops last + # binding out of binding stack (the old stack still has that binding). + _pry_.command_state["cd"] ||= Pry::Config.from_hash({}) # FIXME + _pry_.command_state['cd'].old_stack = _pry_.binding_stack.dup + _pry_.binding_stack.pop + end + end + + DEFAULT_SYSTEM = proc do |output, cmd, _| + if !system(cmd) + output.puts "Error: there was a problem executing system command: #{cmd}" + end + end + + # Store the current working directory. This allows show-source etc. to work if + # your process has changed directory since boot. [Issue #675] + INITIAL_PWD = Dir.pwd + + # This is to keep from breaking under Rails 3.2 for people who are doing that + # IRB = Pry thing. + module ExtendCommandBundle; end +end + +require 'method_source' +require 'shellwords' +require 'stringio' +require 'coderay' +require 'slop' +require 'rbconfig' +require 'tempfile' +require 'pathname' + +require 'pry/version' +require 'pry/repl' +require 'pry/rbx_path' +require 'pry/code' +require 'pry/history_array' +require 'pry/helpers' +require 'pry/code_object' +require 'pry/method' +require 'pry/wrapped_module' +require 'pry/history' +require 'pry/command' +require 'pry/command_set' +require 'pry/commands' +require 'pry/plugins' +require 'pry/core_extensions' +require 'pry/pry_class' +require 'pry/pry_instance' +require 'pry/cli' +require 'pry/color_printer' +require 'pry/pager' +require 'pry/terminal' +require 'pry/editor' +require 'pry/rubygem' +require "pry/indent" +require "pry/last_exception" +require "pry/prompt" +require "pry/inspector" +require 'pry/object_path' +require 'pry/output' diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/cli.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/cli.rb new file mode 100644 index 0000000..ef73869 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/cli.rb @@ -0,0 +1,220 @@ +class Pry + + # Manage the processing of command line options + class CLI + + NoOptionsError = Class.new(StandardError) + + class << self + + # @return [Proc] The Proc defining the valid command line options. + attr_accessor :options + + # @return [Array] The Procs that process the parsed options. Plugins can + # utilize this facility in order to add and process their own Pry + # options. + attr_accessor :option_processors + + # @return [Array] The input array of strings to process + # as CLI options. + attr_accessor :input_args + + # Add another set of CLI options (a Slop block) + def add_options(&block) + if options + old_options = options + self.options = proc do + instance_exec(&old_options) + instance_exec(&block) + end + else + self.options = block + end + + self + end + + # Bring in options defined in plugins + def add_plugin_options + Pry.plugins.values.each do |plugin| + plugin.load_cli_options + end + + self + end + + # Add a block responsible for processing parsed options. + def add_option_processor(&block) + self.option_processors ||= [] + option_processors << block + + self + end + + # Clear `options` and `option_processors` + def reset + self.options = nil + self.option_processors = nil + end + + def parse_options(args=ARGV) + unless options + raise NoOptionsError, "No command line options defined! Use Pry::CLI.add_options to add command line options." + end + + self.input_args = args + + begin + opts = Slop.parse!( + args, + :help => true, + :multiple_switches => false, + :strict => true, + &options + ) + rescue Slop::InvalidOptionError + # Display help message on unknown switches and exit. + puts Slop.new(&options) + exit + end + + # Option processors are optional. + if option_processors + option_processors.each { |processor| processor.call(opts) } + end + + self + end + + end + + reset + end +end + + +# String that is built to be executed on start (created by -e and -exec switches) +exec_string = "" + +# Bring in options defined by plugins +Slop.new do + on "no-plugins" do + Pry.config.should_load_plugins = false + end +end.parse(ARGV.dup) + +if Pry.config.should_load_plugins + Pry::CLI.add_plugin_options +end + +# The default Pry command line options (before plugin options are included) +Pry::CLI.add_options do + banner %{Usage: pry [OPTIONS] +Start a Pry session. +See http://pryrepl.org/ for more information. +Copyright (c) 2013 John Mair (banisterfiend) +-- +} + on :e, :exec=, "A line of code to execute in context before the session starts" do |input| + exec_string << input << "\n" + end + + on "no-pager", "Disable pager for long output" do + Pry.config.pager = false + end + + on "no-history", "Disable history loading" do + Pry.config.history.should_load = false + end + + on "no-color", "Disable syntax highlighting for session" do + Pry.config.color = false + end + + on :f, "Suppress loading of ~/.pryrc and ./.pryrc" do + Pry.config.should_load_rc = false + Pry.config.should_load_local_rc = false + end + + on :s, "select-plugin=", "Only load specified plugin (and no others)." do |plugin_name| + Pry.config.should_load_plugins = false + Pry.plugins[plugin_name].activate! + end + + on :d, "disable-plugin=", "Disable a specific plugin." do |plugin_name| + Pry.plugins[plugin_name].disable! + end + + on "no-plugins", "Suppress loading of plugins." do + Pry.config.should_load_plugins = false + end + + on "plugins", "List installed plugins." do + puts "Installed Plugins:" + puts "--" + Pry.locate_plugins.each do |plugin| + puts "#{plugin.name}".ljust(18) << plugin.spec.summary + end + exit + end + + on "simple-prompt", "Enable simple prompt mode" do + Pry.config.prompt = Pry::SIMPLE_PROMPT + end + + on "noprompt", "No prompt mode" do + Pry.config.prompt = Pry::NO_PROMPT + end + + on :r, :require=, "`require` a Ruby script at startup" do |file| + Pry.config.requires << file + end + + on :I=, "Add a path to the $LOAD_PATH", :as => Array, :delimiter => ":" do |load_path| + load_path.map! do |path| + /\A\.\// =~ path ? path : File.expand_path(path) + end + + $LOAD_PATH.unshift(*load_path) + end + + on "gem", "Shorthand for -I./lib -rgemname" do |load_path| + $LOAD_PATH.unshift("./lib") + Dir["./lib/*.rb"].each do |file| + Pry.config.requires << file + end + end + + on :v, :version, "Display the Pry version" do + puts "Pry version #{Pry::VERSION} on Ruby #{RUBY_VERSION}" + exit + end + + on(:c, :context=, + "Start the session in the specified context. Equivalent to `context.pry` in a session.", + :default => "Pry.toplevel_binding" + ) +end.add_option_processor do |opts| + + exit if opts.help? + + # invoked via cli + Pry.cli = true + + # create the actual context + if opts[:context] + Pry.initial_session_setup + context = Pry.binding_for(eval(opts[:context])) + else + context = Pry.toplevel_binding + end + + if Pry::CLI.input_args.any? && Pry::CLI.input_args != ["pry"] + full_name = File.expand_path(Pry::CLI.input_args.first) + Pry.load_file_through_repl(full_name) + exit + end + + # Start the session (running any code passed with -e, if there is any) + Pry.start(context, :input => StringIO.new(exec_string)) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/code.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/code.rb new file mode 100644 index 0000000..b99f976 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/code.rb @@ -0,0 +1,341 @@ +require 'pry/code/loc' +require 'pry/code/code_range' +require 'pry/code/code_file' + +class Pry + class << self + # Convert the given object into an instance of `Pry::Code`, if it isn't + # already one. + # + # @param [Code, Method, UnboundMethod, Proc, Pry::Method, String, Array, + # IO] obj + def Code(obj) + case obj + when Code + obj + when ::Method, UnboundMethod, Proc, Pry::Method + Code.from_method(obj) + else + Code.new(obj) + end + end + end + + # `Pry::Code` is a class that encapsulates lines of source code and their + # line numbers and formats them for terminal output. It can read from a file + # or method definition or be instantiated with a `String` or an `Array`. + # + # In general, the formatting methods in `Code` return a new `Code` object + # which will format the text as specified when `#to_s` is called. This allows + # arbitrary chaining of formatting methods without mutating the original + # object. + class Code + class << self + include MethodSource::CodeHelpers + + # Instantiate a `Code` object containing code loaded from a file or + # Pry's line buffer. + # + # @param [String] filename The name of a file, or "(pry)". + # @param [Symbol] code_type The type of code the file contains. + # @return [Code] + def from_file(filename, code_type = nil) + code_file = CodeFile.new(filename, code_type) + new(code_file.code, 1, code_file.code_type) + end + + # Instantiate a `Code` object containing code extracted from a + # `::Method`, `UnboundMethod`, `Proc`, or `Pry::Method` object. + # + # @param [::Method, UnboundMethod, Proc, Pry::Method] meth The method + # object. + # @param [Integer, nil] start_line The line number to start on, or nil to + # use the method's original line numbers. + # @return [Code] + def from_method(meth, start_line = nil) + meth = Pry::Method(meth) + start_line ||= meth.source_line || 1 + new(meth.source, start_line, meth.source_type) + end + + # Attempt to extract the source code for module (or class) `mod`. + # + # @param [Module, Class] mod The module (or class) of interest. + # @param [Integer] candidate_rank The module candidate (by rank) + # to use (see `Pry::WrappedModule::Candidate` for more information). + # @param [Integer, nil] start_line The line number to start on, or nil to + # use the method's original line numbers. + # @return [Code] + def from_module(mod, candidate_rank = 0, start_line=nil) + candidate = Pry::WrappedModule(mod).candidate(candidate_rank) + start_line ||= candidate.line + new(candidate.source, start_line, :ruby) + end + end + + # @return [Symbol] The type of code stored in this wrapper. + attr_accessor :code_type + + # Instantiate a `Code` object containing code from the given `Array`, + # `String`, or `IO`. The first line will be line 1 unless specified + # otherwise. If you need non-contiguous line numbers, you can create an + # empty `Code` object and then use `#push` to insert the lines. + # + # @param [Array, String, IO] lines + # @param [Integer?] start_line + # @param [Symbol?] code_type + def initialize(lines = [], start_line = 1, code_type = :ruby) + if lines.is_a? String + lines = lines.lines + end + @lines = lines.each_with_index.map { |line, lineno| + LOC.new(line, lineno + start_line.to_i) } + @code_type = code_type + end + + # Append the given line. +lineno+ is one more than the last existing + # line, unless specified otherwise. + # + # @param [String] line + # @param [Integer?] lineno + # @return [String] The inserted line. + def push(line, lineno = nil) + if lineno.nil? + lineno = @lines.last.lineno + 1 + end + @lines.push(LOC.new(line, lineno)) + line + end + alias << push + + # Filter the lines using the given block. + # + # @yield [LOC] + # @return [Code] + def select(&block) + alter do + @lines = @lines.select(&block) + end + end + + # Remove all lines that aren't in the given range, expressed either as a + # `Range` object or a first and last line number (inclusive). Negative + # indices count from the end of the array of lines. + # + # @param [Range, Integer] start_line + # @param [Integer?] end_line + # @return [Code] + def between(start_line, end_line = nil) + return self unless start_line + + code_range = CodeRange.new(start_line, end_line) + + alter do + @lines = @lines[code_range.indices_range(@lines)] || [] + end + end + + # Take `num_lines` from `start_line`, forward or backwards. + # + # @param [Integer] start_line + # @param [Integer] num_lines + # @return [Code] + def take_lines(start_line, num_lines) + start_idx = + if start_line >= 0 + @lines.index { |loc| loc.lineno >= start_line } || @lines.length + else + [@lines.length + start_line, 0].max + end + + alter do + @lines = @lines.slice(start_idx, num_lines) + end + end + + # Remove all lines except for the +lines+ up to and excluding +lineno+. + # + # @param [Integer] lineno + # @param [Integer] lines + # @return [Code] + def before(lineno, lines = 1) + return self unless lineno + + select do |loc| + loc.lineno >= lineno - lines && loc.lineno < lineno + end + end + + # Remove all lines except for the +lines+ on either side of and including + # +lineno+. + # + # @param [Integer] lineno + # @param [Integer] lines + # @return [Code] + def around(lineno, lines = 1) + return self unless lineno + + select do |loc| + loc.lineno >= lineno - lines && loc.lineno <= lineno + lines + end + end + + # Remove all lines except for the +lines+ after and excluding +lineno+. + # + # @param [Integer] lineno + # @param [Integer] lines + # @return [Code] + def after(lineno, lines = 1) + return self unless lineno + + select do |loc| + loc.lineno > lineno && loc.lineno <= lineno + lines + end + end + + # Remove all lines that don't match the given `pattern`. + # + # @param [Regexp] pattern + # @return [Code] + def grep(pattern) + return self unless pattern + pattern = Regexp.new(pattern) + + select do |loc| + loc.line =~ pattern + end + end + + # Format output with line numbers next to it, unless `y_n` is falsy. + # + # @param [Boolean?] y_n + # @return [Code] + def with_line_numbers(y_n = true) + alter do + @with_line_numbers = y_n + end + end + + # Format output with a marker next to the given +lineno+, unless +lineno+ is + # falsy. + # + # @param [Integer?] lineno + # @return [Code] + def with_marker(lineno = 1) + alter do + @with_marker = !!lineno + @marker_lineno = lineno + end + end + + # Format output with the specified number of spaces in front of every line, + # unless `spaces` is falsy. + # + # @param [Integer?] spaces + # @return [Code] + def with_indentation(spaces = 0) + alter do + @with_indentation = !!spaces + @indentation_num = spaces + end + end + + # @return [String] + def inspect + Object.instance_method(:to_s).bind(self).call + end + + # @return [Integer] the number of digits in the last line. + def max_lineno_width + @lines.length > 0 ? @lines.last.lineno.to_s.length : 0 + end + + # @return [String] a formatted representation (based on the configuration of + # the object). + def to_s + print_to_output("") + end + + # Writes a formatted representation (based on the configuration of the + # object) to the given output, which must respond to `#<<`. + def print_to_output(output, color=false) + @lines.each do |loc| + loc = loc.dup + loc.colorize(@code_type) + loc.add_line_number(max_lineno_width, color) if @with_line_numbers + loc.add_marker(@marker_lineno) if @with_marker + loc.indent(@indentation_num) if @with_indentation + output << loc.line + output << "\n" + end + output + end + + # Get the comment that describes the expression on the given line number. + # + # @param [Integer] line_number (1-based) + # @return [String] the code. + def comment_describing(line_number) + self.class.comment_describing(raw, line_number) + end + + # Get the multiline expression that starts on the given line number. + # + # @param [Integer] line_number (1-based) + # @return [String] the code. + def expression_at(line_number, consume = 0) + self.class.expression_at(raw, line_number, :consume => consume) + end + + # Get the (approximate) Module.nesting at the give line number. + # + # @param [Integer] line_number line number starting from 1 + # @param [Module] top_module the module in which this code exists + # @return [Array] a list of open modules. + def nesting_at(line_number, top_module = Object) + Pry::Indent.nesting_at(raw, line_number) + end + + # Return an unformatted String of the code. + # + # @return [String] + def raw + @lines.map(&:line).join("\n") << "\n" + end + + # Return the number of lines stored. + # + # @return [Integer] + def length + @lines ? @lines.length : 0 + end + + # Two `Code` objects are equal if they contain the same lines with the same + # numbers. Otherwise, call `to_s` and `chomp` and compare as Strings. + # + # @param [Code, Object] other + # @return [Boolean] + def ==(other) + if other.is_a?(Code) + other_lines = other.instance_variable_get(:@lines) + @lines.each_with_index.all? { |loc, i| loc == other_lines[i] } + else + to_s.chomp == other.to_s.chomp + end + end + + # Forward any missing methods to the output of `#to_s`. + def method_missing(name, *args, &block) + to_s.send(name, *args, &block) + end + undef =~ + + protected + + # An abstraction of the `dup.instance_eval` pattern used throughout this + # class. + def alter(&block) + dup.tap { |o| o.instance_eval(&block) } + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_file.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_file.rb new file mode 100644 index 0000000..9ccb23b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_file.rb @@ -0,0 +1,103 @@ +class Pry + class CodeFile + DEFAULT_EXT = '.rb' + + # List of all supported languages. + # @return [Hash] + EXTENSIONS = { + %w(.py) => :python, + %w(.js) => :javascript, + %w(.css) => :css, + %w(.xml) => :xml, + %w(.php) => :php, + %w(.html) => :html, + %w(.diff) => :diff, + %w(.java) => :java, + %w(.json) => :json, + %w(.c .h) => :c, + %w(.rhtml) => :rhtml, + %w(.yaml .yml) => :yaml, + %w(.cpp .hpp .cc .h cxx) => :cpp, + %w(.rb .ru .irbrc .gemspec .pryrc) => :ruby, + } + + # @return [Symbol] The type of code stored in this wrapper. + attr_reader :code_type + + # @param [String] filename The name of a file with code to be detected + # @param [Symbol] code_type The type of code the `filename` contains + def initialize(filename, code_type = type_from_filename(filename)) + @filename = filename + @code_type = code_type + end + + # @return [String] The code contained in the current `@filename`. + def code + if @filename == Pry.eval_path + Pry.line_buffer.drop(1) + elsif Pry::Method::Patcher.code_for(@filename) + Pry::Method::Patcher.code_for(@filename) + elsif RbxPath.is_core_path?(@filename) + File.read(RbxPath.convert_path_to_full(@filename)) + else + path = abs_path + @code_type = type_from_filename(path) + File.read(path) + end + end + + private + + # @raise [MethodSource::SourceNotFoundError] if the `filename` is not + # readable for some reason. + # @return [String] absolute path for the given `filename`. + def abs_path + code_path.detect { |path| readable?(path) } or + raise MethodSource::SourceNotFoundError, + "Cannot open #{ @filename.inspect } for reading." + end + + # @param [String] path + # @return [Boolean] if the path, with or without the default ext, + # is a readable file then `true`, otherwise `false`. + def readable?(path) + File.readable?(path) && !File.directory?(path) or + File.readable?(path << DEFAULT_EXT) + end + + # @return [Array] All the paths that contain code that Pry can use for its + # API's. Skips directories. + def code_path + [from_pwd, from_pry_init_pwd, *from_load_path] + end + + # @param [String] filename + # @param [Symbol] default (:unknown) the file type to assume if none could be + # detected. + # @return [Symbol, nil] The CodeRay type of a file from its extension, or + # `nil` if `:unknown`. + def type_from_filename(filename, default = :unknown) + _, @code_type = EXTENSIONS.find do |k, _| + k.any? { |ext| ext == File.extname(filename) } + end + + code_type || default + end + + # @return [String] + def from_pwd + File.expand_path(@filename, Dir.pwd) + end + + # @return [String] + def from_pry_init_pwd + File.expand_path(@filename, Pry::INITIAL_PWD) + end + + # @return [String] + def from_load_path + $LOAD_PATH.map { |path| File.expand_path(@filename, path) } + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_range.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_range.rb new file mode 100644 index 0000000..043be02 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/code_range.rb @@ -0,0 +1,71 @@ +class Pry + class Code + + # Represents a range of lines in a code listing. + # + # @api private + class CodeRange + + # @param [Integer] start_line + # @param [Integer?] end_line + def initialize(start_line, end_line = nil) + @start_line = start_line + @end_line = end_line + force_set_end_line + end + + # @param [Array] lines + # @return [Range] + def indices_range(lines) + Range.new(*indices(lines)) + end + + private + + def start_line; @start_line; end + def end_line; @end_line; end + + # If `end_line` is equal to `nil`, then calculate it from the first + # parameter, `start_line`. Otherwise, leave it as it is. + # @return [void] + def force_set_end_line + if start_line.is_a?(Range) + set_end_line_from_range + else + @end_line ||= start_line + end + end + + # Finds indices of `start_line` and `end_line` in the given Array of + # +lines+. + # + # @param [Array] lines + # @return [Array] + def indices(lines) + [find_start_index(lines), find_end_index(lines)] + end + + # @return [Integer] + def find_start_index(lines) + return start_line if start_line < 0 + lines.index { |loc| loc.lineno >= start_line } || lines.length + end + + # @return [Integer] + def find_end_index(lines) + return end_line if end_line < 0 + (lines.index { |loc| loc.lineno > end_line } || 0) - 1 + end + + # For example, if the range is 4..10, then `start_line` would be equal to + # 4 and `end_line` to 10. + # @return [void] + def set_end_line_from_range + @end_line = start_line.last + @end_line -= 1 if start_line.exclude_end? + @start_line = start_line.first + end + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/code/loc.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/loc.rb new file mode 100644 index 0000000..905c704 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/code/loc.rb @@ -0,0 +1,92 @@ +class Pry + class Code + + # Represents a line of code. A line of code is a tuple, which consists of a + # line and a line number. A `LOC` object's state (namely, the line + # parameter) can be changed via instance methods. `Pry::Code` heavily uses + # this class. + # + # @api private + # @example + # loc = LOC.new("def example\n :example\nend", 1) + # puts loc.line + # def example + # :example + # end + # #=> nil + # + # loc.indent(3) + # loc.line #=> " def example\n :example\nend" + class LOC + + # @return [Array] + attr_reader :tuple + + # @param [String] line The line of code. + # @param [Integer] lineno The position of the +line+. + def initialize(line, lineno) + @tuple = [line.chomp, lineno.to_i] + end + + # @return [Boolean] + def ==(other) + other.tuple == tuple + end + + def dup + self.class.new(line, lineno) + end + + # @return [String] + def line + tuple.first + end + + # @return [Integer] + def lineno + tuple.last + end + + # Paints the `line` of code. + # + # @param [Symbol] code_type + # @return [void] + def colorize(code_type) + tuple[0] = CodeRay.scan(line, code_type).term + end + + # Prepends the line number `lineno` to the `line`. + # + # @param [Integer] max_width + # @return [void] + def add_line_number(max_width = 0, color = false) + padded = lineno.to_s.rjust(max_width) + colorized_lineno = color ? Pry::Helpers::BaseHelpers.colorize_code(padded) : padded + tuple[0] = "#{ colorized_lineno }: #{ line }" + end + + # Prepends a marker "=>" or an empty marker to the +line+. + # + # @param [Integer] marker_lineno If it is equal to the `lineno`, then + # prepend a hashrocket. Otherwise, an empty marker. + # @return [void] + def add_marker(marker_lineno) + tuple[0] = + if lineno == marker_lineno + " => #{ line }" + else + " #{ line }" + end + end + + # Indents the `line` with +distance+ spaces. + # + # @param [Integer] distance + # @return [void] + def indent(distance) + tuple[0] = "#{ ' ' * distance }#{ line }" + end + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/code_object.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/code_object.rb new file mode 100644 index 0000000..11a3aa6 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/code_object.rb @@ -0,0 +1,172 @@ +class Pry + + # This class is responsible for taking a string (identifying a + # command/class/method/etc) and returning the relevant type of object. + # For example, if the user looks up "show-source" then a + # `Pry::Command` will be returned. Alternatively, if the user passes in "Pry#repl" then + # a `Pry::Method` object will be returned. + # + # The `CodeObject.lookup` method is responsible for 1. figuring out what kind of + # object the user wants (applying precedence rules in doing so -- i.e methods + # get precedence over commands with the same name) and 2. Returning + # the appropriate object. If the user fails to provide a string + # identifer for the object (i.e they pass in `nil` or "") then the + # object looked up will be the 'current method' or 'current class' + # associated with the Binding. + # + # TODO: This class is a clusterfuck. We need a much more robust + # concept of what a "Code Object" really is. Currently + # commands/classes/candidates/methods and so on just share a very + # ill-defined interface. + class CodeObject + module Helpers + # we need this helper as some Pry::Method objects can wrap Procs + # @return [Boolean] + def real_method_object? + is_a?(::Method) || is_a?(::UnboundMethod) + end + + def c_method? + real_method_object? && source_type == :c + end + + def module_with_yard_docs? + is_a?(WrappedModule) && yard_docs? + end + + def command? + is_a?(Module) && self <= Pry::Command + end + end + + include Pry::Helpers::CommandHelpers + + class << self + def lookup(str, _pry_, options={}) + co = new(str, _pry_, options) + + co.default_lookup || co.method_or_class_lookup || + co.command_lookup || co.empty_lookup + end + end + + attr_accessor :str + attr_accessor :target + attr_accessor :_pry_ + attr_accessor :super_level + + def initialize(str, _pry_, options={}) + options = { + :super => 0, + }.merge!(options) + + @str = str + @_pry_ = _pry_ + @target = _pry_.current_context + @super_level = options[:super] + end + + def command_lookup + # TODO: just make it so find_command_by_match_or_listing doesn't + # raise? + _pry_.commands.find_command_by_match_or_listing(str) rescue nil + end + + # when no paramter is given (i.e CodeObject.lookup(nil)), then we + # lookup the 'current object' from the binding. + def empty_lookup + return nil if str && !str.empty? + + obj = if internal_binding?(target) + mod = target_self.is_a?(Module) ? target_self : target_self.class + Pry::WrappedModule(mod) + else + Pry::Method.from_binding(target) + end + + # respect the super level (i.e user might have specified a + # --super flag to show-source) + lookup_super(obj, super_level) + end + + # lookup variables and constants and `self` that are not modules + def default_lookup + + # we skip instance methods as we want those to fall through to method_or_class_lookup() + if safe_to_evaluate?(str) && !looks_like_an_instance_method?(str) + obj = target.eval(str) + + # restrict to only objects we KNOW for sure support the full API + # Do NOT support just any object that responds to source_location + if sourcable_object?(obj) + Pry::Method(obj) + elsif !obj.is_a?(Module) + Pry::WrappedModule(obj.class) + else + nil + end + end + + rescue Pry::RescuableException + nil + end + + def method_or_class_lookup + obj = case str + when /\S+\(\)\z/ + Pry::Method.from_str(str.sub(/\(\)\z/, ''),target) || Pry::WrappedModule.from_str(str, target) + else + Pry::WrappedModule.from_str(str,target) || Pry::Method.from_str(str, target) + end + + lookup_super(obj, super_level) + end + + private + + def sourcable_object?(obj) + [::Proc, ::Method, ::UnboundMethod].any? { |o| obj.is_a?(o) } + end + + # Returns true if `str` looks like a method, i.e Klass#method + # We need to consider this case because method lookups should fall + # through to the `method_or_class_lookup()` method but a + # defined?() on a "Klass#method` string will see the `#` as a + # comment and only evaluate the `Klass` part. + # @param [String] str + # @return [Boolean] Whether the string looks like an instance method. + def looks_like_an_instance_method?(str) + str =~ /\S#\S/ + end + + # We use this method to decide whether code is safe to eval. Method's are + # generally not, but everything else is. + # TODO: is just checking != "method" enough?? + # TODO: see duplication of this method in Pry::WrappedModule + # @param [String] str The string to lookup + # @return [Boolean] + def safe_to_evaluate?(str) + return true if str.strip == "self" + kind = target.eval("defined?(#{str})") + kind =~ /variable|constant/ + end + + def target_self + target.eval('self') + end + + # grab the nth (`super_level`) super of `obj + # @param [Object] obj + # @param [Fixnum] super_level How far up the super chain to ascend. + def lookup_super(obj, super_level) + return nil if !obj + + sup = obj.super(super_level) + if !sup + raise Pry::CommandError, "No superclass found for #{obj.wrapped}" + else + sup + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/color_printer.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/color_printer.rb new file mode 100644 index 0000000..218a821 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/color_printer.rb @@ -0,0 +1,55 @@ +# PP subclass for streaming inspect output in color. +class Pry + class ColorPrinter < ::PP + OBJ_COLOR = begin + code = CodeRay::Encoders::Terminal::TOKEN_COLORS[:keyword] + if code.start_with? "\e" + code + else + "\e[0m\e[0;#{code}m" + end + end + + CodeRay::Encoders::Terminal::TOKEN_COLORS[:comment][:self] = "\e[1;34m" + + def self.pp(obj, out = $>, width = 79) + q = ColorPrinter.new(out, width) + q.guard_inspect_key { q.pp obj } + q.flush + out << "\n" + end + + def text(str, width = str.length) + # Don't recolorize output with color [Issue #751] + if str.include?("\e[") + super "#{str}\e[0m", width + elsif str.start_with?('#<') || str == '=' || str == '>' + super highlight_object_literal(str), width + else + super CodeRay.scan(str, :ruby).term, width + end + end + + def pp(obj) + super + rescue => e + raise if e.is_a? Pry::Pager::StopPaging + + # Read the class name off of the singleton class to provide a default + # inspect. + singleton = class << obj; self; end + ancestors = Pry::Method.safe_send(singleton, :ancestors) + klass = ancestors.reject { |k| k == singleton }.first + obj_id = obj.__id__.to_s(16) rescue 0 + str = "#<#{klass}:0x#{obj_id}>" + + text highlight_object_literal(str) + end + + private + + def highlight_object_literal(object_literal) + "#{OBJ_COLOR}#{object_literal}\e[0m" + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/command.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/command.rb new file mode 100644 index 0000000..0cf334f --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/command.rb @@ -0,0 +1,692 @@ +require 'delegate' +require 'pry/helpers/documentation_helpers' + +class Pry + + # The super-class of all commands, new commands should be created by calling + # {Pry::CommandSet#command} which creates a BlockCommand or {Pry::CommandSet#create_command} + # which creates a ClassCommand. Please don't use this class directly. + class Command + extend Helpers::DocumentationHelpers + extend CodeObject::Helpers + + # represents a void return value for a command + VOID_VALUE = Object.new + + # give it a nice inspect + def VOID_VALUE.inspect() "void" end + + # Properties of the command itself (as passed as arguments to + # {CommandSet#command} or {CommandSet#create_command}). + class << self + attr_writer :block + attr_writer :description + attr_writer :command_options + attr_writer :match + + def match(arg=nil) + if arg + @command_options ||= default_options(arg) + @command_options[:listing] = arg.is_a?(String) ? arg : arg.inspect + @match = arg + end + @match ||= nil + end + + # Define or get the command's description + def description(arg=nil) + @description = arg if arg + @description ||= nil + end + + # Define or get the command's options + def command_options(arg=nil) + @command_options ||= default_options(match) + @command_options.merge!(arg) if arg + @command_options + end + # backward compatibility + alias_method :options, :command_options + alias_method :options=, :command_options= + + # Define or get the command's banner + def banner(arg=nil) + @banner = arg if arg + @banner || description + end + + def block + @block || instance_method(:process) + end + + def source + file, line = block.source_location + strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line)) + end + + def doc + new.help + end + + def source_location + block.source_location + end + + def source_file + Array(block.source_location).first + end + alias_method :file, :source_file + + def source_line + Array(block.source_location).last + end + alias_method :line, :source_line + + def default_options(match) + { + :requires_gem => [], + :keep_retval => false, + :argument_required => false, + :interpolate => true, + :shellwords => true, + :listing => (String === match ? match : match.inspect), + :use_prefix => true, + :takes_block => false + } + end + end + + # Make those properties accessible to instances + def name; self.class.name; end + def match; self.class.match; end + def description; self.class.description; end + def block; self.class.block; end + def command_options; self.class.options; end + def command_name; self.class.command_name; end + def source; self.class.source; end + def source_location; self.class.source_location; end + + class << self + def name + super.to_s == "" ? "#" : super + end + + def inspect + name + end + + def command_name + self.options[:listing] + end + + # Create a new command with the given properties. + # @param [String, Regex] match The thing that triggers this command + # @param [String] description The description to appear in `help` + # @param [Hash] options Behavioral options (see {Pry::CommandSet#command}) + # @param [Module] helpers A module of helper functions to be included. + # @yield optional, used for BlockCommands + # @return [Class] (a subclass of {Pry::Command}) + def subclass(match, description, options, helpers, &block) + klass = Class.new(self) + klass.send(:include, helpers) + klass.match = match + klass.description = description + klass.command_options = options + klass.block = block + klass + end + + # Should this command be called for the given line? + # @param [String] val A line input at the REPL + # @return [Boolean] + def matches?(val) + command_regex =~ val + end + + # How well does this command match the given line? + # + # Higher scores are better because they imply that this command matches + # the line more closely. + # + # The score is calculated by taking the number of characters at the start + # of the string that are used only to identify the command, not as part of + # the arguments. + # + # @example + # /\.(.*)/.match_score(".foo") #=> 1 + # /\.*(.*)/.match_score("...foo") #=> 3 + # 'hi'.match_score("hi there") #=> 2 + # + # @param [String] val A line input at the REPL + # @return [Fixnum] + def match_score(val) + if command_regex =~ val + Regexp.last_match.size > 1 ? Regexp.last_match.begin(1) : Regexp.last_match.end(0) + else + -1 + end + end + + # Store hooks to be run before or after the command body. + # @see {Pry::CommandSet#before_command} + # @see {Pry::CommandSet#after_command} + def hooks + @hooks ||= {:before => [], :after => []} + end + + def command_regex + pr = Pry.respond_to?(:config) ? Pry.config.command_prefix : "" + prefix = convert_to_regex(pr) + prefix = "(?:#{prefix})?" unless options[:use_prefix] + + /^#{prefix}#{convert_to_regex(match)}(?!\S)/ + end + + def convert_to_regex(obj) + case obj + when String + Regexp.escape(obj) + else + obj + end + end + + # The group in which the command should be displayed in "help" output. + # This is usually auto-generated from directory naming, but it can be + # manually overridden if necessary. + # Group should not be changed once it is initialized. + def group(name=nil) + @group ||= if name + name + else + case Pry::Method(block).source_file + when %r{/pry/.*_commands/(.*).rb} + $1.capitalize.gsub(/_/, " ") + when %r{(pry-\w+)-([\d\.]+([\w\.]+)?)} + name, version = $1, $2 + "#{name.to_s} (v#{version.to_s})" + when /pryrc/ + "~/.pryrc" + else + "(other)" + end + end + end + end + + # Properties of one execution of a command (passed by {Pry#run_command} as a hash of + # context and expanded in `#initialize` + attr_accessor :output + attr_accessor :target + attr_accessor :captures + attr_accessor :eval_string + attr_accessor :arg_string + attr_accessor :context + attr_accessor :command_set + attr_accessor :_pry_ + + # The block we pass *into* a command so long as `:takes_block` is + # not equal to `false` + # @example + # my-command | do + # puts "block content" + # end + attr_accessor :command_block + + # Run a command from another command. + # @param [String] command_string The string that invokes the command + # @param [Array] args Further arguments to pass to the command + # @example + # run "show-input" + # @example + # run ".ls" + # @example + # run "amend-line", "5", 'puts "hello world"' + def run(command_string, *args) + command_string = _pry_.config.command_prefix.to_s + command_string + complete_string = "#{command_string} #{args.join(" ")}".rstrip + command_set.process_line(complete_string, context) + end + + def commands + command_set.to_hash + end + + def text + Pry::Helpers::Text + end + + def void + VOID_VALUE + end + + include Pry::Helpers::BaseHelpers + include Pry::Helpers::CommandHelpers + + # Instantiate a command, in preparation for calling it. + # @param [Hash] context The runtime context to use with this command. + def initialize(context={}) + self.context = context + self.target = context[:target] + self.output = context[:output] + self.eval_string = context[:eval_string] + self.command_set = context[:command_set] + self._pry_ = context[:pry_instance] + end + + # @return [Object] The value of `self` inside the `target` binding. + def target_self; target.eval('self'); end + + # @return [Hash] Pry commands can store arbitrary state + # here. This state persists between subsequent command invocations. + # All state saved here is unique to the command, it does not + # need to be namespaced. + # @example + # state.my_state = "my state" # this will not conflict with any + # # `state.my_state` used in another command. + def state + _pry_.command_state[match] ||= Pry::Config.from_hash({}) + end + + # Revaluate the string (str) and perform interpolation. + # @param [String] str The string to reevaluate with interpolation. + # + # @return [String] The reevaluated string with interpolations + # applied (if any). + def interpolate_string(str) + dumped_str = str.dump + if dumped_str.gsub!(/\\\#\{/, '#{') + target.eval(dumped_str) + else + str + end + end + + # Display a warning if a command collides with a local/method in + # the current scope. + def check_for_command_collision(command_match, arg_string) + collision_type = target.eval("defined?(#{command_match})") + collision_type ||= 'local-variable' if arg_string.match(%r{\A\s*[-+*/%&|^]*=}) + + if collision_type + output.puts "#{text.bold('WARNING:')} Calling Pry command '#{command_match}', which conflicts with a #{collision_type}.\n\n" + end + rescue Pry::RescuableException + end + + # Extract necessary information from a line that Command.matches? this + # command. + # + # Returns an array of four elements: + # + # ``` + # [String] the portion of the line that matched with the Command match + # [String] a string of all the arguments (i.e. everything but the match) + # [Array] the captures caught by the command_regex + # [Array] the arguments obtained by splitting the arg_string + # ``` + # + # @param [String] val The line of input + # @return [Array] + def tokenize(val) + val.replace(interpolate_string(val)) if command_options[:interpolate] + + self.class.command_regex =~ val + + # please call Command.matches? before Command#call_safely + raise CommandError, "fatal: called a command which didn't match?!" unless Regexp.last_match + captures = Regexp.last_match.captures + pos = Regexp.last_match.end(0) + + arg_string = val[pos..-1] + + # remove the one leading space if it exists + arg_string.slice!(0) if arg_string.start_with?(" ") + + # process and pass a block if one is found + pass_block(arg_string) if command_options[:takes_block] + + if arg_string + args = command_options[:shellwords] ? Shellwords.shellwords(arg_string) : arg_string.split(" ") + else + args = [] + end + + [val[0..pos].rstrip, arg_string, captures, args] + end + + # Process a line that Command.matches? this command. + # @param [String] line The line to process + # @return [Object, Command::VOID_VALUE] + def process_line(line) + command_match, arg_string, captures, args = tokenize(line) + + check_for_command_collision(command_match, arg_string) if Pry.config.collision_warning + + self.arg_string = arg_string + self.captures = captures + + call_safely(*(captures + args)) + end + + # Pass a block argument to a command. + # @param [String] arg_string The arguments (as a string) passed to the command. + # We inspect these for a '| do' or a '| {' and if we find it we use it + # to start a block input sequence. Once we have a complete + # block, we save it to an accessor that can be retrieved from the command context. + # Note that if we find the '| do' or '| {' we delete this and the + # elements following it from `arg_string`. + def pass_block(arg_string) + # Workaround for weird JRuby bug where rindex in this case can return nil + # even when there's a match. + arg_string.scan(/\| *(?:do|\{)/) + block_index = $~ && $~.offset(0)[0] + + return if !block_index + + block_init_string = arg_string.slice!(block_index..-1)[1..-1] + prime_string = "proc #{block_init_string}\n" + + if !Pry::Code.complete_expression?(prime_string) + block_string = _pry_.r(target, prime_string) + else + block_string = prime_string + end + + begin + self.command_block = target.eval(block_string) + rescue Pry::RescuableException + raise CommandError, "Incomplete block definition." + end + end + + private :pass_block + + # Run the command with the given `args`. + # + # This is a public wrapper around `#call` which ensures all preconditions + # are met. + # + # @param [Array] args The arguments to pass to this command. + # @return [Object] The return value of the `#call` method, or + # {Command::VOID_VALUE}. + def call_safely(*args) + unless dependencies_met? + gems_needed = Array(command_options[:requires_gem]) + gems_not_installed = gems_needed.select { |g| !Rubygem.installed?(g) } + output.puts "\nThe command '#{command_name}' is #{text.bold("unavailable")} because it requires the following gems to be installed: #{(gems_not_installed.join(", "))}" + output.puts "-" + output.puts "Type `install-command #{command_name}` to install the required gems and activate this command." + return void + end + + if command_options[:argument_required] && args.empty? + raise CommandError, "The command '#{command_name}' requires an argument." + end + + ret = call_with_hooks(*args) + command_options[:keep_retval] ? ret : void + end + + # Are all the gems required to use this command installed? + # + # @return Boolean + def dependencies_met? + @dependencies_met ||= command_dependencies_met?(command_options) + end + + # Generate completions for this command + # + # @param [String] search The line typed so far + # @return [Array] Completion words + def complete(search) + [] + end + + private + + # Run the `#call` method and all the registered hooks. + # @param [Array] args The arguments to `#call` + # @return [Object] The return value from `#call` + def call_with_hooks(*args) + self.class.hooks[:before].each do |block| + instance_exec(*args, &block) + end + + ret = call(*args) + + self.class.hooks[:after].each do |block| + ret = instance_exec(*args, &block) + end + + ret + end + + # Fix the number of arguments we pass to a block to avoid arity warnings. + # @param [Fixnum] arity The arity of the block + # @param [Array] args The arguments to pass + # @return [Array] A (possibly shorter) array of the arguments to pass + def correct_arg_arity(arity, args) + case + when arity < 0 + args + when arity == 0 + [] + when arity > 0 + args.values_at(*(0..(arity - 1)).to_a) + end + end + end + + # A super-class for Commands that are created with a single block. + # + # This class ensures that the block is called with the correct number of arguments + # and the right context. + # + # Create subclasses using {Pry::CommandSet#command}. + class BlockCommand < Command + # backwards compatibility + alias_method :opts, :context + + # Call the block that was registered with this command. + # @param [Array] args The arguments passed + # @return [Object] The return value of the block + def call(*args) + instance_exec(*correct_arg_arity(block.arity, args), &block) + end + + def help + "#{command_options[:listing].to_s.ljust(18)} #{description}" + end + end + + # A super-class of Commands with structure. + # + # This class implements the bare-minimum functionality that a command should + # have, namely a --help switch, and then delegates actual processing to its + # subclasses. + # + # Create subclasses using {Pry::CommandSet#create_command}, and override the + # `options(opt)` method to set up an instance of Slop, and the `process` + # method to actually run the command. If necessary, you can also override + # `setup` which will be called before `options`, for example to require any + # gems your command needs to run, or to set up state. + class ClassCommand < Command + class << self + + # Ensure that subclasses inherit the options, description and + # match from a ClassCommand super class. + def inherited(klass) + klass.match match + klass.description description + klass.command_options options + end + + def source + source_object.source + end + + def doc + new.help + end + + def source_location + source_object.source_location + end + + def source_file + source_object.source_file + end + alias_method :file, :source_file + + def source_line + source_object.source_line + end + alias_method :line, :source_line + + private + + # The object used to extract the source for the command. + # + # This should be a `Pry::Method(block)` for a command made with `create_command` + # and a `Pry::WrappedModule(self)` for a command that's a standard class. + # @return [Pry::WrappedModule, Pry::Method] + def source_object + @source_object ||= if name =~ /^[A-Z]/ + Pry::WrappedModule(self) + else + Pry::Method(block) + end + end + end + + attr_accessor :opts + attr_accessor :args + + # Set up `opts` and `args`, and then call `process`. + # + # This method will display help if necessary. + # + # @param [Array] args The arguments passed + # @return [Object] The return value of `process` or VOID_VALUE + def call(*args) + setup + + self.opts = slop + self.args = self.opts.parse!(args) + + if opts.present?(:help) + output.puts slop.help + void + else + process(*correct_arg_arity(method(:process).arity, args)) + end + end + + # Return the help generated by Slop for this command. + def help + slop.help + end + + # Return an instance of Slop that can parse either subcommands or the + # options that this command accepts. + def slop + Slop.new do |opt| + opt.banner(unindent(self.class.banner)) + subcommands(opt) + options(opt) + opt.on :h, :help, 'Show this message.' + end + end + + # Generate shell completions + # @param [String] search The line typed so far + # @return [Array] the words to complete + def complete(search) + slop.map do |opt| + [opt.long && "--#{opt.long} " || opt.short && "-#{opt.short}"] + end.flatten(1).compact + super + end + + # A method called just before `options(opt)` as part of `call`. + # + # This method can be used to set up any context your command needs to run, + # for example requiring gems, or setting default values for options. + # + # @example + # def setup + # require 'gist' + # @action = :method + # end + def setup; end + + # A method to setup Slop commands so it can parse the subcommands your + # command expects. If you need to set up default values, use `setup` + # instead. + # + # @example A minimal example + # def subcommands(cmd) + # cmd.command :download do |opt| + # description 'Downloads a content from a server' + # + # opt.on :verbose, 'Use verbose output' + # + # run do |options, arguments| + # ContentDownloader.download(options, arguments) + # end + # end + # end + # + # @example Define the invokation block anywhere you want + # def subcommands(cmd) + # cmd.command :download do |opt| + # description 'Downloads a content from a server' + # + # opt.on :verbose, 'Use verbose output' + # end + # end + # + # def process + # # Perform calculations... + # opts.fetch_command(:download).run do |options, arguments| + # ContentDownloader.download(options, arguments) + # end + # # More calculations... + # end + def subcommands(cmd); end + + # A method to setup Slop so it can parse the options your command expects. + # + # @note Please don't do anything side-effecty in the main part of this + # method, as it may be called by Pry at any time for introspection reasons. + # If you need to set up default values, use `setup` instead. + # + # @example + # def options(opt) + # opt.banner "Gists methods or classes" + # opt.on(:c, :class, "gist a class") do + # @action = :class + # end + # end + def options(opt); end + + # The actual body of your command should go here. + # + # The `opts` mehod can be called to get the options that Slop has passed, + # and `args` gives the remaining, unparsed arguments. + # + # The return value of this method is discarded unless the command was + # created with `:keep_retval => true`, in which case it is returned to the + # repl. + # + # @example + # def process + # if opts.present?(:class) + # gist_class + # else + # gist_method + # end + # end + def process; raise CommandError, "command '#{command_name}' not implemented" end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/command_set.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/command_set.rb new file mode 100644 index 0000000..9483ab0 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/command_set.rb @@ -0,0 +1,443 @@ +class Pry + class NoCommandError < StandardError + def initialize(match, owner) + super "Command '#{match}' not found in command set #{owner}" + end + end + + # This class is used to create sets of commands. Commands can be imported from + # different sets, aliased, removed, etc. + class CommandSet + include Enumerable + include Pry::Helpers::BaseHelpers + attr_reader :helper_module + + # @param [Array] imported_sets + # Sets which will be imported automatically + # @yield Optional block run to define commands + def initialize(*imported_sets, &block) + @commands = {} + @helper_module = Module.new + import(*imported_sets) + instance_eval(&block) if block + end + + # Defines a new Pry command. + # @param [String, Regexp] match The start of invocations of this command. + # @param [String] description A description of the command. + # @param [Hash] options The optional configuration parameters. + # @option options [Boolean] :keep_retval Whether or not to use return value + # of the block for return of `command` or just to return `nil` + # (the default). + # @option options [Array] :requires_gem Whether the command has + # any gem dependencies, if it does and dependencies not met then + # command is disabled and a stub proc giving instructions to + # install command is provided. + # @option options [Boolean] :interpolate Whether string #{} based + # interpolation is applied to the command arguments before + # executing the command. Defaults to true. + # @option options [String] :listing The listing name of the + # command. That is the name by which the command is looked up by + # help and by show-command. Necessary for commands with regex matches. + # @option options [Boolean] :use_prefix Whether the command uses + # `Pry.config.command_prefix` prefix (if one is defined). Defaults + # to true. + # @option options [Boolean] :shellwords Whether the command's arguments + # should be split using Shellwords instead of just split on spaces. + # Defaults to true. + # @yield The action to perform. The parameters in the block + # determines the parameters the command will receive. All + # parameters passed into the block will be strings. Successive + # command parameters are separated by whitespace at the Pry prompt. + # @example + # MyCommands = Pry::CommandSet.new do + # command "greet", "Greet somebody" do |name| + # puts "Good afternoon #{name.capitalize}!" + # end + # end + # + # # From pry: + # # pry(main)> _pry_.commands = MyCommands + # # pry(main)> greet john + # # Good afternoon John! + # # pry(main)> help greet + # # Greet somebody + # @example Regexp command + # MyCommands = Pry::CommandSet.new do + # command /number-(\d+)/, "number-N regex command", :listing => "number" do |num, name| + # puts "hello #{name}, nice number: #{num}" + # end + # end + # + # # From pry: + # # pry(main)> _pry_.commands = MyCommands + # # pry(main)> number-10 john + # # hello john, nice number: 10 + # # pry(main)> help number + # # number-N regex command + def block_command(match, description="No description.", options={}, &block) + description, options = ["No description.", description] if description.is_a?(Hash) + options = Pry::Command.default_options(match).merge!(options) + + @commands[match] = Pry::BlockCommand.subclass(match, description, options, helper_module, &block) + end + alias_method :command, :block_command + + # Defines a new Pry command class. + # + # @param [String, Regexp] match The start of invocations of this command. + # @param [String] description A description of the command. + # @param [Hash] options The optional configuration parameters, see {#command} + # @yield The class body's definition. + # + # @example + # Pry::Commands.create_command "echo", "echo's the input", :shellwords => false do + # def options(opt) + # opt.banner "Usage: echo [-u | -d] " + # opt.on :u, :upcase, "ensure the output is all upper-case" + # opt.on :d, :downcase, "ensure the output is all lower-case" + # end + # + # def process + # raise Pry::CommandError, "-u and -d makes no sense" if opts.present?(:u) && opts.present?(:d) + # result = args.join(" ") + # result.downcase! if opts.present?(:downcase) + # result.upcase! if opts.present?(:upcase) + # output.puts result + # end + # end + # + def create_command(match, description="No description.", options={}, &block) + description, options = ["No description.", description] if description.is_a?(Hash) + options = Pry::Command.default_options(match).merge!(options) + + @commands[match] = Pry::ClassCommand.subclass(match, description, options, helper_module, &block) + @commands[match].class_eval(&block) + @commands[match] + end + + # Execute a block of code before a command is invoked. The block also + # gets access to parameters that will be passed to the command and + # is evaluated in the same context. + # @param [String, Regexp] search The match or listing of the command. + # @yield The block to be run before the command. + # @example Display parameter before invoking command + # Pry.config.commands.before_command("whereami") do |n| + # output.puts "parameter passed was #{n}" + # end + def before_command(search, &block) + cmd = find_command_by_match_or_listing(search) + cmd.hooks[:before].unshift block + end + + # Execute a block of code after a command is invoked. The block also + # gets access to parameters that will be passed to the command and + # is evaluated in the same context. + # @param [String, Regexp] search The match or listing of the command. + # @yield The block to be run after the command. + # @example Display text 'command complete' after invoking command + # Pry.config.commands.after_command("whereami") do |n| + # output.puts "command complete!" + # end + def after_command(search, &block) + cmd = find_command_by_match_or_listing(search) + cmd.hooks[:after] << block + end + + def each(&block) + @commands.each(&block) + end + + # Removes some commands from the set + # @param [Array] searches the matches or listings of the commands to remove + def delete(*searches) + searches.each do |search| + cmd = find_command_by_match_or_listing(search) + @commands.delete cmd.match + end + end + + # Imports all the commands from one or more sets. + # @param [Array] sets Command sets, all of the commands of which + # will be imported. + # @return [Pry::CommandSet] Returns the reciever (a command set). + def import(*sets) + sets.each do |set| + @commands.merge! set.to_hash + helper_module.send :include, set.helper_module + end + self + end + + # Imports some commands from a set + # @param [CommandSet] set Set to import commands from + # @param [Array] matches Commands to import + # @return [Pry::CommandSet] Returns the reciever (a command set). + def import_from(set, *matches) + helper_module.send :include, set.helper_module + matches.each do |match| + cmd = set.find_command_by_match_or_listing(match) + @commands[cmd.match] = cmd + end + self + end + + # @param [String, Regexp] match_or_listing The match or listing of a command. + # of the command to retrieve. + # @return [Command] The command object matched. + def find_command_by_match_or_listing(match_or_listing) + cmd = (@commands[match_or_listing] || + Pry::Helpers::BaseHelpers.find_command(match_or_listing, @commands)) + cmd or raise ArgumentError, "Cannot find a command: '#{match_or_listing}'!" + end + + # Aliases a command + # @param [String, Regex] match The match of the alias (can be a regex). + # @param [String] action The action to be performed (typically + # another command). + # @param [Hash] options The optional configuration parameters, + # accepts the same as the `command` method, but also allows the + # command description to be passed this way too as `:desc` + # @example Creating an alias for `ls -M` + # Pry.config.commands.alias_command "lM", "ls -M" + # @example Pass explicit description (overriding default). + # Pry.config.commands.alias_command "lM", "ls -M", :desc => "cutiepie" + def alias_command(match, action, options={}) + cmd = find_command(action) or fail "Command: `#{action}` not found" + original_options = cmd.options.dup + + options = original_options.merge!({ + :desc => "Alias for `#{action}`", + :listing => match + }).merge!(options) + + # ensure default description is used if desc is nil + desc = options.delete(:desc).to_s + + c = block_command match, desc, options do |*args| + run action, *args + end + + c.class_eval do + define_method(:complete) do |input| + cmd.new(context).complete(input) + end + end + + c.group "Aliases" + + c + end + + # Rename a command. Accepts either match or listing for the search. + # + # @param [String, Regexp] new_match The new match for the command. + # @param [String, Regexp] search The command's current match or listing. + # @param [Hash] options The optional configuration parameters, + # accepts the same as the `command` method, but also allows the + # command description to be passed this way too. + # @example Renaming the `ls` command and changing its description. + # Pry.config.commands.rename "dir", "ls", :description => "DOS friendly ls" + def rename_command(new_match, search, options={}) + cmd = find_command_by_match_or_listing(search) + + options = { + :listing => new_match, + :description => cmd.description + }.merge!(options) + + @commands[new_match] = cmd.dup + @commands[new_match].match = new_match + @commands[new_match].description = options.delete(:description) + @commands[new_match].options.merge!(options) + @commands.delete(cmd.match) + end + + def disabled_command(name_of_disabled_command, message, matcher=name_of_disabled_command) + create_command name_of_disabled_command do + match matcher + description "" + + define_method(:process) do + output.puts "DISABLED: #{message}" + end + end + end + + # Sets or gets the description for a command (replacing the old + # description). Returns current description if no description + # parameter provided. + # @param [String, Regexp] search The command match. + # @param [String?] description (nil) The command description. + # @example Setting + # MyCommands = Pry::CommandSet.new do + # desc "help", "help description" + # end + # @example Getting + # Pry.config.commands.desc "amend-line" + def desc(search, description=nil) + cmd = find_command_by_match_or_listing(search) + return cmd.description if !description + + cmd.description = description + end + + # Defines helpers methods for this command sets. + # Those helpers are only defined in this command set. + # + # @yield A block defining helper methods + # @example + # helpers do + # def hello + # puts "Hello!" + # end + # + # include OtherModule + # end + def helpers(&block) + helper_module.class_eval(&block) + end + + + # @return [Array] + # The list of commands provided by the command set. + def list_commands + @commands.keys + end + alias_method :keys, :list_commands + + def to_hash + @commands.dup + end + alias_method :to_h, :to_hash + + # Find a command that matches the given line + # @param [String] pattern The line that might be a command invocation + # @return [Pry::Command, nil] + def [](pattern) + @commands.values.select do |command| + command.matches?(pattern) + end.sort_by do |command| + command.match_score(pattern) + end.last + end + alias_method :find_command, :[] + + # + # Re-assign the command found at _pattern_ with _command_. + # + # @param [Regexp, String] pattern + # The command to add or replace(found at _pattern_). + # + # @param [Pry::Command] command + # The command to add. + # + # @return [Pry::Command] + # Returns the new command (matched with "pattern".) + # + # @example + # Pry.config.commands["help"] = MyHelpCommand + # + def []=(pattern, command) + if command.equal?(nil) + return @commands.delete(pattern) + end + unless Class === command && command < Pry::Command + raise TypeError, "command is not a subclass of Pry::Command" + end + bind_command_to_pattern = pattern != command.match + if bind_command_to_pattern + command_copy = command.dup + command_copy.match = pattern + @commands[pattern] = command_copy + else + @commands[pattern] = command + end + end + + # + # Add a command to set. + # + # @param [Command] command + # a subclass of Pry::Command. + # + def add_command(command) + self[command.match] = command + end + + # Find the command that the user might be trying to refer to. + # @param [String] search The user's search. + # @return [Pry::Command?] + def find_command_for_help(search) + find_command(search) || (begin + find_command_by_match_or_listing(search) + rescue ArgumentError + nil + end) + end + + # Is the given line a command invocation? + # @param [String] val + # @return [Boolean] + def valid_command?(val) + !!find_command(val) + end + + # Process the given line to see whether it needs executing as a command. + # @param [String] val The line to execute + # @param [Hash] context The context to execute the commands with + # @return [CommandSet::Result] + def process_line(val, context={}) + if command = find_command(val) + context = context.merge(:command_set => self) + retval = command.new(context).process_line(val) + Result.new(true, retval) + else + Result.new(false) + end + end + + # @private (used for testing) + def run_command(context, match, *args) + command = @commands[match] or raise NoCommandError.new(match, self) + command.new(context).call_safely(*args) + end + + # Generate completions for the user's search. + # @param [String] search The line to search for + # @param [Hash] context The context to create the command with + # @return [Array] + def complete(search, context={}) + if command = find_command(search) + command.new(context).complete(search) + else + @commands.keys.select do |key| + String === key && key.start_with?(search) + end.map{ |key| key + " " } + end + end + end + + # Wraps the return result of process_commands, indicates if the + # result IS a command and what kind of command (e.g void) + class Result + attr_reader :retval + + def initialize(is_command, retval = nil) + @is_command, @retval = is_command, retval + end + + # Is the result a command? + # @return [Boolean] + def command? + @is_command + end + + # Is the result a command and if it is, is it a void command? + # (one that does not return a value) + # @return [Boolean] + def void_command? + retval == Command::VOID_VALUE + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands.rb new file mode 100644 index 0000000..4b85ada --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands.rb @@ -0,0 +1,6 @@ +# Default commands used by Pry. +Pry::Commands = Pry::CommandSet.new + +Dir[File.expand_path('../commands', __FILE__) << '/*.rb'].each do |file| + require file +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/amend_line.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/amend_line.rb new file mode 100644 index 0000000..d30c9a0 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/amend_line.rb @@ -0,0 +1,99 @@ +class Pry + class Command::AmendLine < Pry::ClassCommand + match(/amend-line(?: (-?\d+)(?:\.\.(-?\d+))?)?/) + group 'Editing' + description 'Amend a line of input in multi-line mode.' + command_options :interpolate => false, :listing => 'amend-line' + + banner <<-'BANNER' + Amend a line of input in multi-line mode. `amend-line N`, where the N represents + line to replace. Can also specify a range of lines using `amend-line N..M` + syntax. Passing "!" as replacement content deletes the line(s) instead. + + amend-line 1 puts 'new' # replace line 1 + amend-line 1..4 ! # delete lines 1..4 + amend-line 3 >puts 'bye' # insert before line 3 + amend-line puts 'appended' # no line number modifies immediately preceding line + BANNER + + def process + raise CommandError, "No input to amend." if eval_string.empty? + + eval_string.replace amended_input(eval_string) + run "fix-indent" + run "show-input" + end + + private + + # @param [String] string The string to amend. + # @return [String] A new string with the amendments applied to it. + def amended_input(string) + input_array = eval_string.each_line.to_a + + if arg_string == "!" + delete_from_array(input_array, line_range) + elsif arg_string.start_with?(">") + insert_into_array(input_array, line_range) + else + replace_in_array(input_array, line_range) + end + + input_array.join + end + + def delete_from_array(array, range) + array.slice!(range) + end + + def insert_into_array(array, range) + insert_slot = Array(range).first + array.insert(insert_slot, arg_string[1..-1] << "\n") + end + + def replace_in_array(array, range) + array[range] = arg_string + "\n" + end + + # @return [Fixnum] The number of lines currently in `eval_string` (the input buffer). + def line_count + eval_string.lines.count + end + + # Returns the (one-indexed) start and end lines given by the user. + # The lines in this range will be affected by the `amend-line`. + # Returns `nil` if no lines were specified by the user. + # @return [Array, nil] + def start_and_end_line_number + start_line_number, end_line_number = args + end_line_number ||= start_line_number.to_i + + [start_line_number.to_i, end_line_number.to_i] if start_line_number + end + + # Takes two numbers that are 1-indexed, and returns a range (or + # number) that is 0-indexed. 1-indexed means the first element is + # indentified by 1 rather than by 0 (as is the case for Ruby arrays). + # @param [Fixnum] start_line_number One-indexed number. + # @param [Fixnum] end_line_number One-indexed number. + # @return [Range] The zero-indexed range. + def zero_indexed_range_from_one_indexed_numbers(start_line_number, end_line_number) + # FIXME: one_index_number is a horrible name for this method + one_index_number(start_line_number)..one_index_number(end_line_number) + end + + # The lines (or line) that will be modified by the `amend-line`. + # @return [Range, Fixnum] The lines or line. + def line_range + start_line_number, end_line_number = start_and_end_line_number + if start_line_number + zero_indexed_range_from_one_indexed_numbers(start_line_number, + end_line_number) + else + line_count - 1 + end + end + end + + Pry::Commands.add_command(Pry::Command::AmendLine) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang.rb new file mode 100644 index 0000000..117835e --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang.rb @@ -0,0 +1,20 @@ +class Pry + class Command::Bang < Pry::ClassCommand + match /^\s*!\s*$/ + group 'Editing' + description 'Clear the input buffer.' + command_options :use_prefix => false + + banner <<-'BANNER' + Clear the input buffer. Useful if the parsing process goes wrong and you get + stuck in the read loop. + BANNER + + def process + output.puts 'Input buffer cleared!' + eval_string.replace('') + end + end + + Pry::Commands.add_command(Pry::Command::Bang) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang_pry.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang_pry.rb new file mode 100644 index 0000000..71f81ef --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/bang_pry.rb @@ -0,0 +1,17 @@ +class Pry + class Command::BangPry < Pry::ClassCommand + match '!pry' + group 'Navigating Pry' + description 'Start a Pry session on current self.' + + banner <<-'BANNER' + Start a Pry session on current self. Also works mid multi-line expression. + BANNER + + def process + target.pry + end + end + + Pry::Commands.add_command(Pry::Command::BangPry) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat.rb new file mode 100644 index 0000000..8ca537f --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat.rb @@ -0,0 +1,62 @@ +class Pry + class Command::Cat < Pry::ClassCommand + require 'pry/commands/cat/abstract_formatter.rb' + require 'pry/commands/cat/input_expression_formatter.rb' + require 'pry/commands/cat/exception_formatter.rb' + require 'pry/commands/cat/file_formatter.rb' + + match 'cat' + group 'Input and Output' + description "Show code from a file, Pry's input buffer, or the last exception." + + banner <<-'BANNER' + Usage: cat FILE + cat --ex [STACK_INDEX] + cat --in [INPUT_INDEX_OR_RANGE] + + `cat` is capable of showing part or all of a source file, the context of the + last exception, or an expression from Pry's input history. + + `cat --ex` defaults to showing the lines surrounding the location of the last + exception. Invoking it more than once travels up the exception's backtrace, and + providing a number shows the context of the given index of the backtrace. + BANNER + + def options(opt) + opt.on :ex, "Show the context of the last exception", :optional_argument => true, :as => Integer + opt.on :i, :in, "Show one or more entries from Pry's expression history", :optional_argument => true, :as => Range, :default => -5..-1 + opt.on :s, :start, "Starting line (defaults to the first line)", :optional_argument => true, :as => Integer + opt.on :e, :end, "Ending line (defaults to the last line)", :optional_argument => true, :as => Integer + opt.on :l, :'line-numbers', "Show line numbers" + opt.on :t, :type, "The file type for syntax highlighting (e.g., 'ruby' or 'python')", :argument => true, :as => Symbol + end + + def process + output = case + when opts.present?(:ex) + ExceptionFormatter.new(_pry_.last_exception, _pry_, opts).format + when opts.present?(:in) + InputExpressionFormatter.new(_pry_.input_array, opts).format + else + FileFormatter.new(args.first, _pry_, opts).format + end + + _pry_.pager.page output + end + + def complete(search) + super | load_path_completions + end + + def load_path_completions + $LOAD_PATH.flat_map do |path| + Dir[path + '/**/*'].map { |f| + next if File.directory?(f) + f.sub!(path + '/', '') + } + end + end + end + + Pry::Commands.add_command(Pry::Command::Cat) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/abstract_formatter.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/abstract_formatter.rb new file mode 100644 index 0000000..661f036 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/abstract_formatter.rb @@ -0,0 +1,27 @@ +class Pry + class Command::Cat + class AbstractFormatter + include Pry::Helpers::CommandHelpers + include Pry::Helpers::BaseHelpers + + private + def decorate(content) + content.code_type = code_type + content.between(*between_lines). + with_line_numbers(use_line_numbers?) + end + + def code_type + opts[:type] || :ruby + end + + def use_line_numbers? + opts.present?(:'line-numbers') || opts.present?(:ex) + end + + def between_lines + [opts[:start] || 1, opts[:end] || -1] + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/exception_formatter.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/exception_formatter.rb new file mode 100644 index 0000000..af10e9d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/exception_formatter.rb @@ -0,0 +1,77 @@ +class Pry + class Command::Cat + class ExceptionFormatter < AbstractFormatter + attr_reader :ex + attr_reader :opts + attr_reader :_pry_ + + def initialize(exception, _pry_, opts) + @ex = exception + @opts = opts + @_pry_ = _pry_ + end + + def format + check_for_errors + set_file_and_dir_locals(backtrace_file, _pry_, _pry_.current_context) + code = decorate(Pry::Code.from_file(backtrace_file). + between(*start_and_end_line_for_code_window). + with_marker(backtrace_line)) + "#{header}#{code}" + end + + private + + def code_window_size + _pry_.config.default_window_size || 5 + end + + def backtrace_level + return @backtrace_level if @backtrace_level + + bl = if opts[:ex].nil? + ex.bt_index + else + ex.bt_index = absolute_index_number(opts[:ex], ex.backtrace.size) + end + + increment_backtrace_level + @backtrace_level = bl + end + + def increment_backtrace_level + ex.inc_bt_index + end + + def backtrace_file + Array(ex.bt_source_location_for(backtrace_level)).first + end + + def backtrace_line + Array(ex.bt_source_location_for(backtrace_level)).last + end + + def check_for_errors + raise CommandError, "No exception found." unless ex + raise CommandError, "The given backtrace level is out of bounds." unless backtrace_file + end + + def start_and_end_line_for_code_window + start_line = backtrace_line - code_window_size + start_line = 1 if start_line < 1 + + [start_line, backtrace_line + code_window_size] + end + + def header + unindent %{ + #{Helpers::Text.bold 'Exception:'} #{ex.class}: #{ex.message} + -- + #{Helpers::Text.bold('From:')} #{backtrace_file} @ line #{backtrace_line} @ #{Helpers::Text.bold("level: #{backtrace_level}")} of backtrace (of #{ex.backtrace.size - 1}). + + } + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/file_formatter.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/file_formatter.rb new file mode 100644 index 0000000..92c6268 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/file_formatter.rb @@ -0,0 +1,67 @@ +class Pry + class Command::Cat + class FileFormatter < AbstractFormatter + attr_reader :file_with_embedded_line + attr_reader :opts + attr_reader :_pry_ + + def initialize(file_with_embedded_line, _pry_, opts) + @file_with_embedded_line = file_with_embedded_line + @opts = opts + @_pry_ = _pry_ + @code_from_file = Pry::Code.from_file(file_name) + end + + def format + raise CommandError, "Must provide a filename, --in, or --ex." if !file_with_embedded_line + + set_file_and_dir_locals(file_name, _pry_, _pry_.current_context) + decorate(@code_from_file) + end + + def file_and_line + file_name, line_num = file_with_embedded_line.split(/:(?!\/|\\)/) + + [file_name, line_num ? line_num.to_i : nil] + end + + private + + def file_name + file_and_line.first + end + + def line_number + file_and_line.last + end + + def code_window_size + _pry_.config.default_window_size || 7 + end + + def decorate(content) + line_number ? super.around(line_number, code_window_size) : super + end + + def code_type + opts[:type] || detect_code_type_from_file(file_name) + end + + def detect_code_type_from_file(file_name) + code_type = @code_from_file.code_type + + if code_type == :unknown + name, ext = File.basename(file_name).split('.', 2) + case name + when "Rakefile", "Gemfile" + :ruby + else + :text + end + else + code_type + end + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/input_expression_formatter.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/input_expression_formatter.rb new file mode 100644 index 0000000..8791ac3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cat/input_expression_formatter.rb @@ -0,0 +1,43 @@ +class Pry + class Command::Cat + class InputExpressionFormatter < AbstractFormatter + attr_accessor :input_expressions + attr_accessor :opts + + def initialize(input_expressions, opts) + @input_expressions = input_expressions + @opts = opts + end + + def format + raise CommandError, "No input expressions!" if numbered_input_items.length < 1 + + if numbered_input_items.length > 1 + content = "" + numbered_input_items.each do |i, s| + content << "#{Helpers::Text.bold(i.to_s)}:\n" << decorate(Pry::Code(s).with_indentation(2)).to_s + end + + content + else + decorate(Pry::Code(selected_input_items.first)) + end + end + + private + + def selected_input_items + input_expressions[normalized_expression_range] || [] + end + + def numbered_input_items + @numbered_input_items ||= normalized_expression_range.zip(selected_input_items). + reject { |_, s| s.nil? || s == "" } + end + + def normalized_expression_range + absolute_index_range(opts[:i], input_expressions.length) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cd.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cd.rb new file mode 100644 index 0000000..667453a --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/cd.rb @@ -0,0 +1,41 @@ +class Pry + class Command::Cd < Pry::ClassCommand + match 'cd' + group 'Context' + description 'Move into a new context (object or scope).' + + banner <<-'BANNER' + Usage: cd [OPTIONS] [--help] + + Move into new context (object or scope). As in UNIX shells use `cd ..` to go + back, `cd /` to return to Pry top-level and `cd -` to toggle between last two + scopes. Complex syntax (e.g `cd ../@x/@y`) also supported. + + cd @x + cd .. + cd / + cd - + + https://github.com/pry/pry/wiki/State-navigation#wiki-Changing_scope + BANNER + + def process + state.old_stack ||= [] + + if arg_string.strip == "-" + unless state.old_stack.empty? + _pry_.binding_stack, state.old_stack = state.old_stack, _pry_.binding_stack + end + else + stack = ObjectPath.new(arg_string, _pry_.binding_stack).resolve + + if stack && stack != _pry_.binding_stack + state.old_stack = _pry_.binding_stack + _pry_.binding_stack = stack + end + end + end + end + + Pry::Commands.add_command(Pry::Command::Cd) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_inspector.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_inspector.rb new file mode 100644 index 0000000..183dec4 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_inspector.rb @@ -0,0 +1,27 @@ +class Pry::Command::ChangeInspector < Pry::ClassCommand + match 'change-inspector' + group 'Input and Output' + description 'Change the current inspector proc.' + command_options argument_required: true + banner <<-BANNER + Usage: change-inspector NAME + + Change the proc used to print return values. See list-inspectors for a list + of available procs and a short description of what each one does. + BANNER + + def process(inspector) + if inspector_map.key?(inspector) + _pry_.print = inspector_map[inspector][:value] + output.puts "Switched to the '#{inspector}' inspector!" + else + raise Pry::CommandError, "'#{inspector}' isn't a known inspector!" + end + end + +private + def inspector_map + Pry::Inspector::MAP + end + Pry::Commands.add_command(self) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_prompt.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_prompt.rb new file mode 100644 index 0000000..13d36cb --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/change_prompt.rb @@ -0,0 +1,26 @@ +class Pry::Command::ChangePrompt < Pry::ClassCommand + match 'change-prompt' + group 'Input and Output' + description 'Change the current prompt.' + command_options argument_required: true + banner <<-BANNER + Usage: change-prompt NAME + + Change the current prompt. See list-prompts for a list of available + prompts. + BANNER + + def process(prompt) + if prompt_map.key?(prompt) + _pry_.prompt = prompt_map[prompt][:value] + else + raise Pry::CommandError, "'#{prompt}' isn't a known prompt!" + end + end + +private + def prompt_map + Pry::Prompt::MAP + end + Pry::Commands.add_command(self) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/code_collector.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/code_collector.rb new file mode 100644 index 0000000..72e8181 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/code_collector.rb @@ -0,0 +1,165 @@ +class Pry + class Command::CodeCollector + include Helpers::CommandHelpers + + attr_reader :args + attr_reader :opts + attr_reader :_pry_ + + # The name of the explicitly given file (if any). + attr_accessor :file + + class << self + attr_accessor :input_expression_ranges + attr_accessor :output_result_ranges + end + + @input_expression_ranges = [] + @output_result_ranges = [] + + def initialize(args, opts, _pry_) + @args = args + @opts = opts + @_pry_ = _pry_ + end + + # Add the `--lines`, `-o`, `-i`, `-s`, `-d` options. + def self.inject_options(opt) + @input_expression_ranges = [] + @output_result_ranges = [] + + opt.on :l, :lines, "Restrict to a subset of lines. Takes a line number or range", + :optional_argument => true, :as => Range, :default => 1..-1 + opt.on :o, :out, "Select lines from Pry's output result history. Takes an index or range", + :optional_argument => true, :as => Range, :default => -5..-1 do |r| + output_result_ranges << (r || (-5..-1)) + end + opt.on :i, :in, "Select lines from Pry's input expression history. Takes an index or range", + :optional_argument => true, :as => Range, :default => -5..-1 do |r| + input_expression_ranges << (r || (-5..-1)) + end + opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", + :as => :count + opt.on :d, :doc, "Select lines from the code object's documentation" + end + + # The content (i.e code/docs) for the selected object. + # If the user provided a bare code object, it returns the source. + # If the user provided the `-i` or `-o` switches, it returns the + # selected input/output lines joined as a string. If the user used + # `-d CODE_OBJECT` it returns the docs for that code object. + # + # @return [String] + def content + return @content if @content + raise CommandError, "Only one of --out, --in, --doc and CODE_OBJECT may be specified." if bad_option_combination? + + content = case + when opts.present?(:o) + pry_output_content + when opts.present?(:i) + pry_input_content + when opts.present?(:d) + code_object_doc + else + code_object_source_or_file + end + + @content ||= restrict_to_lines(content, line_range) + end + + # The code object + # + # @return [Pry::WrappedModule, Pry::Method, Pry::Command] + def code_object + Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super]) + end + + # Given a string and a range, return the `range` lines of that + # string. + # + # @param [String] content + # @param [Range, Fixnum] range + # @return [String] The string restricted to the given range + def restrict_to_lines(content, range) + Array(content.lines.to_a[range]).join + end + + # The selected `_pry_.output_array` as a string, as specified by + # the `-o` switch. + # + # @return [String] + def pry_output_content + pry_array_content_as_string(_pry_.output_array, self.class.output_result_ranges) do |v| + _pry_.config.gist.inspecter.call(v) + end + end + + # The selected `_pry_.input_array` as a string, as specified by + # the `-i` switch. + # + # @return [String] + def pry_input_content + pry_array_content_as_string(_pry_.input_array, self.class.input_expression_ranges) { |v| v } + end + + # The line range passed to `--lines`, converted to a 0-indexed range. + def line_range + opts.present?(:lines) ? one_index_range_or_number(opts[:lines]) : 0..-1 + end + + # Name of the object argument + def obj_name + @obj_name ||= args.empty? ? "" : args.join(" ") + end + + private + + def bad_option_combination? + [opts.present?(:in), opts.present?(:out), + !args.empty?].count(true) > 1 + end + + def pry_array_content_as_string(array, ranges, &block) + all = '' + ranges.each do |range| + raise CommandError, "Minimum value for range is 1, not 0." if convert_to_range(range).first == 0 + + ranged_array = Array(array[range]) || [] + ranged_array.compact.each { |v| all << block.call(v) } + end + + all + end + + def code_object_doc + (code_object && code_object.doc) or could_not_locate(obj_name) + end + + def code_object_source_or_file + (code_object && code_object.source) || file_content + end + + def file_content + if File.exists?(obj_name) + # Set the file accessor. + self.file = obj_name + File.read(obj_name) + else + could_not_locate(obj_name) + end + end + + def could_not_locate(name) + raise CommandError, "Cannot locate: #{name}!" + end + + def convert_to_range(n) + if !n.is_a?(Range) + (n..n) + else + n + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disable_pry.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disable_pry.rb new file mode 100644 index 0000000..69bfc4e --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disable_pry.rb @@ -0,0 +1,27 @@ +class Pry + class Command::DisablePry < Pry::ClassCommand + match 'disable-pry' + group 'Navigating Pry' + description 'Stops all future calls to pry and exits the current session.' + + banner <<-'BANNER' + Usage: disable-pry + + After this command is run any further calls to pry will immediately return `nil` + without interrupting the flow of your program. This is particularly useful when + you've debugged the problem you were having, and now wish the program to run to + the end. + + As alternatives, consider using `exit!` to force the current Ruby process + to quit immediately; or using `edit-method -p` to remove the `binding.pry` + from the code. + BANNER + + def process + ENV['DISABLE_PRY'] = 'true' + _pry_.run_command "exit" + end + end + + Pry::Commands.add_command(Pry::Command::DisablePry) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disabled_commands.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disabled_commands.rb new file mode 100644 index 0000000..9866f90 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/disabled_commands.rb @@ -0,0 +1,2 @@ +Pry::Commands.disabled_command("edit-method", "Use `edit` instead.") +Pry::Commands.disabled_command("show-command", "Use show-source [command_name] instead.") diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/easter_eggs.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/easter_eggs.rb new file mode 100644 index 0000000..84a97df --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/easter_eggs.rb @@ -0,0 +1,112 @@ +class Pry + Pry::Commands.instance_eval do + command "nyan-cat", "", :requires_gem => ["nyancat"] do + run ".nyancat" + end + + command(/!s\/(.*?)\/(.*?)/, "") do |source, dest| + eval_string.gsub!(/#{source}/) { dest } + run "show-input" + end + + command "get-naked", "" do + text = %{ + -- + We dont have to take our clothes off to have a good time. + We could dance & party all night And drink some cherry wine. + -- Jermaine Stewart } + output.puts text + text + end + + command "east-coker", "" do + text = %{ + -- + Now the light falls + Across the open field, leaving the deep lane + Shuttered with branches, dark in the afternoon, + Where you lean against a bank while a van passes, + And the deep lane insists on the direction + Into the village, in the electric heat + Hypnotised. In a warm haze the sultry light + Is absorbed, not refracted, by grey stone. + The dahlias sleep in the empty silence. + Wait for the early owl. + -- T.S Eliot + } + output.puts text + text + end + + command "cohen-poem", "" do + text = %{ + -- + When this American woman, + whose thighs are bound in casual red cloth, + comes thundering past my sitting place + like a forest-burning Mongol tribe, + the city is ravished + and brittle buildings of a hundred years + splash into the street; + and my eyes are burnt + for the embroidered Chinese girls, + already old, + and so small between the thin pines + on these enormous landscapes, + that if you turn your head + they are lost for hours. + -- Leonard Cohen + } + output.puts text + text + end + + command "pessoa-poem", "" do + output.puts <<-TEXT + -- + I've gone to bed with every feeling, + I've been the pimp of every emotion, + All felt sensations have bought me drinks, + I've traded glances with every motive for every act, + I've held hands with every urge to depart, + .. + Rage, foam, the vastness that doesn't fit in my handkerchief, + The dog in heat howling in the night, + The pond from the farm going in circles around my insomnia, + The woods as they were, on our late-afternoon walks, the rose, + The indifferent tuft of hair, the moss, the pines, + The rage of not containing all this, not retaining all this, + O abstract hunger for things, impotent libido for moments, + Intellectual orgy of feeling life! + -- Fernando Pessoa +TEXT + end + + command "test-ansi", "" do + prev_color = _pry_.config.color + _pry_.config.color = true + + picture = unindent <<-'EOS'.gsub(/[[:alpha:]!]/) { |s| text.red(s) } + ____ _______________________ + / \ | A W G | + / O O \ | N I O N ! | + | | | S S R I ! | + \ \__/ / __| I K ! | + \____/ \________________________| + EOS + + if windows_ansi? + move_up = proc { |n| "\e[#{n}F" } + else + move_up = proc { |n| "\e[#{n}A\e[0G" } + end + + output.puts "\n" * 6 + output.puts picture.lines.map(&:chomp).reverse.join(move_up[1]) + output.puts "\n" * 6 + output.puts "** ENV['TERM'] is #{ENV['TERM']} **\n\n" + + _pry_.config.color = prev_color + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit.rb new file mode 100644 index 0000000..cf2cc1c --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit.rb @@ -0,0 +1,195 @@ +class Pry + class Command::Edit < Pry::ClassCommand + require 'pry/commands/edit/exception_patcher' + require 'pry/commands/edit/file_and_line_locator' + + match 'edit' + group 'Editing' + description 'Invoke the default editor on a file.' + + banner <<-'BANNER' + Usage: edit [--no-reload|--reload|--patch] [--line LINE] [--temp|--ex|FILE[:LINE]|OBJECT|--in N] + + Open a text editor. When no FILE is given, edits the pry input buffer. + When a method/module/command is given, the code is opened in an editor. + Ensure `Pry.config.editor` or `_pry_.config.editor` is set to your editor of choice. + + edit sample.rb edit -p MyClass#my_method + edit sample.rb --line 105 edit MyClass + edit MyClass#my_method edit --ex + edit --method edit --ex -p + + https://github.com/pry/pry/wiki/Editor-integration#wiki-Edit_command + BANNER + + def options(opt) + opt.on :e, :ex, "Open the file that raised the most recent exception (_ex_.file)", + :optional_argument => true, :as => Integer + opt.on :i, :in, "Open a temporary file containing the Nth input expression. N may be a range", + :optional_argument => true, :as => Range, :default => -1..-1 + opt.on :t, :temp, "Open an empty temporary file" + opt.on :l, :line, "Jump to this line in the opened file", + :argument => true, :as => Integer + opt.on :n, :"no-reload", "Don't automatically reload the edited file" + opt.on :c, :current, "Open the current __FILE__ and at __LINE__ (as returned by `whereami`)" + opt.on :r, :reload, "Reload the edited code immediately (default for ruby files)" + opt.on :p, :patch, "Instead of editing the object's file, try to edit in a tempfile and apply as a monkey patch" + opt.on :m, :method, "Explicitly edit the _current_ method (when inside a method context)." + end + + def process + if bad_option_combination? + raise CommandError, "Only one of --ex, --temp, --in, --method and FILE may be specified." + end + + if repl_edit? + # code defined in pry, eval'd within pry. + repl_edit + elsif runtime_patch? + # patch code without persisting changes + apply_runtime_patch + else + # code stored in actual files, eval'd at top-level + file_edit + end + end + + def repl_edit? + !opts.present?(:ex) && !opts.present?(:current) && !opts.present?(:method) && + filename_argument.empty? + end + + def repl_edit + content = Pry::Editor.new(_pry_).edit_tempfile_with_content(initial_temp_file_content, + initial_temp_file_content.lines.count) + silence_warnings do + eval_string.replace content + end + end + + def file_based_exception? + opts.present?(:ex) && !opts.present?(:patch) + end + + def runtime_patch? + !file_based_exception? && (opts.present?(:patch) || pry_method?(code_object)) + end + + def apply_runtime_patch + if patch_exception? + ExceptionPatcher.new(_pry_, state, file_and_line_for_current_exception).perform_patch + else + if code_object.is_a?(Pry::Method) + code_object.redefine Pry::Editor.new(_pry_).edit_tempfile_with_content(code_object.source) + else + raise NotImplementedError, "Cannot yet patch #{code_object} objects!" + end + end + end + + def ensure_file_name_is_valid(file_name) + raise CommandError, "Cannot find a valid file for #{filename_argument}" if !file_name + raise CommandError, "#{file_name} is not a valid file name, cannot edit!" if not_a_real_file?(file_name) + end + + def file_and_line_for_current_exception + FileAndLineLocator.from_exception(_pry_.last_exception, opts[:ex].to_i) + end + + def file_and_line + file_name, line = if opts.present?(:current) + FileAndLineLocator.from_binding(target) + elsif opts.present?(:ex) + file_and_line_for_current_exception + elsif code_object + FileAndLineLocator.from_code_object(code_object, filename_argument) + else + # when file and line are passed as a single arg, e.g my_file.rb:30 + FileAndLineLocator.from_filename_argument(filename_argument) + end + + [file_name, opts.present?(:line) ? opts[:l].to_i : line] + end + + def file_edit + file_name, line = file_and_line + + ensure_file_name_is_valid(file_name) + + Pry::Editor.new(_pry_).invoke_editor(file_name, line, reload?(file_name)) + set_file_and_dir_locals(file_name) + + if reload?(file_name) + silence_warnings do + load file_name + end + end + end + + def filename_argument + args.join(' ') + end + + def code_object + @code_object ||= !probably_a_file?(filename_argument) && + Pry::CodeObject.lookup(filename_argument, _pry_) + end + + def pry_method?(code_object) + code_object.is_a?(Pry::Method) && + code_object.pry_method? + end + + def patch_exception? + opts.present?(:ex) && opts.present?(:patch) + end + + def bad_option_combination? + [opts.present?(:ex), opts.present?(:temp), + opts.present?(:in), opts.present?(:method), !filename_argument.empty?].count(true) > 1 + end + + def input_expression + case opts[:i] + when Range + (_pry_.input_array[opts[:i]] || []).join + when Fixnum + _pry_.input_array[opts[:i]] || "" + else + raise Pry::CommandError, "Not a valid range: #{opts[:i]}" + end + end + + def reloadable? + opts.present?(:reload) || opts.present?(:ex) + end + + def never_reload? + opts.present?(:'no-reload') || _pry_.config.disable_auto_reload + end + + def reload?(file_name="") + (reloadable? || file_name.end_with?(".rb")) && !never_reload? + end + + def initial_temp_file_content + case + when opts.present?(:temp) + "" + when opts.present?(:in) + input_expression + when eval_string.strip != "" + eval_string + else + _pry_.input_array.reverse_each.find { |x| x && x.strip != "" } || "" + end + end + + def probably_a_file?(str) + [".rb", ".c", ".py", ".yml", ".gemspec"].include?(File.extname(str)) || + str =~ /\/|\\/ + end + end + + Pry::Commands.add_command(Pry::Command::Edit) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/exception_patcher.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/exception_patcher.rb new file mode 100644 index 0000000..07e13bc --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/exception_patcher.rb @@ -0,0 +1,25 @@ +class Pry + class Command::Edit + class ExceptionPatcher + attr_accessor :_pry_ + attr_accessor :state + attr_accessor :file_and_line + + def initialize(_pry_, state, exception_file_and_line) + @_pry_ = _pry_ + @state = state + @file_and_line = exception_file_and_line + end + + # perform the patch + def perform_patch + file_name, _ = file_and_line + lines = state.dynamical_ex_file || File.read(file_name) + + source = Pry::Editor.new(_pry_).edit_tempfile_with_content(lines) + _pry_.evaluate_ruby source + state.dynamical_ex_file = source.split("\n") + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/file_and_line_locator.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/file_and_line_locator.rb new file mode 100644 index 0000000..5f712f3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/edit/file_and_line_locator.rb @@ -0,0 +1,36 @@ +class Pry + class Command::Edit + module FileAndLineLocator + class << self + def from_binding(target) + [target.eval("__FILE__"), target.eval("__LINE__")] + end + + def from_code_object(code_object, filename_argument) + if File.exists?(code_object.source_file.to_s) + [code_object.source_file, code_object.source_line] + else + raise CommandError, "Cannot find a file for #{filename_argument}!" + end + end + + def from_exception(exception, backtrace_level) + raise CommandError, "No exception found." if exception.nil? + + file_name, line = exception.bt_source_location_for(backtrace_level) + raise CommandError, "Exception has no associated file." if file_name.nil? + raise CommandError, "Cannot edit exceptions raised in REPL." if Pry.eval_path == file_name + + [file_name, line] + end + + # when file and line are passed as a single arg, e.g my_file.rb:30 + def from_filename_argument(filename_argument) + f = File.expand_path(filename_argument) + l = f.sub!(/:(\d+)$/, "") ? $1.to_i : 1 + [f, l] + end + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit.rb new file mode 100644 index 0000000..32c0c2e --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit.rb @@ -0,0 +1,42 @@ +class Pry + class Command::Exit < Pry::ClassCommand + match 'exit' + group 'Navigating Pry' + description 'Pop the previous binding.' + command_options :keep_retval => true + + banner <<-'BANNER' + Usage: exit [OPTIONS] [--help] + Aliases: quit + + Pop the previous binding (does NOT exit program). It can be useful to exit a + context with a user-provided value. For instance an exit value can be used to + determine program flow. + + exit "pry this" + exit + + https://github.com/pry/pry/wiki/State-navigation#wiki-Exit_with_value + BANNER + + def process + if _pry_.binding_stack.one? + _pry_.run_command "exit-all #{arg_string}" + else + # otherwise just pop a binding and return user supplied value + process_pop_and_return + end + end + + def process_pop_and_return + popped_object = _pry_.binding_stack.pop.eval('self') + + # return a user-specified value if given otherwise return the object + return target.eval(arg_string) unless arg_string.empty? + popped_object + end + end + + Pry::Commands.add_command(Pry::Command::Exit) + Pry::Commands.alias_command 'quit', 'exit' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_all.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_all.rb new file mode 100644 index 0000000..1136de3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_all.rb @@ -0,0 +1,29 @@ +class Pry + class Command::ExitAll < Pry::ClassCommand + match 'exit-all' + group 'Navigating Pry' + description 'End the current Pry session.' + + banner <<-'BANNER' + Usage: exit-all [--help] + Aliases: !!@ + + End the current Pry session (popping all bindings and returning to caller). + Accepts optional return value. + BANNER + + def process + # calculate user-given value + exit_value = target.eval(arg_string) + + # clear the binding stack + _pry_.binding_stack.clear + + # break out of the repl loop + throw(:breakout, exit_value) + end + end + + Pry::Commands.add_command(Pry::Command::ExitAll) + Pry::Commands.alias_command '!!@', 'exit-all' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_program.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_program.rb new file mode 100644 index 0000000..a4d9168 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/exit_program.rb @@ -0,0 +1,23 @@ +class Pry + class Command::ExitProgram < Pry::ClassCommand + match 'exit-program' + group 'Navigating Pry' + description 'End the current program.' + + banner <<-'BANNER' + Usage: exit-program [--help] + Aliases: quit-program + !!! + + End the current program. + BANNER + + def process + Kernel.exit target.eval(arg_string).to_i + end + end + + Pry::Commands.add_command(Pry::Command::ExitProgram) + Pry::Commands.alias_command 'quit-program', 'exit-program' + Pry::Commands.alias_command '!!!', 'exit-program' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/find_method.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/find_method.rb new file mode 100644 index 0000000..c1ee2c5 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/find_method.rb @@ -0,0 +1,193 @@ +class Pry + class Command::FindMethod < Pry::ClassCommand + extend Pry::Helpers::BaseHelpers + + match 'find-method' + group 'Context' + description 'Recursively search for a method within a Class/Module or the current namespace.' + command_options :shellwords => false + + banner <<-'BANNER' + Usage: find-method [-n|-c] METHOD [NAMESPACE] + + Recursively search for a method within a Class/Module or the current namespace. + Use the `-n` switch (the default) to search for methods whose name matches the + given regex. Use the `-c` switch to search for methods that contain the given + code. + + # Find all methods whose name match /re/ inside + # the Pry namespace. Matches Pry#repl, etc. + find-method re Pry + + # Find all methods that contain the code: + # output.puts inside the Pry namepsace. + find-method -c 'output.puts' Pry + BANNER + + def options(opt) + opt.on :n, :name, "Search for a method by name" + opt.on :c, :content, "Search for a method based on content in Regex form" + end + + def process + return if args.size < 1 + klass = search_class + + matches = if opts.content? + content_search(klass) + else + name_search(klass) + end + + show_search_results(matches) + end + + private + + # @return [Regexp] The pattern to search for. + def pattern + @pattern ||= ::Regexp.new args[0] + end + + # Output the result of the search. + # + # @param [Array] matches + def show_search_results(matches) + if matches.empty? + output.puts text.bold("No Methods Matched") + else + print_matches(matches) + end + end + + # The class to search for methods. + # We only search classes, so if the search object is an + # instance, return its class. If no search object is given + # search `target_self`. + def search_class + klass = if args[1] + target.eval(args[1]) + else + target_self + end + + klass.is_a?(Module) ? klass : klass.class + end + + # pretty-print a list of matching methods. + # + # @param [Array] matches + def print_matches(matches) + grouped = matches.group_by(&:owner) + order = grouped.keys.sort_by{ |x| x.name || x.to_s } + + order.each do |klass| + print_matches_for_class(klass, grouped) + end + end + + # Print matched methods for a class + def print_matches_for_class(klass, grouped) + output.puts text.bold(klass.name) + grouped[klass].each do |method| + header = method.name_with_owner + output.puts header + additional_info(header, method) + end + end + + # Return the matched lines of method source if `-c` is given or "" + # if `-c` was not given + def additional_info(header, method) + if opts.content? + ": " << colorize_code(matched_method_lines(header, method)) + else + "" + end + end + + def matched_method_lines(header, method) + method.source.split(/\n/).select {|x| x =~ pattern }.join("\n#{' ' * header.length}") + end + + # Run the given block against every constant in the provided namespace. + # + # @param [Module] klass The namespace in which to start the search. + # @param [Hash] done The namespaces we've already visited (private) + # @yieldparam klass Each class/module in the namespace. + # + def recurse_namespace(klass, done={}, &block) + return if !(Module === klass) || done[klass] + + done[klass] = true + + yield klass + + klass.constants.each do |name| + next if klass.autoload?(name) + begin + const = klass.const_get(name) + rescue RescuableException + # constant loading is an inexact science at the best of times, + # this often happens when a constant was .autoload? but someone + # tried to load it. It's now not .autoload? but will still raise + # a NameError when you access it. + else + recurse_namespace(const, done, &block) + end + end + end + + # Gather all the methods in a namespace that pass the given block. + # + # @param [Module] namespace The namespace in which to search. + # @yieldparam [Method] method The method to test + # @yieldreturn [Boolean] + # @return [Array] + # + def search_all_methods(namespace) + done = Hash.new{ |h,k| h[k] = {} } + matches = [] + + recurse_namespace(namespace) do |klass| + (Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)).each do |method| + next if done[method.owner][method.name] + done[method.owner][method.name] = true + + matches << method if yield method + end + end + + matches + end + + # Search for all methods with a name that matches the given regex + # within a namespace. + # + # @param [Module] namespace The namespace to search + # @return [Array] + # + def name_search(namespace) + search_all_methods(namespace) do |meth| + meth.name =~ pattern + end + end + + # Search for all methods who's implementation matches the given regex + # within a namespace. + # + # @param [Module] namespace The namespace to search + # @return [Array] + # + def content_search(namespace) + search_all_methods(namespace) do |meth| + begin + meth.source =~ pattern + rescue RescuableException + false + end + end + end + end + + Pry::Commands.add_command(Pry::Command::FindMethod) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/fix_indent.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/fix_indent.rb new file mode 100644 index 0000000..75c48c7 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/fix_indent.rb @@ -0,0 +1,19 @@ +class Pry + class Command::FixIndent < Pry::ClassCommand + match 'fix-indent' + group 'Input and Output' + + description "Correct the indentation for contents of the input buffer" + + banner <<-USAGE + Usage: fix-indent + USAGE + + def process + indented_str = Pry::Indent.indent(eval_string) + eval_string.replace indented_str + end + end + + Pry::Commands.add_command(Pry::Command::FixIndent) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_cd.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_cd.rb new file mode 100644 index 0000000..da1907a --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_cd.rb @@ -0,0 +1,26 @@ +class Pry + class Command::GemCd < Pry::ClassCommand + match 'gem-cd' + group 'Gems' + description "Change working directory to specified gem's directory." + command_options :argument_required => true + + banner <<-'BANNER' + Usage: gem-cd GEM_NAME + + Change the current working directory to that in which the given gem is + installed. + BANNER + + def process(gem) + Dir.chdir(Rubygem.spec(gem).full_gem_path) + output.puts(Dir.pwd) + end + + def complete(str) + Rubygem.complete(str) + end + end + + Pry::Commands.add_command(Pry::Command::GemCd) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_install.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_install.rb new file mode 100644 index 0000000..873e106 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_install.rb @@ -0,0 +1,32 @@ +class Pry + class Command::GemInstall < Pry::ClassCommand + match 'gem-install' + group 'Gems' + description 'Install a gem and refresh the gem cache.' + command_options :argument_required => true + + banner <<-'BANNER' + Usage: gem-install GEM_NAME + + Installs the given gem, refreshes the gem cache, and requires the gem for you + based on a best guess from the gem name. + + gem-install pry-stack_explorer + BANNER + + def setup + require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller + end + + def process(gem) + Rubygem.install(gem) + output.puts "Gem `#{ text.green(gem) }` installed." + require gem + rescue LoadError + require_path = gem.split('-').join('/') + require require_path + end + end + + Pry::Commands.add_command(Pry::Command::GemInstall) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_list.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_list.rb new file mode 100644 index 0000000..e4a5d00 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_list.rb @@ -0,0 +1,33 @@ +class Pry + class Command::GemList < Pry::ClassCommand + match 'gem-list' + group 'Gems' + description 'List and search installed gems.' + + banner <<-'BANNER' + Usage: gem-list [REGEX] + + List all installed gems, when a regex is provided, limit the output to those + that match the regex. + BANNER + + def process(pattern = nil) + pattern = Regexp.compile(pattern || '') + gems = Rubygem.list(pattern).group_by(&:name) + + gems.each do |gem, specs| + specs.sort! do |a,b| + Gem::Version.new(b.version) <=> Gem::Version.new(a.version) + end + + versions = specs.each_with_index.map do |spec, index| + index == 0 ? text.bright_green(spec.version.to_s) : text.green(spec.version.to_s) + end + + output.puts "#{text.default gem} (#{versions.join ', '})" + end + end + end + + Pry::Commands.add_command(Pry::Command::GemList) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_open.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_open.rb new file mode 100644 index 0000000..e21723a --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gem_open.rb @@ -0,0 +1,29 @@ +class Pry + class Command::GemOpen < Pry::ClassCommand + match 'gem-open' + group 'Gems' + description 'Opens the working directory of the gem in your editor.' + command_options :argument_required => true + + banner <<-'BANNER' + Usage: gem-open GEM_NAME + + Change the current working directory to that in which the given gem is + installed, and then opens your text editor. + + gem-open pry-exception_explorer + BANNER + + def process(gem) + Dir.chdir(Rubygem.spec(gem).full_gem_path) do + Pry::Editor.invoke_editor(".", 0, false) + end + end + + def complete(str) + Rubygem.complete(str) + end + end + + Pry::Commands.add_command(Pry::Command::GemOpen) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gist.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gist.rb new file mode 100644 index 0000000..83cdf2b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/gist.rb @@ -0,0 +1,101 @@ +class Pry + class Command::Gist < Pry::ClassCommand + match 'gist' + group 'Misc' + description 'Upload code, docs, history to https://gist.github.com/.' + command_options :requires_gem => "gist" + + banner <<-'BANNER' + Usage: gist [OPTIONS] [--help] + + The gist command enables you to gist code from files and methods to github. + + gist -i 20 --lines 1..3 + gist Pry#repl --lines 1..-1 + gist Rakefile --lines 5 + BANNER + + def setup + require 'gist' + end + + def options(opt) + CodeCollector.inject_options(opt) + opt.on :login, "Authenticate the gist gem with GitHub" + opt.on :p, :public, "Create a public gist (default: false)", :default => false + opt.on :clip, "Copy the selected content to clipboard instead, do NOT gist it", :default => false + end + + def process + return ::Gist.login! if opts.present?(:login) + cc = CodeCollector.new(args, opts, _pry_) + + if cc.content =~ /\A\s*\z/ + raise CommandError, "Found no code to gist." + end + + if opts.present?(:clip) + clipboard_content(cc.content) + else + # we're overriding the default behavior of the 'in' option (as + # defined on CodeCollector) with our local behaviour. + content = opts.present?(:in) ? input_content : cc.content + gist_content content, cc.file + end + end + + def clipboard_content(content) + ::Gist.copy(content) + output.puts "Copied content to clipboard!" + end + + def input_content + content = "" + CodeCollector.input_expression_ranges.each do |range| + input_expressions = _pry_.input_array[range] || [] + Array(input_expressions).each_with_index do |code, index| + corrected_index = index + range.first + if code && code != "" + content << code + if code !~ /;\Z/ + content << "#{comment_expression_result_for_gist(_pry_.config.gist.inspecter.call(_pry_.output_array[corrected_index]))}" + end + end + end + end + + content + end + + def comment_expression_result_for_gist(result) + content = "" + result.lines.each_with_index do |line, index| + if index == 0 + content << "# => #{line}" + else + content << "# #{line}" + end + end + + content + end + + def gist_content(content, filename) + response = ::Gist.gist(content, :filename => filename || "pry_gist.rb", :public => !!opts[:p]) + if response + url = response['html_url'] + message = "Gist created at URL #{url}" + begin + ::Gist.copy(url) + message << ", which is now in the clipboard." + rescue ::Gist::ClipboardError + end + + output.puts message + end + end + end + + Pry::Commands.add_command(Pry::Command::Gist) + Pry::Commands.alias_command 'clipit', 'gist --clip' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/help.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/help.rb new file mode 100644 index 0000000..3f29c2c --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/help.rb @@ -0,0 +1,164 @@ +class Pry + class Command::Help < Pry::ClassCommand + match 'help' + group 'Help' + description 'Show a list of commands or information about a specific command.' + + banner <<-'BANNER' + Usage: help [COMMAND] + + With no arguments, help lists all the available commands along with their + descriptions. When given a command name as an argument, shows the help + for that command. + BANNER + + # We only want to show commands that have descriptions, so that the + # easter eggs don't show up. + def visible_commands + visible = {} + commands.each do |key, command| + visible[key] = command if command.description && !command.description.empty? + end + visible + end + + # Get a hash of available commands grouped by the "group" name. + def command_groups + visible_commands.values.group_by(&:group) + end + + def process + if args.empty? + display_index(command_groups) + else + display_search(args.first) + end + end + + # Display the index view, with headings and short descriptions per command. + # + # @param [Hash>] groups + def display_index(groups) + help_text = [] + + sorted_group_names(groups).each do |group_name| + commands = sorted_commands(groups[group_name]) + + if commands.any? + help_text << help_text_for_commands(group_name, commands) + end + end + + _pry_.pager.page help_text.join("\n\n") + end + + # Given a group name and an array of commands, + # return the help string for those commands. + # + # @param [String] name The group name. + # @param [Array] commands + # @return [String] The generated help string. + def help_text_for_commands(name, commands) + "#{text.bold(name.capitalize)}\n" << commands.map do |command| + " #{command.options[:listing].to_s.ljust(18)} #{command.description.capitalize}" + end.join("\n") + end + + # @param [Hash] groups + # @return [Array] An array of sorted group names. + def sorted_group_names(groups) + groups.keys.sort_by(&method(:group_sort_key)) + end + + # Sort an array of commands by their `listing` name. + # + # @param [Array] commands The commands to sort + # @return [Array] commands sorted by listing name. + def sorted_commands(commands) + commands.sort_by{ |command| command.options[:listing].to_s } + end + + # Display help for an individual command or group. + # + # @param [String] search The string to search for. + def display_search(search) + if command = command_set.find_command_for_help(search) + display_command(command) + else + display_filtered_search_results(search) + end + end + + # Display help for a searched item, filtered first by group + # and if that fails, filtered by command name. + # + # @param [String] search The string to search for. + def display_filtered_search_results(search) + groups = search_hash(search, command_groups) + + if groups.size > 0 + display_index(groups) + else + display_filtered_commands(search) + end + end + + # Display help for a searched item, filtered by group + # + # @param [String] search The string to search for. + def display_filtered_commands(search) + filtered = search_hash(search, visible_commands) + raise CommandError, "No help found for '#{args.first}'" if filtered.empty? + + if filtered.size == 1 + display_command(filtered.values.first) + else + display_index({"'#{search}' commands" => filtered.values}) + end + end + + # Display help for an individual command. + # + # @param [Pry::Command] command + def display_command(command) + _pry_.pager.page command.new.help + end + + # Find a subset of a hash that matches the user's search term. + # + # If there's an exact match a Hash of one element will be returned, + # otherwise a sub-Hash with every key that matches the search will + # be returned. + # + # @param [String] search the search term + # @param [Hash] hash the hash to search + def search_hash(search, hash) + matching = {} + + hash.each_pair do |key, value| + next unless key.is_a?(String) + if normalize(key) == normalize(search) + return {key => value} + elsif normalize(key).start_with?(normalize(search)) + matching[key] = value + end + end + + matching + end + + # Clean search terms to make it easier to search group names + # + # @param [String] key + # @return [String] + def normalize(key) + key.downcase.gsub(/pry\W+/, '') + end + + def group_sort_key(group_name) + [%w(Help Context Editing Introspection Input_and_output Navigating_pry Gems Basic Commands).index(group_name.gsub(' ', '_')) || 99, group_name] + end + end + + Pry::Commands.add_command(Pry::Command::Help) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/hist.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/hist.rb new file mode 100644 index 0000000..083d3f5 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/hist.rb @@ -0,0 +1,180 @@ +class Pry + class Command::Hist < Pry::ClassCommand + match 'hist' + group 'Editing' + description 'Show and replay Readline history.' + + banner <<-'BANNER' + Usage: hist [--head|--tail] + hist --all + hist --head N + hist --tail N + hist --show START..END + hist --grep PATTERN + hist --clear + hist --replay START..END + hist --save [START..END] FILE + Aliases: history + + Show and replay Readline history. + BANNER + + def options(opt) + opt.on :a, :all, "Display all history" + opt.on :H, :head, "Display the first N items", :optional_argument => true, :as => Integer + opt.on :T, :tail, "Display the last N items", :optional_argument => true, :as => Integer + opt.on :s, :show, "Show the given range of lines", :optional_argument => true, :as => Range + opt.on :G, :grep, "Show lines matching the given pattern", :argument => true, :as => String + opt.on :c, :clear , "Clear the current session's history" + opt.on :r, :replay, "Replay a line or range of lines", :argument => true, :as => Range + opt.on :save, "Save history to a file", :argument => true, :as => Range + opt.on :e, :'exclude-pry', "Exclude Pry commands from the history" + opt.on :n, :'no-numbers', "Omit line numbers" + end + + def process + @history = find_history + + if opts.present?(:show) + @history = @history.between(opts[:show]) + end + + if opts.present?(:grep) + @history = @history.grep(opts[:grep]) + end + + @history = case + when opts.present?(:head) + @history.take_lines(1, opts[:head] || 10) + when opts.present?(:tail) + @history.take_lines(-(opts[:tail] || 10), opts[:tail] || 10) + when opts.present?(:show) + @history.between(opts[:show]) + else + @history + end + + if opts.present?(:'exclude-pry') + @history = @history.select do |loc| + !command_set.valid_command?(loc.line) + end + end + + if opts.present?(:save) + process_save + elsif opts.present?(:clear) + process_clear + elsif opts.present?(:replay) + process_replay + else + process_display + end + end + + private + + def process_display + unless opts.present?(:'no-numbers') + @history = @history.with_line_numbers + end + + _pry_.pager.open do |pager| + @history.print_to_output(pager, true) + end + end + + def process_save + case opts[:save] + when Range + @history = @history.between(opts[:save]) + + unless args.first + raise CommandError, "Must provide a file name." + end + + file_name = File.expand_path(args.first) + when String + file_name = File.expand_path(opts[:save]) + end + + output.puts "Saving history in #{file_name}..." + + File.open(file_name, 'w') { |f| f.write(@history.raw) } + + output.puts "History saved." + end + + def process_clear + Pry.history.clear + output.puts "History cleared." + end + + def process_replay + @history = @history.between(opts[:r]) + replay_sequence = @history.raw + + # If we met follow-up "hist" call, check for the "--replay" option + # presence. If "hist" command is called with other options, proceed + # further. + check_for_juxtaposed_replay(replay_sequence) + + replay_sequence.lines.each do |line| + _pry_.eval line, :generated => true + end + end + + # Checks +replay_sequence+ for the presence of neighboring replay calls. + # @example + # [1] pry(main)> hist --show 46894 + # 46894: hist --replay 46675..46677 + # [2] pry(main)> hist --show 46675..46677 + # 46675: 1+1 + # 46676: a = 100 + # 46677: hist --tail + # [3] pry(main)> hist --replay 46894 + # Error: Replay index 46894 points out to another replay call: `hist -r 46675..46677` + # [4] pry(main)> + # + # @raise [Pry::CommandError] If +replay_sequence+ contains another + # "hist --replay" call + # @param [String] replay_sequence The sequence of commands to be replayed + # (per saltum) + # @return [Boolean] `false` if +replay_sequence+ does not contain another + # "hist --replay" call + def check_for_juxtaposed_replay(replay_sequence) + if replay_sequence =~ /\Ahist(?:ory)?\b/ + # Create *fresh* instance of Options for parsing of "hist" command. + _slop = self.slop + _slop.parse replay_sequence.split(' ')[1..-1] + + if _slop.present?(:r) + replay_sequence = replay_sequence.split("\n").join('; ') + index = opts[:r] + index = index.min if index.min == index.max || index.max.nil? + + raise CommandError, "Replay index #{ index } points out to another replay call: `#{ replay_sequence }`" + end + else + false + end + end + + # Finds history depending on the given switch. + # + # @return [Pry::Code] if it finds `--all` (or `-a`) switch, returns all + # entries in history. Without the switch returns only the entries from the + # current Pry session. + def find_history + h = if opts.present?(:all) + Pry.history.to_a + else + Pry.history.to_a.last(Pry.history.session_line_count) + end + # The last value in history will be the 'hist' command itself. + Pry::Code(h[0..-2]) + end + end + + Pry::Commands.add_command(Pry::Command::Hist) + Pry::Commands.alias_command 'history', 'hist' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/import_set.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/import_set.rb new file mode 100644 index 0000000..5689883 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/import_set.rb @@ -0,0 +1,22 @@ +class Pry + class Command::ImportSet < Pry::ClassCommand + match 'import-set' + group 'Commands' + # TODO: Provide a better description with examples and a general conception + # of this command. + description 'Import a Pry command set.' + + banner <<-'BANNER' + Import a Pry command set. + BANNER + + def process(command_set_name) + raise CommandError, "Provide a command set name" if command_set.nil? + + set = target.eval(arg_string) + _pry_.commands.import set + end + end + + Pry::Commands.add_command(Pry::Command::ImportSet) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/install_command.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/install_command.rb new file mode 100644 index 0000000..acafe7b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/install_command.rb @@ -0,0 +1,53 @@ +class Pry + class Command::InstallCommand < Pry::ClassCommand + match 'install-command' + group 'Commands' + description 'Install a disabled command.' + + banner <<-'BANNER' + Usage: install-command COMMAND + + Installs the gems necessary to run the given COMMAND. You will generally not + need to run this unless told to by an error message. + BANNER + + def process(name) + require 'rubygems/dependency_installer' unless defined? Gem::DependencyInstaller + command = find_command(name) + + unless command + output.puts "Command #{ text.green(name) } is not found" + return + end + + if command_dependencies_met?(command.options) + output.puts "Dependencies for #{ text.green(name) } are met. Nothing to do" + return + end + + output.puts "Attempting to install #{ text.green(name) } command..." + gems_to_install = Array(command.options[:requires_gem]) + + gems_to_install.each do |g| + next if Rubygem.installed?(g) + output.puts "Installing #{ text.green(g) } gem..." + Rubygem.install(g) + end + + gems_to_install.each do |g| + begin + require g + rescue LoadError + fail_msg = "Required gem #{ text.green(g) } installed but not found." + fail_msg += " Aborting command installation\n" + fail_msg += 'Tips: 1. Check your PATH; 2. Run `bundle update`' + raise CommandError, fail_msg + end + end + + output.puts "Installation of #{ text.green(name) } successful! Type `help #{name}` for information" + end + end + + Pry::Commands.add_command(Pry::Command::InstallCommand) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/jump_to.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/jump_to.rb new file mode 100644 index 0000000..4179fc7 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/jump_to.rb @@ -0,0 +1,29 @@ +class Pry + class Command::JumpTo < Pry::ClassCommand + match 'jump-to' + group 'Navigating Pry' + description 'Jump to a binding further up the stack.' + + banner <<-'BANNER' + Jump to a binding further up the stack, popping all bindings below. + BANNER + + def process(break_level) + break_level = break_level.to_i + nesting_level = _pry_.binding_stack.size - 1 + + case break_level + when nesting_level + output.puts "Already at nesting level #{nesting_level}" + when (0...nesting_level) + _pry_.binding_stack.slice!(break_level + 1, _pry_.binding_stack.size) + + else + max_nest_level = nesting_level - 1 + output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}." + end + end + end + + Pry::Commands.add_command(Pry::Command::JumpTo) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_inspectors.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_inspectors.rb new file mode 100644 index 0000000..c96c395 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_inspectors.rb @@ -0,0 +1,35 @@ +class Pry::Command::ListInspectors < Pry::ClassCommand + match 'list-inspectors' + group 'Input and Output' + description 'List the inspector procs available for use.' + banner <<-BANNER + Usage: list-inspectors + + List the inspector procs available to print return values. You can use + change-inspector to switch between them. + BANNER + + def process + output.puts heading("Available inspectors") + "\n" + inspector_map.each do |name, inspector| + output.write "Name: #{text.bold(name)}" + output.puts selected_inspector?(inspector) ? selected_text : "" + output.puts inspector[:description] + output.puts + end + end + +private + def inspector_map + Pry::Inspector::MAP + end + + def selected_text + text.red " (selected) " + end + + def selected_inspector?(inspector) + _pry_.print == inspector[:value] + end + Pry::Commands.add_command(self) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_prompts.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_prompts.rb new file mode 100644 index 0000000..436f719 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/list_prompts.rb @@ -0,0 +1,35 @@ +class Pry::Command::ListPrompts < Pry::ClassCommand + match 'list-prompts' + group 'Input and Output' + description 'List the prompts available for use.' + banner <<-BANNER + Usage: list-prompts + + List the available prompts. You can use change-prompt to switch between + them. + BANNER + + def process + output.puts heading("Available prompts") + "\n" + prompt_map.each do |name, prompt| + output.write "Name: #{text.bold(name)}" + output.puts selected_prompt?(prompt) ? selected_text : "" + output.puts prompt[:description] + output.puts + end + end + +private + def prompt_map + Pry::Prompt::MAP + end + + def selected_text + text.red " (selected) " + end + + def selected_prompt?(prompt) + _pry_.prompt == prompt[:value] + end + Pry::Commands.add_command(self) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls.rb new file mode 100644 index 0000000..9f0e68f --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls.rb @@ -0,0 +1,114 @@ +require 'pry/commands/ls/ls_entity' +class Pry + class Command::Ls < Pry::ClassCommand + DEFAULT_OPTIONS = { + :heading_color => :bright_blue, + :public_method_color => :default, + :private_method_color => :blue, + :protected_method_color => :blue, + :method_missing_color => :bright_red, + :local_var_color => :yellow, + :pry_var_color => :default, # e.g. _, _pry_, _file_ + :instance_var_color => :blue, # e.g. @foo + :class_var_color => :bright_blue, # e.g. @@foo + :global_var_color => :default, # e.g. $CODERAY_DEBUG, $eventmachine_library + :builtin_global_color => :cyan, # e.g. $stdin, $-w, $PID + :pseudo_global_color => :cyan, # e.g. $~, $1..$9, $LAST_MATCH_INFO + :constant_color => :default, # e.g. VERSION, ARGF + :class_constant_color => :blue, # e.g. Object, Kernel + :exception_constant_color => :magenta, # e.g. Exception, RuntimeError + :unloaded_constant_color => :yellow, # Any constant that is still in .autoload? state + :separator => " ", + :ceiling => [Object, Module, Class] + } + + + match 'ls' + group 'Context' + description 'Show the list of vars and methods in the current scope.' + command_options :shellwords => false, :interpolate => false + + banner <<-'BANNER' + Usage: ls [-m|-M|-p|-pM] [-q|-v] [-c|-i] [Object] + ls [-g] [-l] + + ls shows you which methods, constants and variables are accessible to Pry. By + default it shows you the local variables defined in the current shell, and any + public methods or instance variables defined on the current object. + + The colours used are configurable using Pry.config.ls.*_color, and the separator + is Pry.config.ls.separator. + + Pry.config.ls.ceiling is used to hide methods defined higher up in the + inheritance chain, this is by default set to [Object, Module, Class] so that + methods defined on all Objects are omitted. The -v flag can be used to ignore + this setting and show all methods, while the -q can be used to set the ceiling + much lower and show only methods defined on the object or its direct class. + + Also check out `find-method` command (run `help find-method`). + BANNER + + + def options(opt) + opt.on :m, :methods, "Show public methods defined on the Object" + opt.on :M, "instance-methods", "Show public methods defined in a Module or Class" + opt.on :p, :ppp, "Show public, protected (in yellow) and private (in green) methods" + opt.on :q, :quiet, "Show only methods defined on object.singleton_class and object.class" + opt.on :v, :verbose, "Show methods and constants on all super-classes (ignores Pry.config.ls.ceiling)" + opt.on :g, :globals, "Show global variables, including those builtin to Ruby (in cyan)" + opt.on :l, :locals, "Show hash of local vars, sorted by descending size" + opt.on :c, :constants, "Show constants, highlighting classes (in blue), and exceptions (in purple).\n" << + " " * 32 << "Constants that are pending autoload? are also shown (in yellow)" + opt.on :i, :ivars, "Show instance variables (in blue) and class variables (in bright blue)" + opt.on :G, :grep, "Filter output by regular expression", :argument => true + + if jruby? + opt.on :J, "all-java", "Show all the aliases for methods from java (default is to show only prettiest)" + end + end + + # Exclude -q, -v and --grep because they, + # don't specify what the user wants to see. + def no_user_opts? + !(opts[:methods] || opts['instance-methods'] || opts[:ppp] || + opts[:globals] || opts[:locals] || opts[:constants] || opts[:ivars]) + end + + def process + @interrogatee = args.empty? ? target_self : target.eval(args.join(' ')) + raise_errors_if_arguments_are_weird + ls_entity = LsEntity.new({ + :interrogatee => @interrogatee, + :no_user_opts => no_user_opts?, + :opts => opts, + :args => args, + :_pry_ => _pry_ + }) + + _pry_.pager.page ls_entity.entities_table + end + + private + + def error_list + any_args = args.any? + non_mod_interrogatee = !(Module === @interrogatee) + [ + ['-l does not make sense with a specified Object', :locals, any_args], + ['-g does not make sense with a specified Object', :globals, any_args], + ['-q does not make sense with -v', :quiet, opts.present?(:verbose)], + ['-M only makes sense with a Module or a Class', 'instance-methods', non_mod_interrogatee], + ['-c only makes sense with a Module or a Class', :constants, any_args && non_mod_interrogatee] + ] + end + + def raise_errors_if_arguments_are_weird + error_list.each do |message, option, invalid_expr| + raise Pry::CommandError, message if opts.present?(option) && invalid_expr + end + end + + end + + Pry::Commands.add_command(Pry::Command::Ls) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/constants.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/constants.rb new file mode 100644 index 0000000..3db8162 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/constants.rb @@ -0,0 +1,47 @@ +require 'pry/commands/ls/interrogatable' + +class Pry + class Command::Ls < Pry::ClassCommand + class Constants < Pry::Command::Ls::Formatter + include Pry::Command::Ls::Interrogatable + + + def initialize(interrogatee, no_user_opts, opts, _pry_) + super(_pry_) + @interrogatee = interrogatee + @no_user_opts = no_user_opts + @default_switch = opts[:constants] + @verbose_switch = opts[:verbose] + end + + def correct_opts? + super || (@no_user_opts && interrogating_a_module?) + end + + def output_self + mod = interrogatee_mod + constants = WrappedModule.new(mod).constants(@verbose_switch) + output_section('constants', grep.regexp[format(mod, constants)]) + end + + private + + def format(mod, constants) + constants.sort_by(&:downcase).map do |name| + if const = (!mod.autoload?(name) && (mod.const_get(name) || true) rescue nil) + if (const < Exception rescue false) + color(:exception_constant, name) + elsif (Module === mod.const_get(name) rescue false) + color(:class_constant, name) + else + color(:constant, name) + end + else + color(:unloaded_constant, name) + end + end + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/formatter.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/formatter.rb new file mode 100644 index 0000000..844a220 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/formatter.rb @@ -0,0 +1,49 @@ +class Pry + class Command::Ls < Pry::ClassCommand + class Formatter + attr_accessor :grep + attr_reader :_pry_ + + def initialize(_pry_) + @_pry_ = _pry_ + @target = _pry_.current_context + end + + def write_out + return false unless correct_opts? + output_self + end + + private + + def color(type, str) + Pry::Helpers::Text.send _pry_.config.ls["#{type}_color"], str + end + + # Add a new section to the output. + # Outputs nothing if the section would be empty. + def output_section(heading, body) + return '' if body.compact.empty? + fancy_heading = Pry::Helpers::Text.bold(color(:heading, heading)) + Pry::Helpers.tablify_or_one_line(fancy_heading, body) + end + + def format_value(value) + Pry::ColorPrinter.pp(value, '') + end + + def correct_opts? + @default_switch + end + + def output_self + raise NotImplementedError + end + + def grep + @grep || proc { |x| x } + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/globals.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/globals.rb new file mode 100644 index 0000000..2b3d0fd --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/globals.rb @@ -0,0 +1,48 @@ +class Pry + class Command::Ls < Pry::ClassCommand + class Globals < Pry::Command::Ls::Formatter + + # Taken from "puts global_variables.inspect". + BUILTIN_GLOBALS = + %w($" $$ $* $, $-0 $-F $-I $-K $-W $-a $-d $-i $-l $-p $-v $-w $. $/ $\\ + $: $; $< $= $> $0 $ARGV $CONSOLE $DEBUG $DEFAULT_INPUT $DEFAULT_OUTPUT + $FIELD_SEPARATOR $FILENAME $FS $IGNORECASE $INPUT_LINE_NUMBER + $INPUT_RECORD_SEPARATOR $KCODE $LOADED_FEATURES $LOAD_PATH $NR $OFS + $ORS $OUTPUT_FIELD_SEPARATOR $OUTPUT_RECORD_SEPARATOR $PID $PROCESS_ID + $PROGRAM_NAME $RS $VERBOSE $deferr $defout $stderr $stdin $stdout) + + # `$SAFE` and `$?` are thread-local, the exception stuff only works in a + # rescue clause, everything else is basically a local variable with a `$` + # in its name. + PSEUDO_GLOBALS = + %w($! $' $& $` $@ $? $+ $_ $~ $1 $2 $3 $4 $5 $6 $7 $8 $9 + $CHILD_STATUS $SAFE $ERROR_INFO $ERROR_POSITION $LAST_MATCH_INFO + $LAST_PAREN_MATCH $LAST_READ_LINE $MATCH $POSTMATCH $PREMATCH) + + def initialize(opts, _pry_) + super(_pry_) + @default_switch = opts[:globals] + end + + def output_self + variables = format(@target.eval('global_variables')) + output_section('global variables', grep.regexp[variables]) + end + + private + + def format(globals) + globals.map(&:to_s).sort_by(&:downcase).map do |name| + if PSEUDO_GLOBALS.include?(name) + color(:pseudo_global, name) + elsif BUILTIN_GLOBALS.include?(name) + color(:builtin_global, name) + else + color(:global_var, name) + end + end + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/grep.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/grep.rb new file mode 100644 index 0000000..14e6b00 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/grep.rb @@ -0,0 +1,21 @@ +class Pry + class Command::Ls < Pry::ClassCommand + class Grep + + def initialize(grep_regexp) + @grep_regexp = grep_regexp + end + + def regexp + proc { |x| + if x.instance_of?(Array) + x.grep(@grep_regexp) + else + x =~ @grep_regexp + end + } + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/instance_vars.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/instance_vars.rb new file mode 100644 index 0000000..2f33677 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/instance_vars.rb @@ -0,0 +1,39 @@ +require 'pry/commands/ls/interrogatable' + +class Pry + class Command::Ls < Pry::ClassCommand + class InstanceVars < Pry::Command::Ls::Formatter + include Pry::Command::Ls::Interrogatable + + def initialize(interrogatee, no_user_opts, opts, _pry_) + super(_pry_) + @interrogatee = interrogatee + @no_user_opts = no_user_opts + @default_switch = opts[:ivars] + end + + def correct_opts? + super || @no_user_opts + end + + def output_self + ivars = if Object === @interrogatee + Pry::Method.safe_send(@interrogatee, :instance_variables) + else + [] #TODO: BasicObject support + end + kvars = Pry::Method.safe_send(interrogatee_mod, :class_variables) + ivars_out = output_section('instance variables', format(:instance_var, ivars)) + kvars_out = output_section('class variables', format(:class_var, kvars)) + ivars_out + kvars_out + end + + private + + def format(type, vars) + vars.sort_by { |var| var.to_s.downcase }.map { |var| color(type, var) } + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/interrogatable.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/interrogatable.rb new file mode 100644 index 0000000..5904d1b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/interrogatable.rb @@ -0,0 +1,18 @@ +module Pry::Command::Ls::Interrogatable + + private + + def interrogating_a_module? + Module === @interrogatee + end + + def interrogatee_mod + if interrogating_a_module? + @interrogatee + else + singleton = Pry::Method.singleton_class_of(@interrogatee) + singleton.ancestors.grep(::Class).reject { |c| c == singleton }.first + end + end + +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/jruby_hacks.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/jruby_hacks.rb new file mode 100644 index 0000000..0f73e08 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/jruby_hacks.rb @@ -0,0 +1,49 @@ +module Pry::Command::Ls::JRubyHacks + + private + + # JRuby creates lots of aliases for methods imported from java in an attempt + # to make life easier for ruby programmers. (e.g. getFooBar becomes + # get_foo_bar and foo_bar, and maybe foo_bar? if it returns a Boolean). The + # full transformations are in the assignAliases method of: + # https://github.com/jruby/jruby/blob/master/src/org/jruby/javasupport/JavaClass.java + # + # This has the unfortunate side-effect of making the output of ls even more + # incredibly verbose than it normally would be for these objects; and so we + # filter out all but the nicest of these aliases here. + # + # TODO: This is a little bit vague, better heuristics could be used. + # JRuby also has a lot of scala-specific logic, which we don't copy. + def trim_jruby_aliases(methods) + grouped = methods.group_by do |m| + m.name.sub(/\A(is|get|set)(?=[A-Z_])/, '').gsub(/[_?=]/, '').downcase + end + + grouped.map do |key, values| + values = values.sort_by do |m| + rubbishness(m.name) + end + + found = [] + values.select do |x| + (!found.any? { |y| x == y }) && found << x + end + end.flatten(1) + end + + # When removing jruby aliases, we want to keep the alias that is + # "least rubbish" according to this metric. + def rubbishness(name) + name.each_char.map { |x| + case x + when /[A-Z]/ + 1 + when '?', '=', '!' + -2 + else + 0 + end + }.inject(&:+) + (name.size / 100.0) + end + +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_names.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_names.rb new file mode 100644 index 0000000..9d6350b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_names.rb @@ -0,0 +1,35 @@ +class Pry + class Command::Ls < Pry::ClassCommand + class LocalNames < Pry::Command::Ls::Formatter + + def initialize(no_user_opts, args, _pry_) + super(_pry_) + @no_user_opts = no_user_opts + @args = args + @sticky_locals = _pry_.sticky_locals + end + + def correct_opts? + super || (@no_user_opts && @args.empty?) + end + + def output_self + local_vars = grep.regexp[@target.eval('local_variables')] + output_section('locals', format(local_vars)) + end + + private + + def format(locals) + locals.sort_by(&:downcase).map do |name| + if @sticky_locals.include?(name.to_sym) + color(:pry_var, name) + else + color(:local_var, name) + end + end + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_vars.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_vars.rb new file mode 100644 index 0000000..d48ddae --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/local_vars.rb @@ -0,0 +1,39 @@ +class Pry + class Command::Ls < Pry::ClassCommand + class LocalVars < Pry::Command::Ls::Formatter + + def initialize(opts, _pry_) + super(_pry_) + @default_switch = opts[:locals] + @sticky_locals = _pry_.sticky_locals + end + + def output_self + name_value_pairs = @target.eval('local_variables').reject { |e| + @sticky_locals.keys.include?(e.to_sym) + }.map { |name| + [name, (@target.eval(name.to_s))] + } + format(name_value_pairs).join('') + end + + private + + def format(name_value_pairs) + name_value_pairs.sort_by { |name, value| + value.to_s.size + }.reverse.map { |name, value| + colorized_assignment_style(name, format_value(value)) + } + end + + def colorized_assignment_style(lhs, rhs, desired_width = 7) + colorized_lhs = color(:local_var, lhs) + color_escape_padding = colorized_lhs.size - lhs.size + pad = desired_width + color_escape_padding + "%-#{pad}s = %s" % [color(:local_var, colorized_lhs), rhs] + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/ls_entity.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/ls_entity.rb new file mode 100644 index 0000000..3d69bcd --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/ls_entity.rb @@ -0,0 +1,70 @@ +require 'pry/commands/ls/grep' +require 'pry/commands/ls/formatter' +require 'pry/commands/ls/globals' +require 'pry/commands/ls/constants' +require 'pry/commands/ls/methods' +require 'pry/commands/ls/self_methods' +require 'pry/commands/ls/instance_vars' +require 'pry/commands/ls/local_names' +require 'pry/commands/ls/local_vars' + +class Pry + class Command::Ls < Pry::ClassCommand + + class LsEntity + attr_reader :_pry_ + + def initialize(opts) + @interrogatee = opts[:interrogatee] + @no_user_opts = opts[:no_user_opts] + @opts = opts[:opts] + @args = opts[:args] + @grep = Grep.new(Regexp.new(opts[:opts][:G] || '.')) + @_pry_ = opts.delete(:_pry_) + end + + def entities_table + entities.map(&:write_out).reject { |o| !o }.join('') + end + + private + + def grep(entity) + entity.tap { |o| o.grep = @grep } + end + + def globals + grep Globals.new(@opts, _pry_) + end + + def constants + grep Constants.new(@interrogatee, @no_user_opts, @opts, _pry_) + end + + def methods + grep(Methods.new(@interrogatee, @no_user_opts, @opts, _pry_)) + end + + def self_methods + grep SelfMethods.new(@interrogatee, @no_user_opts, @opts, _pry_) + end + + def instance_vars + grep InstanceVars.new(@interrogatee, @no_user_opts, @opts, _pry_) + end + + def local_names + grep LocalNames.new(@no_user_opts, @args, _pry_) + end + + def local_vars + LocalVars.new(@opts, _pry_) + end + + def entities + [globals, constants, methods, self_methods, instance_vars, local_names, + local_vars] + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods.rb new file mode 100644 index 0000000..c085f42 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods.rb @@ -0,0 +1,57 @@ +require 'pry/commands/ls/methods_helper' +require 'pry/commands/ls/interrogatable' + +class Pry + class Command::Ls < Pry::ClassCommand + class Methods < Pry::Command::Ls::Formatter + + include Pry::Command::Ls::Interrogatable + include Pry::Command::Ls::MethodsHelper + + def initialize(interrogatee, no_user_opts, opts, _pry_) + super(_pry_) + @interrogatee = interrogatee + @no_user_opts = no_user_opts + @default_switch = opts[:methods] + @instance_methods_switch = opts['instance-methods'] + @ppp_switch = opts[:ppp] + @jruby_switch = opts['all-java'] + @quiet_switch = opts[:quiet] + @verbose_switch = opts[:verbose] + end + + def output_self + methods = all_methods.group_by(&:owner) + # Reverse the resolution order so that the most useful information + # appears right by the prompt. + resolution_order.take_while(&below_ceiling).reverse.map do |klass| + methods_here = (methods[klass] || []).select { |m| grep.regexp[m.name] } + heading = "#{ Pry::WrappedModule.new(klass).method_prefix }methods" + output_section(heading, format(methods_here)) + end.join('') + end + + private + + def correct_opts? + super || @instance_methods_switch || @ppp_switch || @no_user_opts + end + + + # Get a lambda that can be used with `take_while` to prevent over-eager + # traversal of the Object's ancestry graph. + def below_ceiling + ceiling = if @quiet_switch + [Pry::Method.safe_send(interrogatee_mod, :ancestors)[1]] + + _pry_.config.ls.ceiling + elsif @verbose_switch + [] + else + _pry_.config.ls.ceiling.dup + end + lambda { |klass| !ceiling.include?(klass) } + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods_helper.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods_helper.rb new file mode 100644 index 0000000..f0b4414 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/methods_helper.rb @@ -0,0 +1,46 @@ +require 'pry/commands/ls/jruby_hacks' + +module Pry::Command::Ls::MethodsHelper + + include Pry::Command::Ls::JRubyHacks + + private + + # Get all the methods that we'll want to output. + def all_methods(instance_methods = false) + methods = if instance_methods || @instance_methods_switch + Pry::Method.all_from_class(@interrogatee) + else + Pry::Method.all_from_obj(@interrogatee) + end + + if Pry::Helpers::BaseHelpers.jruby? && !@jruby_switch + methods = trim_jruby_aliases(methods) + end + + methods.select { |method| @ppp_switch || method.visibility == :public } + end + + def resolution_order + if @instance_methods_switch + Pry::Method.instance_resolution_order(@interrogatee) + else + Pry::Method.resolution_order(@interrogatee) + end + end + + def format(methods) + methods.sort_by(&:name).map do |method| + if method.name == 'method_missing' + color(:method_missing, 'method_missing') + elsif method.visibility == :private + color(:private_method, method.name) + elsif method.visibility == :protected + color(:protected_method, method.name) + else + color(:public_method, method.name) + end + end + end + +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/self_methods.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/self_methods.rb new file mode 100644 index 0000000..91f3490 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ls/self_methods.rb @@ -0,0 +1,32 @@ +require 'pry/commands/ls/interrogatable' +require 'pry/commands/ls/methods_helper' + +class Pry + class Command::Ls < Pry::ClassCommand + class SelfMethods < Pry::Command::Ls::Formatter + include Pry::Command::Ls::Interrogatable + include Pry::Command::Ls::MethodsHelper + + def initialize(interrogatee, no_user_opts, opts, _pry_) + super(_pry_) + @interrogatee = interrogatee + @no_user_opts = no_user_opts + end + + def output_self + methods = all_methods(true).select do |m| + m.owner == @interrogatee && grep.regexp[m.name] + end + heading = "#{ Pry::WrappedModule.new(@interrogatee).method_prefix }methods" + output_section(heading, format(methods)) + end + + private + + def correct_opts? + @no_user_opts && interrogating_a_module? + end + + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/nesting.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/nesting.rb new file mode 100644 index 0000000..f9c0297 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/nesting.rb @@ -0,0 +1,25 @@ +class Pry + class Command::Nesting < Pry::ClassCommand + match 'nesting' + group 'Navigating Pry' + description 'Show nesting information.' + + banner <<-'BANNER' + Show nesting information. + BANNER + + def process + output.puts 'Nesting status:' + output.puts '--' + _pry_.binding_stack.each_with_index do |obj, level| + if level == 0 + output.puts "#{level}. #{Pry.view_clip(obj.eval('self'))} (Pry top level)" + else + output.puts "#{level}. #{Pry.view_clip(obj.eval('self'))}" + end + end + end + end + + Pry::Commands.add_command(Pry::Command::Nesting) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/play.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/play.rb new file mode 100644 index 0000000..5498d38 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/play.rb @@ -0,0 +1,103 @@ +class Pry + class Command::Play < Pry::ClassCommand + match 'play' + group 'Editing' + description 'Playback a string variable, method, line, or file as input.' + + banner <<-'BANNER' + Usage: play [OPTIONS] [--help] + + The play command enables you to replay code from files and methods as if they + were entered directly in the Pry REPL. + + play --lines 149..153 # assumes current context + play -i 20 --lines 1..3 # assumes lines of the input expression at 20 + play -o 4 # the output of of an expression at 4 + play Pry#repl -l 1..-1 # play the contents of Pry#repl method + play -e 2 # play from specified line until end of valid expression + play hello.rb # play a file + play Rakefile -l 5 # play line 5 of a file + play -d hi # play documentation of hi method + play hi --open # play hi method and leave it open + + https://github.com/pry/pry/wiki/User-Input#wiki-Play + BANNER + + def options(opt) + CodeCollector.inject_options(opt) + + opt.on :open, 'Plays the selected content except the last line. Useful' \ + ' for replaying methods and leaving the method definition' \ + ' "open". `amend-line` can then be used to' \ + ' modify the method.' + + opt.on :e, :expression=, 'Executes until end of valid expression', :as => Integer + opt.on :p, :print, 'Prints executed code' + end + + def process + @cc = CodeCollector.new(args, opts, _pry_) + + perform_play + show_input + end + + def perform_play + eval_string << content_after_options + run "fix-indent" + end + + def show_input + if opts.present?(:print) or !Pry::Code.complete_expression?(eval_string) + run "show-input" + end + end + + + def content_after_options + if opts.present?(:open) + restrict_to_lines(content, (0..-2)) + elsif opts.present?(:expression) + content_at_expression + else + content + end + end + + def content_at_expression + code_object.expression_at(opts[:expression]) + end + + def code_object + Pry::Code.new(content) + end + + def should_use_default_file? + !args.first && !opts.present?(:in) && !opts.present?(:out) + end + + def content + if should_use_default_file? + file_content + else + @cc.content + end + end + + # The file to play from when no code object is specified. + # e.g `play --lines 4..10` + def default_file + target.eval("__FILE__") && File.expand_path(target.eval("__FILE__")) + end + + def file_content + if default_file && File.exists?(default_file) + @cc.restrict_to_lines(File.read(default_file), @cc.line_range) + else + raise CommandError, "File does not exist! File was: #{default_file.inspect}" + end + end + end + + Pry::Commands.add_command(Pry::Command::Play) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_backtrace.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_backtrace.rb new file mode 100644 index 0000000..6795aa3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_backtrace.rb @@ -0,0 +1,25 @@ +class Pry + class Command::PryBacktrace < Pry::ClassCommand + match 'pry-backtrace' + group 'Context' + description 'Show the backtrace for the Pry session.' + + banner <<-BANNER + Usage: pry-backtrace [OPTIONS] [--help] + + Show the backtrace for the position in the code where Pry was started. This can + be used to infer the behavior of the program immediately before it entered Pry, + just like the backtrace property of an exception. + + NOTE: if you are looking for the backtrace of the most recent exception raised, + just type: `_ex_.backtrace` instead. + See: https://github.com/pry/pry/wiki/Special-Locals + BANNER + + def process + _pry_.pager.page text.bold('Backtrace:') << "\n--\n" << _pry_.backtrace.join("\n") + end + end + + Pry::Commands.add_command(Pry::Command::PryBacktrace) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_version.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_version.rb new file mode 100644 index 0000000..8cb8fd8 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/pry_version.rb @@ -0,0 +1,17 @@ +class Pry + class Command::Version < Pry::ClassCommand + match 'pry-version' + group 'Misc' + description 'Show Pry version.' + + banner <<-'BANNER' + Show Pry version. + BANNER + + def process + output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}." + end + end + + Pry::Commands.add_command(Pry::Command::Version) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/raise_up.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/raise_up.rb new file mode 100644 index 0000000..70ad087 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/raise_up.rb @@ -0,0 +1,32 @@ +class Pry + # N.B. using a regular expresion here so that "raise-up 'foo'" does the right thing. + class Command::RaiseUp < Pry::ClassCommand + match(/raise-up(!?\b.*)/) + group 'Context' + description 'Raise an exception out of the current pry instance.' + command_options :listing => 'raise-up' + + banner <<-BANNER + Raise up, like exit, allows you to quit pry. Instead of returning a value + however, it raises an exception. If you don't provide the exception to be + raised, it will use the most recent exception (in pry `_ex_`). + + When called as raise-up! (with an exclamation mark), this command raises the + exception through any nested prys you have created by "cd"ing into objects. + + raise-up "get-me-out-of-here" + + # This is equivalent to the command above. + raise "get-me-out-of-here" + raise-up + BANNER + + def process + return _pry.pager.page help if captures[0] =~ /(-h|--help)\b/ + # Handle 'raise-up', 'raise-up "foo"', 'raise-up RuntimeError, 'farble' in a rubyesque manner + target.eval("_pry_.raise_up#{captures[0]}") + end + end + + Pry::Commands.add_command(Pry::Command::RaiseUp) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reload_code.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reload_code.rb new file mode 100644 index 0000000..7041338 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reload_code.rb @@ -0,0 +1,62 @@ +class Pry + class Command::ReloadCode < Pry::ClassCommand + match 'reload-code' + group 'Misc' + description 'Reload the source file that contains the specified code object.' + + banner <<-'BANNER' + Reload the source file that contains the specified code object. + + e.g reload-code MyClass#my_method #=> reload a method + reload-code MyClass #=> reload a class + reload-code my-command #=> reload a pry command + reload-code self #=> reload the current object + reload-code #=> reload the current file or object + BANNER + + def process + if !args.empty? + reload_object(args.join(" ")) + elsif internal_binding?(target) + reload_object("self") + else + reload_current_file + end + end + + private + + def current_file + File.expand_path target.eval("__FILE__") + end + + def reload_current_file + if !File.exists?(current_file) + raise CommandError, "Current file: #{current_file} cannot be found on disk!" + end + + load current_file + output.puts "The current file: #{current_file} was reloaded!" + end + + def reload_object(identifier) + code_object = Pry::CodeObject.lookup(identifier, _pry_) + check_for_reloadability(code_object, identifier) + load code_object.source_file + output.puts "#{identifier} was reloaded!" + end + + def check_for_reloadability(code_object, identifier) + if !code_object || !code_object.source_file + raise CommandError, "Cannot locate #{identifier}!" + elsif !File.exists?(code_object.source_file) + raise CommandError, + "Cannot reload #{identifier} as it has no associated file on disk. " \ + "File found was: #{code_object.source_file}" + end + end + end + + Pry::Commands.add_command(Pry::Command::ReloadCode) + Pry::Commands.alias_command 'reload-method', 'reload-code' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reset.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reset.rb new file mode 100644 index 0000000..4414cbb --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/reset.rb @@ -0,0 +1,18 @@ +class Pry + class Command::Reset < Pry::ClassCommand + match 'reset' + group 'Context' + description 'Reset the REPL to a clean state.' + + banner <<-'BANNER' + Reset the REPL to a clean state. + BANNER + + def process + output.puts 'Pry reset.' + exec 'pry' + end + end + + Pry::Commands.add_command(Pry::Command::Reset) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ri.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ri.rb new file mode 100644 index 0000000..d29c426 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/ri.rb @@ -0,0 +1,60 @@ +class Pry + class Command::Ri < Pry::ClassCommand + match 'ri' + group 'Introspection' + description 'View ri documentation.' + + banner <<-'BANNER' + Usage: ri [spec] + + View ri documentation. Relies on the "rdoc" gem being installed. + See also "show-doc" command. + + ri Array#each + BANNER + + def process(spec) + # Lazily load RI + require 'rdoc/ri/driver' + + unless defined? RDoc::RI::PryDriver + + # Subclass RI so that it formats its output nicely, and uses `lesspipe`. + subclass = Class.new(RDoc::RI::Driver) # the hard way. + + subclass.class_eval do + def initialize(pager, opts) + @pager = pager + super opts + end + def page + paging_text = StringIO.new + yield paging_text + @pager.page(paging_text.string) + end + + def formatter(io) + if @formatter_klass + @formatter_klass.new + else + RDoc::Markup::ToAnsi.new + end + end + end + + RDoc::RI.const_set :PryDriver, subclass # hook it up! + end + + # Spin-up an RI insance. + ri = RDoc::RI::PryDriver.new _pry_.pager, :use_stdout => true, :interactive => false + + begin + ri.display_names [spec] # Get the documentation (finally!) + rescue RDoc::RI::Driver::NotFoundError => e + output.puts "error: '#{e.name}' not found" + end + end + end + + Pry::Commands.add_command(Pry::Command::Ri) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/save_file.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/save_file.rb new file mode 100644 index 0000000..d22a692 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/save_file.rb @@ -0,0 +1,61 @@ +require 'pry/commands/code_collector' + +class Pry + class Command::SaveFile < Pry::ClassCommand + match 'save-file' + group 'Input and Output' + description 'Export to a file using content from the REPL.' + + banner <<-'BANNER' + Usage: save-file [OPTIONS] --to [FILE] + + Export to a file using content from the REPL. + + save-file my_method --to hello.rb + save-file -i 1..10 --to hello.rb --append + save-file show-method --to my_command.rb + save-file sample_file.rb --lines 2..10 --to output_file.rb + BANNER + + def options(opt) + CodeCollector.inject_options(opt) + + opt.on :to=, "Specify the output file path" + opt.on :a, :append, "Append output to file" + end + + def process + @cc = CodeCollector.new(args, opts, _pry_) + raise CommandError, "Found no code to save." if @cc.content.empty? + + if !file_name + display_content + else + save_file + end + end + + def file_name + opts[:to] || nil + end + + def save_file + File.open(file_name, mode) do |f| + f.puts @cc.content + end + output.puts "#{file_name} successfully saved" + end + + def display_content + output.puts @cc.content + output.puts "\n\n--\nPlease use `--to FILE` to export to a file." + output.puts "No file saved!\n--" + end + + def mode + opts.present?(:append) ? "a" : "w" + end + end + + Pry::Commands.add_command(Pry::Command::SaveFile) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_command.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_command.rb new file mode 100644 index 0000000..78fccd5 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_command.rb @@ -0,0 +1,48 @@ +class Pry + class Command::ShellCommand < Pry::ClassCommand + match(/\.(.*)/) + group 'Input and Output' + description "All text following a '.' is forwarded to the shell." + command_options :listing => '.', :use_prefix => false, + :takes_block => true + + banner <<-'BANNER' + Usage: .COMMAND_NAME + + All text following a "." is forwarded to the shell. + + .ls -aF + .uname + BANNER + + def process(cmd) + if cmd =~ /^cd\s*(.*)/i + process_cd parse_destination($1) + else + pass_block(cmd) + if command_block + command_block.call `#{cmd}` + else + _pry_.config.system.call(output, cmd, _pry_) + end + end + end + + private + + def parse_destination(dest) + return "~" if dest.empty? + return dest unless dest == "-" + state.old_pwd || raise(CommandError, "No prior directory available") + end + + def process_cd(dest) + state.old_pwd = Dir.pwd + Dir.chdir File.expand_path(dest) + rescue Errno::ENOENT + raise CommandError, "No such directory: #{dest}" + end + end + + Pry::Commands.add_command(Pry::Command::ShellCommand) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_mode.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_mode.rb new file mode 100644 index 0000000..ee521d3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/shell_mode.rb @@ -0,0 +1,25 @@ +class Pry + class Command::ShellMode < Pry::ClassCommand + match 'shell-mode' + group 'Input and Output' + description 'Toggle shell mode. Bring in pwd prompt and file completion.' + + banner <<-'BANNER' + Toggle shell mode. Bring in pwd prompt and file completion. + BANNER + + def process + case _pry_.prompt + when Pry::SHELL_PROMPT + _pry_.pop_prompt + _pry_.custom_completions = _pry_.config.file_completions + else + _pry_.push_prompt Pry::SHELL_PROMPT + _pry_.custom_completions = _pry_.config.command_completions + end + end + end + + Pry::Commands.add_command(Pry::Command::ShellMode) + Pry::Commands.alias_command 'file-mode', 'shell-mode' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_doc.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_doc.rb new file mode 100644 index 0000000..4969bcd --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_doc.rb @@ -0,0 +1,83 @@ +require 'pry/commands/show_info' + +class Pry + class Command::ShowDoc < Command::ShowInfo + include Pry::Helpers::DocumentationHelpers + + match 'show-doc' + group 'Introspection' + description 'Show the documentation for a method or class.' + + banner <<-BANNER + Usage: show-doc [OPTIONS] [METH] + Aliases: ? + + Show the documentation for a method or class. Tries instance methods first and + then methods by default. + + show-doc hi_method # docs for hi_method + show-doc Pry # for Pry class + show-doc Pry -a # for all definitions of Pry class (all monkey patches) + BANNER + + # The docs for code_object prepared for display. + def content_for(code_object) + Code.new(render_doc_markup_for(code_object), + start_line_for(code_object), :text). + with_line_numbers(use_line_numbers?).to_s + end + + # process the markup (if necessary) and apply colors + def render_doc_markup_for(code_object) + docs = docs_for(code_object) + + if code_object.command? + # command '--help' shouldn't use markup highlighting + docs + else + if docs.empty? + raise CommandError, "No docs found for: #{ + obj_name ? obj_name : 'current context' + }" + end + process_comment_markup(docs) + end + end + + # Return docs for the code_object, adjusting for whether the code_object + # has yard docs available, in which case it returns those. + # (note we only have to check yard docs for modules since they can + # have multiple docs, but methods can only be doc'd once so we + # dont need to check them) + def docs_for(code_object) + if code_object.module_with_yard_docs? + # yard docs + code_object.yard_doc + else + # normal docs (i.e comments above method/module/command) + code_object.doc + end + end + + # Which sections to include in the 'header', can toggle: :owner, + # :signature and visibility. + def header_options + super.merge :signature => true + end + + # figure out start line of docs by back-calculating based on + # number of lines in the comment and the start line of the code_object + # @return [Fixnum] start line of docs + def start_line_for(code_object) + if code_object.command? || opts.present?(:'base-one') + 1 + else + code_object.source_line.nil? ? 1 : + (code_object.source_line - code_object.doc.lines.count) + end + end + end + + Pry::Commands.add_command(Pry::Command::ShowDoc) + Pry::Commands.alias_command '?', 'show-doc' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_info.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_info.rb new file mode 100644 index 0000000..92958cb --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_info.rb @@ -0,0 +1,195 @@ +class Pry + class Command::ShowInfo < Pry::ClassCommand + extend Pry::Helpers::BaseHelpers + + command_options :shellwords => false, :interpolate => false + + def options(opt) + opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors", :as => :count + opt.on :l, "line-numbers", "Show line numbers" + opt.on :b, "base-one", "Show line numbers but start numbering at 1 (useful for `amend-line` and `play` commands)" + opt.on :a, :all, "Show all definitions and monkeypatches of the module/class" + end + + def process + code_object = Pry::CodeObject.lookup(obj_name, _pry_, :super => opts[:super]) + raise CommandError, no_definition_message if !code_object + @original_code_object = code_object + + if show_all_modules?(code_object) + # show all monkey patches for a module + + result = content_and_headers_for_all_module_candidates(code_object) + else + # show a specific code object + co = code_object_with_accessible_source(code_object) + result = content_and_header_for_code_object(co) + end + + set_file_and_dir_locals(code_object.source_file) + _pry_.pager.page result + end + + # This method checks whether the `code_object` is a WrappedModule, + # if it is, then it returns the first candidate (monkeypatch) with + # accessible source (or docs). If `code_object` is not a WrappedModule (i.e a + # method or a command) then the `code_object` itself is just + # returned. + # + # @return [Pry::WrappedModule, Pry::Method, Pry::Command] + def code_object_with_accessible_source(code_object) + if code_object.is_a?(WrappedModule) + candidate = code_object.candidates.find(&:source) + if candidate + return candidate + else + raise CommandError, no_definition_message if !valid_superclass?(code_object) + + @used_super = true + code_object_with_accessible_source(code_object.super) + end + else + code_object + end + end + + def valid_superclass?(code_object) + code_object.super && code_object.super.wrapped != Object + end + + def content_and_header_for_code_object(code_object) + header(code_object) << content_for(code_object) + end + + def content_and_headers_for_all_module_candidates(mod) + result = "Found #{mod.number_of_candidates} candidates for `#{mod.name}` definition:\n" + mod.number_of_candidates.times do |v| + candidate = mod.candidate(v) + begin + result << "\nCandidate #{v+1}/#{mod.number_of_candidates}: #{candidate.source_file} @ line #{candidate.source_line}:\n" + content = content_for(candidate) + + result << "Number of lines: #{content.lines.count}\n\n" << content + rescue Pry::RescuableException + result << "\nNo content found.\n" + next + end + end + result + end + + def no_definition_message + "Couldn't locate a definition for #{obj_name}!" + end + + # Generate a header (meta-data information) for all the code + # object types: methods, modules, commands, procs... + def header(code_object) + file_name, line_num = file_and_line_for(code_object) + h = "\n#{Pry::Helpers::Text.bold('From:')} #{file_name} " + h << code_object_header(code_object, line_num) + h << "\n#{Pry::Helpers::Text.bold('Number of lines:')} " << + "#{content_for(code_object).lines.count}\n\n" + h << Helpers::Text.bold('** Warning:') << " Cannot find code for #{@original_code_object.nonblank_name}. Showing superclass #{code_object.nonblank_name} instead. **\n\n" if @used_super + h + end + + def code_object_header(code_object, line_num) + if code_object.real_method_object? + method_header(code_object, line_num) + + # It sucks we have to test for both Pry::WrappedModule and WrappedModule::Candidate, + # probably indicates a deep refactor needs to happen in those classes. + elsif code_object.is_a?(Pry::WrappedModule) || code_object.is_a?(Pry::WrappedModule::Candidate) + module_header(code_object, line_num) + else + "" + end + end + + def method_header(code_object, line_num) + h = "" + h << (code_object.c_method? ? "(C Method):" : "@ line #{line_num}:") + h << method_sections(code_object)[:owner] + h << method_sections(code_object)[:visibility] + h << method_sections(code_object)[:signature] + h + end + + def module_header(code_object, line_num) + h = "" + h << "@ line #{line_num}:\n" + h << text.bold(code_object.module? ? "Module" : "Class") + h << " #{text.bold('name:')} #{code_object.nonblank_name}" + + if code_object.number_of_candidates > 1 + h << (text.bold("\nNumber of monkeypatches: ") << code_object.number_of_candidates.to_s) + h << ". Use the `-a` option to display all available monkeypatches" + end + h + end + + def method_sections(code_object) + { + :owner => "\n#{text.bold("Owner:")} #{code_object.owner || "N/A"}\n", + :visibility => "#{text.bold("Visibility:")} #{code_object.visibility}", + :signature => "\n#{text.bold("Signature:")} #{code_object.signature}" + }.merge(header_options) { |key, old, new| (new && old).to_s } + end + + def header_options + { + :owner => true, + :visibility => true, + :signature => nil + } + end + + def show_all_modules?(code_object) + code_object.is_a?(Pry::WrappedModule) && opts.present?(:all) + end + + def obj_name + @obj_name ||= args.empty? ? nil : args.join(' ') + end + + def use_line_numbers? + opts.present?(:b) || opts.present?(:l) + end + + def start_line_for(code_object) + if opts.present?(:'base-one') + 1 + else + code_object.source_line || 1 + end + end + + # takes into account possible yard docs, and returns yard_file / yard_line + # Also adjusts for start line of comments (using start_line_for), which it has to infer + # by subtracting number of lines of comment from start line of code_object + def file_and_line_for(code_object) + if code_object.module_with_yard_docs? + [code_object.yard_file, code_object.yard_line] + else + [code_object.source_file, start_line_for(code_object)] + end + end + + def complete(input) + if input =~ /([^ ]*)#([a-z0-9_]*)\z/ + prefix, search = [$1, $2] + methods = begin + Pry::Method.all_from_class(binding.eval(prefix)) + rescue RescuableException + return super + end + methods.map do |method| + [prefix, method.name].join('#') if method.name.start_with?(search) + end.compact + else + super + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_input.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_input.rb new file mode 100644 index 0000000..8b72787 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_input.rb @@ -0,0 +1,17 @@ +class Pry + class Command::ShowInput < Pry::ClassCommand + match 'show-input' + group 'Editing' + description 'Show the contents of the input buffer for the current multi-line expression.' + + banner <<-'BANNER' + Show the contents of the input buffer for the current multi-line expression. + BANNER + + def process + output.puts Code.new(eval_string).with_line_numbers + end + end + + Pry::Commands.add_command(Pry::Command::ShowInput) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_source.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_source.rb new file mode 100644 index 0000000..f3f069e --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/show_source.rb @@ -0,0 +1,50 @@ +require 'pry/commands/show_info' + +class Pry + class Command::ShowSource < Command::ShowInfo + match 'show-source' + group 'Introspection' + description 'Show the source for a method or class.' + + banner <<-'BANNER' + Usage: show-source [OPTIONS] [METH|CLASS] + Aliases: $, show-method + + Show the source for a method or class. Tries instance methods first and then + methods by default. + + show-source hi_method + show-source hi_method + show-source Pry#rep # source for Pry#rep method + show-source Pry # for Pry class + show-source Pry -a # for all Pry class definitions (all monkey patches) + show-source Pry.foo -e # for class of the return value of expression `Pry.foo` + show-source Pry --super # for superclass of Pry (Object class) + + https://github.com/pry/pry/wiki/Source-browsing#wiki-Show_method + BANNER + + def options(opt) + opt.on :e, :eval, "evaluate the command's argument as a ruby expression and show the class its return value" + super(opt) + end + + def process + if opts.present?(:e) + obj = target.eval(args.first) + self.args = Array.new(1) { Module === obj ? obj.name : obj.class.name } + end + super + end + + # The source for code_object prepared for display. + def content_for(code_object) + Code.new(code_object.source, start_line_for(code_object)). + with_line_numbers(use_line_numbers?) + end + end + + Pry::Commands.add_command(Pry::Command::ShowSource) + Pry::Commands.alias_command 'show-method', 'show-source' + Pry::Commands.alias_command '$', 'show-source' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/simple_prompt.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/simple_prompt.rb new file mode 100644 index 0000000..4d1e6ec --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/simple_prompt.rb @@ -0,0 +1,22 @@ +class Pry + class Command::SimplePrompt < Pry::ClassCommand + match 'simple-prompt' + group 'prompts' + description 'Toggle the simple prompt.' + + banner <<-'BANNER' + Toggle the simple prompt. + BANNER + + def process + case _pry_.prompt + when Pry::SIMPLE_PROMPT + _pry_.pop_prompt + else + _pry_.push_prompt Pry::SIMPLE_PROMPT + end + end + end + + Pry::Commands.add_command(Pry::Command::SimplePrompt) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/stat.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/stat.rb new file mode 100644 index 0000000..06a191b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/stat.rb @@ -0,0 +1,40 @@ +class Pry + class Command::Stat < Pry::ClassCommand + match 'stat' + group 'Introspection' + description 'View method information and set _file_ and _dir_ locals.' + command_options :shellwords => false + + banner <<-'BANNER' + Usage: stat [OPTIONS] [METH] + + Show method information for method METH and set _file_ and _dir_ locals. + + stat hello_method + BANNER + + def options(opt) + method_options(opt) + end + + def process + meth = method_object + aliases = meth.aliases + + output.puts unindent <<-EOS + Method Information: + -- + Name: #{meth.name} + Alias#{ "es" if aliases.length > 1 }: #{ aliases.any? ? aliases.join(", ") : "None." } + Owner: #{meth.owner ? meth.owner : "Unknown"} + Visibility: #{meth.visibility} + Type: #{meth.is_a?(::Method) ? "Bound" : "Unbound"} + Arity: #{meth.arity} + Method Signature: #{meth.signature} + Source Location: #{meth.source_location ? meth.source_location.join(":") : "Not found."} + EOS + end + end + + Pry::Commands.add_command(Pry::Command::Stat) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/switch_to.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/switch_to.rb new file mode 100644 index 0000000..ad3e71c --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/switch_to.rb @@ -0,0 +1,23 @@ +class Pry + class Command::SwitchTo < Pry::ClassCommand + match 'switch-to' + group 'Navigating Pry' + description 'Start a new subsession on a binding in the current stack.' + + banner <<-'BANNER' + Start a new subsession on a binding in the current stack (numbered by nesting). + BANNER + + def process(selection) + selection = selection.to_i + + if selection < 0 || selection > _pry_.binding_stack.size - 1 + raise CommandError, "Invalid binding index #{selection} - use `nesting` command to view valid indices." + else + Pry.start(_pry_.binding_stack[selection]) + end + end + end + + Pry::Commands.add_command(Pry::Command::SwitchTo) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/toggle_color.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/toggle_color.rb new file mode 100644 index 0000000..602c293 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/toggle_color.rb @@ -0,0 +1,24 @@ +class Pry + class Command::ToggleColor < Pry::ClassCommand + match 'toggle-color' + group 'Misc' + description 'Toggle syntax highlighting.' + + banner <<-'BANNER' + Usage: toggle-color + + Toggle syntax highlighting. + BANNER + + def process + _pry_.color = color_toggle + output.puts "Syntax highlighting #{_pry_.color ? "on" : "off"}" + end + + def color_toggle + !_pry_.color + end + + Pry::Commands.add_command(self) + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression.rb new file mode 100644 index 0000000..52a88af --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression.rb @@ -0,0 +1,105 @@ +class Pry + class Command::WatchExpression < Pry::ClassCommand + require 'pry/commands/watch_expression/expression.rb' + + match 'watch' + group 'Context' + description 'Watch the value of an expression and print a notification whenever it changes.' + command_options :use_prefix => false + + banner <<-'BANNER' + Usage: watch [EXPRESSION] + watch + watch --delete [INDEX] + + watch [EXPRESSION] adds an expression to the list of those being watched. + It will be re-evaluated every time you hit enter in pry. If its value has + changed, the new value will be printed to the console. + + This is useful if you are step-through debugging and want to see how + something changes over time. It's also useful if you're trying to write + a method inside pry and want to check that it gives the right answers + every time you redefine it. + + watch on its own displays all the currently watched expressions and their + values, and watch --delete [INDEX] allows you to delete expressions from + the list being watched. + BANNER + + def options(opt) + opt.on :d, :delete, + "Delete the watch expression with the given index. If no index is given; clear all watch expressions.", + :optional_argument => true, :as => Integer + opt.on :l, :list, + "Show all current watch expressions and their values. Calling watch with no expressions or options will also show the watch expressions." + end + + def process + case + when opts.present?(:delete) + delete opts[:delete] + when opts.present?(:list) || args.empty? + list + else + add_hook + add_expression(args) + end + end + + private + + def expressions + _pry_.config.watch_expressions ||= [] + end + + def delete(index) + if index + output.puts "Deleting watch expression ##{index}: #{expressions[index-1]}" + expressions.delete_at(index-1) + else + output.puts "Deleting all watched expressions" + expressions.clear + end + end + + def list + if expressions.empty? + output.puts "No watched expressions" + else + _pry_.pager.open do |pager| + pager.puts "Listing all watched expressions:" + pager.puts "" + expressions.each_with_index do |expr, index| + pager.print text.with_line_numbers(expr.to_s, index+1) + end + pager.puts "" + end + end + end + + def eval_and_print_changed(output) + expressions.each do |expr| + expr.eval! + if expr.changed? + output.puts "#{text.blue "watch"}: #{expr.to_s}" + end + end + end + + def add_expression(arguments) + expressions << Expression.new(_pry_, target, arg_string) + output.puts "Watching #{Code.new(arg_string)}" + end + + def add_hook + hook = [:after_eval, :watch_expression] + unless _pry_.hooks.hook_exists?(*hook) + _pry_.hooks.add_hook(*hook) do |_, _pry_| + eval_and_print_changed _pry_.output + end + end + end + end + + Pry::Commands.add_command(Pry::Command::WatchExpression) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression/expression.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression/expression.rb new file mode 100644 index 0000000..a73b401 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/watch_expression/expression.rb @@ -0,0 +1,38 @@ +class Pry + class Command::WatchExpression + class Expression + attr_reader :target, :source, :value, :previous_value, :_pry_ + + def initialize(_pry_, target, source) + @_pry_ = _pry_ + @target = target + @source = source.strip + end + + def eval! + @previous_value = @value + @value = Pry::ColorPrinter.pp(target_eval(target, source), "") + end + + def to_s + "#{Code.new(source).strip} => #{value}" + end + + # Has the value of the expression changed? + # + # We use the pretty-printed string represenation to detect differences + # as this avoids problems with dup (causes too many differences) and == (causes too few) + def changed? + (value != previous_value) + end + + private + + def target_eval(target, source) + target.eval(source) + rescue => e + e + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/whereami.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/whereami.rb new file mode 100644 index 0000000..695ecc9 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/whereami.rb @@ -0,0 +1,190 @@ +class Pry + class Command::Whereami < Pry::ClassCommand + + class << self + attr_accessor :method_size_cutoff + end + + @method_size_cutoff = 30 + + match 'whereami' + description 'Show code surrounding the current context.' + group 'Context' + + banner <<-'BANNER' + Usage: whereami [-qn] [LINES] + + Describe the current location. If you use `binding.pry` inside a method then + whereami will print out the source for that method. + + If a number is passed, then LINES lines before and after the current line will be + shown instead of the method itself. + + The `-q` flag can be used to suppress error messages in the case that there's + no code to show. This is used by pry in the default before_session hook to show + you when you arrive at a `binding.pry`. + + The `-n` flag can be used to hide line numbers so that code can be copy/pasted + effectively. + + When pry was started on an Object and there is no associated method, whereami + will instead output a brief description of the current object. + BANNER + + def setup + @file = expand_path(target.eval('__FILE__')) + @line = target.eval('__LINE__') + @method = Pry::Method.from_binding(target) + end + + def options(opt) + opt.on :q, :quiet, "Don't display anything in case of an error" + opt.on :n, :"no-line-numbers", "Do not display line numbers" + opt.on :m, :"method", "Show the complete source for the current method." + opt.on :c, :"class", "Show the complete source for the current class or module." + opt.on :f, :"file", "Show the complete source for the current file." + end + + def code + @code ||= if opts.present?(:m) + method_code or raise CommandError, "Cannot find method code." + elsif opts.present?(:c) + class_code or raise CommandError, "Cannot find class code." + elsif opts.present?(:f) + Pry::Code.from_file(@file) + elsif args.any? + code_window + else + default_code + end + end + + def code? + !!code + rescue MethodSource::SourceNotFoundError + false + end + + def bad_option_combination? + [opts.present?(:m), opts.present?(:f), + opts.present?(:c), args.any?].count(true) > 1 + end + + def location + "#{@file} @ line #{@line} #{@method && @method.name_with_owner}" + end + + def process + if bad_option_combination? + raise CommandError, "Only one of -m, -c, -f, and LINES may be specified." + end + + if nothing_to_do? + return + elsif internal_binding?(target) + handle_internal_binding + return + end + + set_file_and_dir_locals(@file) + + out = "\n#{text.bold('From:')} #{location}:\n\n" << + code.with_line_numbers(use_line_numbers?).with_marker(marker) << "\n" + + _pry_.pager.page out + end + + private + + def nothing_to_do? + opts.quiet? && (internal_binding?(target) || !code?) + end + + def use_line_numbers? + !opts.present?(:n) + end + + def marker + !opts.present?(:n) && @line + end + + def top_level? + target_self == Pry.main + end + + def handle_internal_binding + if top_level? + output.puts "At the top level." + else + output.puts "Inside #{Pry.view_clip(target_self)}." + end + end + + def small_method? + @method.source_range.count < self.class.method_size_cutoff + end + + def default_code + if method_code && small_method? + method_code + else + code_window + end + end + + def code_window + Pry::Code.from_file(@file).around(@line, window_size) + end + + def method_code + return @method_code if @method_code + + if valid_method? + @method_code = Pry::Code.from_method(@method) + end + end + + # This either returns the `target_self` + # or it returns the class of `target_self` if `target_self` is not a class. + # @return [Pry::WrappedModule] + def target_class + target_self.is_a?(Module) ? Pry::WrappedModule(target_self) : + Pry::WrappedModule(target_self.class) + end + + def class_code + return @class_code if @class_code + + mod = @method ? Pry::WrappedModule(@method.owner) : target_class + + idx = mod.candidates.find_index { |v| expand_path(v.source_file) == @file } + @class_code = idx && Pry::Code.from_module(mod, idx) + end + + def valid_method? + @method && @method.source? && expand_path(@method.source_file) == @file && + @method.source_range.include?(@line) + end + + def expand_path(f) + return if !f + + if Pry.eval_path == f + f + else + File.expand_path(f) + end + end + + def window_size + if args.empty? + _pry_.config.default_window_size + else + args.first.to_i + end + end + end + + Pry::Commands.add_command(Pry::Command::Whereami) + Pry::Commands.alias_command '@', 'whereami' +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/wtf.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/wtf.rb new file mode 100644 index 0000000..2d47dfa --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/commands/wtf.rb @@ -0,0 +1,57 @@ +class Pry + class Command::Wtf < Pry::ClassCommand + match(/wtf([?!]*)/) + group 'Context' + description 'Show the backtrace of the most recent exception.' + options :listing => 'wtf?' + + banner <<-'BANNER' + Usage: wtf[?|!] + + Show's a few lines of the backtrace of the most recent exception (also available + as `_ex_.backtrace`). If you want to see more lines, add more question marks or + exclamation marks. + + wtf? + wtf?!???!?!? + + # To see the entire backtrace, pass the `-v` or `--verbose` flag. + wtf -v + BANNER + + def options(opt) + opt.on :v, :verbose, "Show the full backtrace" + end + + def process + raise Pry::CommandError, "No most-recent exception" unless exception + + output.puts "#{text.bold('Exception:')} #{exception.class}: #{exception}\n--" + if opts.verbose? + output.puts with_line_numbers(backtrace) + else + output.puts with_line_numbers(backtrace.first(size_of_backtrace)) + end + end + + private + + def exception + _pry_.last_exception + end + + def with_line_numbers(bt) + Pry::Code.new(bt, 0, :text).with_line_numbers.to_s + end + + def backtrace + exception.backtrace + end + + def size_of_backtrace + [captures[0].size, 0.5].max * 10 + end + end + + Pry::Commands.add_command(Pry::Command::Wtf) +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/config.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/config.rb new file mode 100644 index 0000000..73b7742 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/config.rb @@ -0,0 +1,24 @@ +class Pry::Config + require_relative 'config/behavior' + require_relative 'config/default' + require_relative 'config/convenience' + include Pry::Config::Behavior + + def self.shortcuts + Convenience::SHORTCUTS + end + + # + # FIXME + # @param [Pry::Hooks] hooks + # + def hooks=(hooks) + if hooks.is_a?(Hash) + warn "Hash-based hooks are now deprecated! Use a `Pry::Hooks` object " \ + "instead! http://rubydoc.info/github/pry/pry/master/Pry/Hooks" + self["hooks"] = Pry::Hooks.from_hash(hooks) + else + self["hooks"] = hooks + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/config/behavior.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/behavior.rb new file mode 100644 index 0000000..1cb98da --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/behavior.rb @@ -0,0 +1,139 @@ +module Pry::Config::Behavior + ASSIGNMENT = "=".freeze + NODUP = [TrueClass, FalseClass, NilClass, Symbol, Numeric, Module, Proc].freeze + INSPECT_REGEXP = /#{Regexp.escape "default=#<"}/ + + module Builder + def from_hash(hash, default = nil) + new(default).tap do |config| + config.merge!(hash) + end + end + end + + def self.included(klass) + unless defined?(RESERVED_KEYS) + const_set :RESERVED_KEYS, instance_methods(false).map(&:to_s).freeze + end + klass.extend(Builder) + end + + def initialize(default = Pry.config) + @default = default + @lookup = {} + end + + # + # @return [Pry::Config::Behavior] + # returns the default used if a matching value for a key isn't found in self + # + def default + @default + end + + def [](key) + @lookup[key.to_s] + end + + def []=(key, value) + key = key.to_s + if RESERVED_KEYS.include?(key) + raise ArgumentError, "few things are reserved by pry, but using '#{key}' as a configuration key is." + end + @lookup[key] = value + end + + def method_missing(name, *args, &block) + key = name.to_s + if key[-1] == ASSIGNMENT + short_key = key[0..-2] + self[short_key] = args[0] + elsif key?(key) + self[key] + elsif @default.respond_to?(name) + value = @default.public_send(name, *args, &block) + # FIXME: refactor Pry::Hook so that it stores config on the config object, + # so that we can use the normal strategy. + self[key] = value.dup if key == 'hooks' + value + else + nil + end + end + + def merge!(other) + other = try_convert_to_hash(other) + raise TypeError, "unable to convert argument into a Hash" unless other + other.each do |key, value| + self[key] = value + end + end + + def ==(other) + @lookup == try_convert_to_hash(other) + end + alias_method :eql?, :== + + def respond_to_missing?(key, include_private=false) + key?(key) or @default.respond_to?(key) or super(key, include_private) + end + + def key?(key) + key = key.to_s + @lookup.key?(key) + end + + def clear + @lookup.clear + true + end + alias_method :refresh, :clear + + def forget(key) + @lookup.delete(key.to_s) + end + + def keys + @lookup.keys + end + + def to_hash + @lookup.dup + end + alias_method :to_h, :to_hash + + + def inspect + key_str = keys.map { |key| "'#{key}'" }.join(",") + "#<#{_clip_inspect(self)} local_keys=[#{key_str}] default=#{@default.inspect}>" + end + + def pretty_print(q) + q.text inspect[1..-1].gsub(INSPECT_REGEXP, "default=<") + end + +private + def _clip_inspect(obj) + "#{obj.class}:0x%x" % obj.object_id << 1 + end + + def _dup(value) + if NODUP.any? { |klass| klass === value } + value + else + value.dup + end + end + + def try_convert_to_hash(obj) + if Hash === obj + obj + elsif obj.respond_to?(:to_h) + obj.to_h + elsif obj.respond_to?(:to_hash) + obj.to_hash + else + nil + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/config/convenience.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/convenience.rb new file mode 100644 index 0000000..9d9273d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/convenience.rb @@ -0,0 +1,26 @@ +module Pry::Config::Convenience + SHORTCUTS = [ + :input, + :output, + :commands, + :print, + :exception_handler, + :quiet?, + :hooks, + :color, + :pager, + :editor, + :memory_size, + :extra_sticky_locals + ] + + + def config_shortcut(*names) + names.each do |name| + reader = name + setter = "#{name}=" + define_method(reader) { config.public_send(name) } + define_method(setter) { |value| config.public_send(setter, value) } + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/config/default.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/default.rb new file mode 100644 index 0000000..587e27d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/config/default.rb @@ -0,0 +1,165 @@ +class Pry::Config::Default + include Pry::Config::Behavior + + default = { + input: proc { + lazy_readline + }, + output: proc { + $stdout + }, + commands: proc { + Pry::Commands + }, + prompt_name: proc { + Pry::DEFAULT_PROMPT_NAME + }, + prompt: proc { + Pry::DEFAULT_PROMPT + }, + prompt_safe_objects: proc { + Pry::DEFAULT_PROMPT_SAFE_OBJECTS + }, + print: proc { + Pry::DEFAULT_PRINT + }, + quiet: proc { + false + }, + exception_handler: proc { + Pry::DEFAULT_EXCEPTION_HANDLER + }, + exception_whitelist: proc { + Pry::DEFAULT_EXCEPTION_WHITELIST + }, + hooks: proc { + Pry::DEFAULT_HOOKS + }, + pager: proc { + true + }, + system: proc { + Pry::DEFAULT_SYSTEM + }, + color: proc { + Pry::Helpers::BaseHelpers.use_ansi_codes? + }, + default_window_size: proc { + 5 + }, + editor: proc { + Pry.default_editor_for_platform + }, # TODO: Pry::Platform.editor + should_load_rc: proc { + true + }, + should_load_local_rc: proc { + true + }, + should_trap_interrupts: proc { + Pry::Helpers::BaseHelpers.jruby? + }, # TODO: Pry::Platform.jruby? + disable_auto_reload: proc { + false + }, + command_prefix: proc { + "" + }, + auto_indent: proc { + Pry::Helpers::BaseHelpers.use_ansi_codes? + }, + correct_indent: proc { + true + }, + collision_warning: proc { + false + }, + output_prefix: proc { + "=> " + }, + requires: proc { + [] + }, + should_load_requires: proc { + true + }, + should_load_plugins: proc { + true + }, + windows_console_warning: proc { + true + }, + control_d_handler: proc { + Pry::DEFAULT_CONTROL_D_HANDLER + }, + memory_size: proc { + 100 + }, + extra_sticky_locals: proc { + {} + }, + command_completions: proc { + proc { commands.keys } + }, + file_completions: proc { + proc { Dir["."] } + }, + ls: proc { + Pry::Config.from_hash(Pry::Command::Ls::DEFAULT_OPTIONS) + }, + completer: proc { + require "pry/input_completer" + Pry::InputCompleter + } + } + + def initialize + super(nil) + configure_gist + configure_history + end + + def quiet? + quiet + end + + default.each do |key, value| + define_method(key) do + if default[key].equal?(value) + default[key] = instance_eval(&value) + end + default[key] + end + end + +private + # TODO: + # all of this configure_* stuff is a relic of old code. + # we should try move this code to being command-local. + def configure_gist + self["gist"] = Pry::Config.from_hash(inspecter: proc(&:pretty_inspect)) + end + + def configure_history + self["history"] = Pry::Config.from_hash "should_save" => true, + "should_load" => true + history.file = File.expand_path("~/.pry_history") rescue nil + if history.file.nil? + self.should_load_rc = false + history.should_save = false + history.should_load = false + end + end + + def lazy_readline + require 'readline' + Readline + rescue LoadError + warn "Sorry, you can't use Pry without Readline or a compatible library." + warn "Possible solutions:" + warn " * Rebuild Ruby with Readline support using `--with-readline`" + warn " * Use the rb-readline gem, which is a pure-Ruby port of Readline" + warn " * Use the pry-coolline gem, a pure-ruby alternative to Readline" + raise + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/core_extensions.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/core_extensions.rb new file mode 100644 index 0000000..a418daf --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/core_extensions.rb @@ -0,0 +1,131 @@ +class Pry + # @return [Array] Code of the method used when implementing Pry's + # __binding__, along with line indication to be used with instance_eval (and + # friends). + # + # @see Object#__binding__ + BINDING_METHOD_IMPL = [<<-METHOD, __FILE__, __LINE__ + 1] + # Get a binding with 'self' set to self, and no locals. + # + # The default definee is determined by the context in which the + # definition is eval'd. + # + # Please don't call this method directly, see {__binding__}. + # + # @return [Binding] + def __pry__ + binding + end + METHOD +end + +class Object + # Start a Pry REPL on self. + # + # If `self` is a Binding then that will be used to evaluate expressions; + # otherwise a new binding will be created. + # + # @param [Object] object the object or binding to pry + # (__deprecated__, use `object.pry`) + # @param [Hash] hash the options hash + # @example With a binding + # binding.pry + # @example On any object + # "dummy".pry + # @example With options + # def my_method + # binding.pry :quiet => true + # end + # my_method() + # @see Pry.start + def pry(object=nil, hash={}) + if object.nil? || Hash === object + Pry.start(self, object || {}) + else + Pry.start(object, hash) + end + end + + # Return a binding object for the receiver. + # + # The `self` of the binding is set to the current object, and it contains no + # local variables. + # + # The default definee (http://yugui.jp/articles/846) is set such that: + # + # * If `self` is a class or module, then new methods created in the binding + # will be defined in that class or module (as in `class Foo; end`). + # * If `self` is a normal object, then new methods created in the binding will + # be defined on its singleton class (as in `class << self; end`). + # * If `self` doesn't have a real singleton class (i.e. it is a Fixnum, Float, + # Symbol, nil, true, or false), then new methods will be created on the + # object's class (as in `self.class.class_eval{ }`) + # + # Newly created constants, including classes and modules, will also be added + # to the default definee. + # + # @return [Binding] + def __binding__ + # If you ever feel like changing this method, be careful about variables + # that you use. They shouldn't be inserted into the binding that will + # eventually be returning. + + # When you're cd'd into a class, methods you define should be added to it. + if is_a?(Module) + # class_eval sets both self and the default definee to this class. + return class_eval "binding" + end + + unless respond_to?(:__pry__) + # The easiest way to check whether an object has a working singleton class + # is to try and define a method on it. (just checking for the presence of + # the singleton class gives false positives for `true` and `false`). + # __pry__ is just the closest method we have to hand, and using + # it has the nice property that we can memoize this check. + begin + # instance_eval sets the default definee to the object's singleton class + instance_eval(*Pry::BINDING_METHOD_IMPL) + + # If we can't define methods on the Object's singleton_class. Then we fall + # back to setting the default definee to be the Object's class. That seems + # nicer than having a REPL in which you can't define methods. + rescue TypeError, Pry::FrozenObjectException + # class_eval sets the default definee to self.class + self.class.class_eval(*Pry::BINDING_METHOD_IMPL) + end + end + + __pry__ + end +end + +class BasicObject + # Return a binding object for the receiver. + # + # The `self` of the binding is set to the current object, and it contains no + # local variables. + # + # The default definee (http://yugui.jp/articles/846) is set such that new + # methods defined will be added to the singleton class of the BasicObject. + # + # @return [Binding] + def __binding__ + # BasicObjects don't have respond_to?, so we just define the method + # every time. As they also don't have `.freeze`, this call won't + # fail as it can for normal Objects. + (class << self; self; end).class_eval <<-EOF, __FILE__, __LINE__ + 1 + # Get a binding with 'self' set to self, and no locals. + # + # The default definee is determined by the context in which the + # definition is eval'd. + # + # Please don't call this method directly, see {__binding__}. + # + # @return [Binding] + def __pry__ + ::Kernel.binding + end + EOF + self.__pry__ + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/editor.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/editor.rb new file mode 100644 index 0000000..a833f70 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/editor.rb @@ -0,0 +1,133 @@ +class Pry + class Editor + include Pry::Helpers::BaseHelpers + include Pry::Helpers::CommandHelpers + + attr_reader :_pry_ + + def initialize(_pry_) + @_pry_ = _pry_ + end + + def edit_tempfile_with_content(initial_content, line=1) + temp_file do |f| + f.puts(initial_content) + f.flush + f.close(false) + invoke_editor(f.path, line, true) + File.read(f.path) + end + end + + def invoke_editor(file, line, blocking=true) + raise CommandError, "Please set Pry.config.editor or export $VISUAL or $EDITOR" unless _pry_.config.editor + + editor_invocation = build_editor_invocation_string(file, line, blocking) + return nil unless editor_invocation + + if jruby? + open_editor_on_jruby(editor_invocation) + else + open_editor(editor_invocation) + end + end + + private + + # Generate the string that's used to start the editor. This includes + # all the flags we want as well as the file and line number we + # want to open at. + def build_editor_invocation_string(file, line, blocking) + + if _pry_.config.editor.respond_to?(:call) + args = [file, line, blocking][0...(_pry_.config.editor.arity)] + _pry_.config.editor.call(*args) + else + sanitized_file = if windows? + file.gsub(/\//, '\\') + else + Shellwords.escape(file) + end + + "#{_pry_.config.editor} #{blocking_flag_for_editor(blocking)} #{start_line_syntax_for_editor(sanitized_file, line)}" + end + end + + # Start the editor running, using the calculated invocation string + def open_editor(editor_invocation) + # Note we dont want to use Pry.config.system here as that + # may be invoked non-interactively (i.e via Open4), whereas we want to + # ensure the editor is always interactive + system(*Shellwords.split(editor_invocation)) or raise CommandError, "`#{editor_invocation}` gave exit status: #{$?.exitstatus}" + end + + # We need JRuby specific code here cos just shelling out using + # system() appears to be pretty broken :/ + def open_editor_on_jruby(editor_invocation) + begin + require 'spoon' + pid = Spoon.spawnp(*Shellwords.split(editor_invocation)) + Process.waitpid(pid) + rescue FFI::NotFoundError + system(editor_invocation) + end + end + + # Some editors that run outside the terminal allow you to control whether or + # not to block the process from which they were launched (in this case, Pry). + # For those editors, return the flag that produces the desired behavior. + def blocking_flag_for_editor(blocking) + case editor_name + when /^emacsclient/ + '--no-wait' unless blocking + when /^[gm]vim/ + '--nofork' if blocking + when /^jedit/ + '-wait' if blocking + when /^mate/, /^subl/ + '-w' if blocking + end + end + + # Return the syntax for a given editor for starting the editor + # and moving to a particular line within that file + def start_line_syntax_for_editor(file_name, line_number) + # special case for 1st line + return file_name if line_number <= 1 + + case editor_name + when /^[gm]?vi/, /^emacs/, /^nano/, /^pico/, /^gedit/, /^kate/ + "+#{line_number} #{file_name}" + when /^mate/, /^geany/ + "-l #{line_number} #{file_name}" + when /^subl/ + "#{file_name}:#{line_number}" + when /^uedit32/ + "#{file_name}/#{line_number}" + when /^jedit/ + "#{file_name} +line:#{line_number}" + else + if windows? + "#{file_name}" + else + "+#{line_number} #{file_name}" + end + end + end + + # Get the name of the binary that Pry.config.editor points to. + # + # This is useful for deciding which flags we pass to the editor as + # we can just use the program's name and ignore any absolute paths. + # + # @example + # Pry.config.editor="/home/conrad/bin/textmate -w" + # editor_name + # # => textmate + # + def editor_name + File.basename(_pry_.config.editor).split(" ").first + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/exceptions.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/exceptions.rb new file mode 100644 index 0000000..0204d84 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/exceptions.rb @@ -0,0 +1,77 @@ +class Pry + + # As a REPL, we often want to catch any unexpected exceptions that may have + # been raised; however we don't want to go overboard and prevent the user + # from exiting Pry when they want to. + module RescuableException + def self.===(exception) + case exception + # Catch when the user hits ^C (Interrupt < SignalException), and assume + # that they just wanted to stop the in-progress command (just like bash + # etc.) + when Interrupt + true + # Don't catch signals (particularly not SIGTERM) as these are unlikely + # to be intended for pry itself. We should also make sure that + # Kernel#exit works. + when *Pry.config.exception_whitelist + false + # All other exceptions will be caught. + else + true + end + end + end + + # Catches SecurityErrors if $SAFE is set + module Pry::TooSafeException + def self.===(exception) + $SAFE > 0 && SecurityError === exception + end + end + + # An Exception Tag (cf. Exceptional Ruby) that instructs Pry to show the error + # in a more user-friendly manner. This should be used when the exception + # happens within Pry itself as a direct consequence of the user typing + # something wrong. + # + # This allows us to distinguish between the user typing: + # + # pry(main)> def ) + # SyntaxError: unexpected ) + # + # pry(main)> method_that_evals("def )") + # SyntaxError: (eval):1: syntax error, unexpected ')' + # from ./a.rb:2 in `eval' + module UserError; end + + # When we try to get a binding for an object, we try to define a method on + # that Object's singleton class. This doesn't work for "frozen" Object's, and + # the exception is just a vanilla RuntimeError. + module FrozenObjectException + def self.===(exception) + ["can't modify frozen class/module", + "can't modify frozen Class", + ].include?(exception.message) + end + end + + # Don't catch these exceptions + DEFAULT_EXCEPTION_WHITELIST = [SystemExit, + SignalException, + Pry::TooSafeException] + + # CommandErrors are caught by the REPL loop and displayed to the user. They + # indicate an exceptional condition that's fatal to the current command. + class CommandError < StandardError; end + class MethodNotFound < CommandError; end + + # indicates obsolete API + class ObsoleteError < StandardError; end + + # This is to keep from breaking under Rails 3.2 for people who are doing that + # IRB = Pry thing. + module ExtendCommandBundle + end + +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers.rb new file mode 100644 index 0000000..f59c308 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers.rb @@ -0,0 +1,5 @@ +require "pry/helpers/base_helpers" +require "pry/helpers/options_helpers" +require "pry/helpers/command_helpers" +require "pry/helpers/text" +require "pry/helpers/table" diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/base_helpers.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/base_helpers.rb new file mode 100644 index 0000000..5dade46 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/base_helpers.rb @@ -0,0 +1,113 @@ +class Pry + module Helpers + + module BaseHelpers + + module_function + + def silence_warnings + old_verbose = $VERBOSE + $VERBOSE = nil + begin + yield + ensure + $VERBOSE = old_verbose + end + end + + # Acts like send but ignores any methods defined below Object or Class in the + # inheritance hierarchy. + # This is required to introspect methods on objects like Net::HTTP::Get that + # have overridden the `method` method. + def safe_send(obj, method, *args, &block) + (Module === obj ? Module : Object).instance_method(method).bind(obj).call(*args, &block) + end + public :safe_send + + def find_command(name, set = Pry::Commands) + command_match = set.find do |_, command| + (listing = command.options[:listing]) == name && listing != nil + end + command_match.last if command_match + end + + def not_a_real_file?(file) + file =~ /(\(.*\))|<.*>/ || file =~ /__unknown__/ || file == "" || file == "-e" + end + + def command_dependencies_met?(options) + return true if !options[:requires_gem] + Array(options[:requires_gem]).all? do |g| + Rubygem.installed?(g) + end + end + + def use_ansi_codes? + windows_ansi? || ENV['TERM'] && ENV['TERM'] != "dumb" + end + + def colorize_code(code) + CodeRay.scan(code, :ruby).term + end + + def highlight(string, regexp, highlight_color=:bright_yellow) + string.gsub(regexp) { |match| "<#{highlight_color}>#{match}" } + end + + # formatting + def heading(text) + text = "#{text}\n--" + "\e[1m#{text}\e[0m" + end + + # have fun on the Windows platform. + def windows? + RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ + end + + # are we able to use ansi on windows? + def windows_ansi? + defined?(Win32::Console) || ENV['ANSICON'] || (windows? && mri_2?) + end + + def jruby? + RbConfig::CONFIG['ruby_install_name'] == 'jruby' + end + + def jruby_19? + jruby? && RbConfig::CONFIG['ruby_version'] == '1.9' + end + + def rbx? + RbConfig::CONFIG['ruby_install_name'] == 'rbx' + end + + def mri? + RbConfig::CONFIG['ruby_install_name'] == 'ruby' + end + + def mri_19? + mri? && RUBY_VERSION =~ /^1\.9/ + end + + def mri_2? + mri? && RUBY_VERSION =~ /^2/ + end + + def mri_20? + mri? && RUBY_VERSION =~ /^2\.0/ + end + + def mri_21? + mri? && RUBY_VERSION =~ /^2\.1/ + end + + # Send the given text through the best available pager (if Pry.config.pager is + # enabled). Infers where to send the output if used as a mixin. + # DEPRECATED. + def stagger_output(text, out = nil) + Pry.new.pager.page text + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/command_helpers.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/command_helpers.rb new file mode 100644 index 0000000..7f7e226 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/command_helpers.rb @@ -0,0 +1,156 @@ +class Pry + module Helpers + + module CommandHelpers + include OptionsHelpers + + module_function + + # Open a temp file and yield it to the block, closing it after + # @return [String] The path of the temp file + def temp_file(ext='.rb') + file = Tempfile.new(['pry', ext]) + yield file + ensure + file.close(true) if file + end + + def internal_binding?(target) + m = target.eval("::Kernel.__method__").to_s + # class_eval is here because of http://jira.codehaus.org/browse/JRUBY-6753 + ["__binding__", "__pry__", "class_eval"].include?(m) + end + + def get_method_or_raise(name, target, opts={}, omit_help=false) + meth = Pry::Method.from_str(name, target, opts) + + if name && !meth + command_error("The method '#{name}' could not be found.", omit_help, MethodNotFound) + end + + (opts[:super] || 0).times do + if meth.super + meth = meth.super + else + command_error("'#{meth.name_with_owner}' has no super method.", omit_help, MethodNotFound) + end + end + + if !meth || (!name && internal_binding?(target)) + command_error("No method name given, and context is not a method.", omit_help, MethodNotFound) + end + + set_file_and_dir_locals(meth.source_file) + meth + end + + def command_error(message, omit_help, klass=CommandError) + message += " Type `#{command_name} --help` for help." unless omit_help + raise klass, message + end + + # Remove any common leading whitespace from every line in `text`. + # + # This can be used to make a HEREDOC line up with the left margin, without + # sacrificing the indentation level of the source code. + # + # e.g. + # opt.banner unindent <<-USAGE + # Lorem ipsum dolor sit amet, consectetur adipisicing elit, + # sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + # "Ut enim ad minim veniam." + # USAGE + # + # Heavily based on textwrap.dedent from Python, which is: + # Copyright (C) 1999-2001 Gregory P. Ward. + # Copyright (C) 2002, 2003 Python Software Foundation. + # Written by Greg Ward + # + # Licensed under + # From + # + # @param [String] text The text from which to remove indentation + # @return [String] The text with indentation stripped. + def unindent(text, left_padding = 0) + # Empty blank lines + text = text.sub(/^[ \t]+$/, '') + + # Find the longest common whitespace to all indented lines + # Ignore lines containing just -- or ++ as these seem to be used by + # comment authors as delimeters. + margin = text.scan(/^[ \t]*(?!--\n|\+\+\n)(?=[^ \t\n])/).inject do |current_margin, next_indent| + if next_indent.start_with?(current_margin) + current_margin + elsif current_margin.start_with?(next_indent) + next_indent + else + "" + end + end + + text.gsub(/^#{margin}/, ' ' * left_padding) + end + + # Restrict a string to the given range of lines (1-indexed) + # @param [String] content The string. + # @param [Range, Fixnum] lines The line(s) to restrict it to. + # @return [String] The resulting string. + def restrict_to_lines(content, lines) + line_range = one_index_range_or_number(lines) + Array(content.lines.to_a[line_range]).join + end + + def one_index_number(line_number) + if line_number > 0 + line_number - 1 + else + line_number + end + end + + # convert a 1-index range to a 0-indexed one + def one_index_range(range) + Range.new(one_index_number(range.begin), one_index_number(range.end)) + end + + def one_index_range_or_number(range_or_number) + case range_or_number + when Range + one_index_range(range_or_number) + else + one_index_number(range_or_number) + end + end + + def absolute_index_number(line_number, array_length) + if line_number >= 0 + line_number + else + [array_length + line_number, 0].max + end + end + + def absolute_index_range(range_or_number, array_length) + case range_or_number + when Range + a = absolute_index_number(range_or_number.begin, array_length) + b = absolute_index_number(range_or_number.end, array_length) + else + a = b = absolute_index_number(range_or_number, array_length) + end + + Range.new(a, b) + end + + def set_file_and_dir_locals(file_name, _pry_=_pry_(), target=target()) + return if !target or !file_name + _pry_.last_file = File.expand_path(file_name) + _pry_.inject_local("_file_", _pry_.last_file, target) + + _pry_.last_dir = File.dirname(_pry_.last_file) + _pry_.inject_local("_dir_", _pry_.last_dir, target) + end + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/documentation_helpers.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/documentation_helpers.rb new file mode 100644 index 0000000..9f9870e --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/documentation_helpers.rb @@ -0,0 +1,75 @@ +class Pry + module Helpers + + # This class contains methods useful for extracting + # documentation from methods and classes. + module DocumentationHelpers + + module_function + + def process_rdoc(comment) + comment = comment.dup + comment.gsub(/(?:\s*\n)?(.*?)\s*<\/code>/m) { CodeRay.scan($1, :ruby).term }. + gsub(/(?:\s*\n)?(.*?)\s*<\/em>/m) { "\e[1m#{$1}\e[0m" }. + gsub(/(?:\s*\n)?(.*?)\s*<\/i>/m) { "\e[1m#{$1}\e[0m" }. + gsub(/\B\+(\w+?)\+\B/) { "\e[32m#{$1}\e[0m" }. + gsub(/((?:^[ \t]+.+(?:\n+|\Z))+)/) { CodeRay.scan($1, :ruby).term }. + gsub(/`(?:\s*\n)?([^\e]*?)\s*`/) { "`#{CodeRay.scan($1, :ruby).term}`" } + end + + def process_yardoc_tag(comment, tag) + in_tag_block = nil + comment.lines.map do |v| + if in_tag_block && v !~ /^\S/ + Pry::Helpers::Text.strip_color Pry::Helpers::Text.strip_color(v) + elsif in_tag_block + in_tag_block = false + v + else + in_tag_block = true if v =~ /^@#{tag}/ + v + end + end.join + end + + def process_yardoc(comment) + yard_tags = ["param", "return", "option", "yield", "attr", "attr_reader", "attr_writer", + "deprecate", "example", "raise"] + (yard_tags - ["example"]).inject(comment) { |a, v| process_yardoc_tag(a, v) }. + gsub(/^@(#{yard_tags.join("|")})/) { "\e[33m#{$1}\e[0m" } + end + + def process_comment_markup(comment) + process_yardoc process_rdoc(comment) + end + + # @param [String] code + # @return [String] + def strip_comments_from_c_code(code) + code.sub(/\A\s*\/\*.*?\*\/\s*/m, '') + end + + # Given a string that makes up a comment in a source-code file parse out the content + # that the user is intended to read. (i.e. without leading indentation, #-characters + # or shebangs) + # + # @param [String] comment + # @return [String] + def get_comment_content(comment) + comment = comment.dup + # Remove #!/usr/bin/ruby + comment.gsub!(/\A\#!.*$/, '') + # Remove leading empty comment lines + comment.gsub!(/\A\#+?$/, '') + comment.gsub!(/^\s*#/, '') + strip_leading_whitespace(comment) + end + + # @param [String] text + # @return [String] + def strip_leading_whitespace(text) + Pry::Helpers::CommandHelpers.unindent(text) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/options_helpers.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/options_helpers.rb new file mode 100644 index 0000000..e566d3b --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/options_helpers.rb @@ -0,0 +1,27 @@ +class Pry + module Helpers + module OptionsHelpers + module_function + + # Add method options to the Slop instance + def method_options(opt) + @method_target = target + opt.on :M, "instance-methods", "Operate on instance methods." + opt.on :m, :methods, "Operate on methods." + opt.on :s, :super, "Select the 'super' method. Can be repeated to traverse the ancestors.", :as => :count + opt.on :c, :context, "Select object context to run under.", :argument => true do |context| + @method_target = Pry.binding_for(target.eval(context)) + end + end + + # Get the method object parsed by the slop instance + def method_object + @method_object ||= get_method_or_raise(args.empty? ? nil : args.join(" "), @method_target, + :super => opts[:super], + :instance => opts.present?(:'instance-methods') && !opts.present?(:'methods'), + :methods => opts.present?(:'methods') && !opts.present?(:'instance-methods') + ) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/table.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/table.rb new file mode 100644 index 0000000..56e7e59 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/table.rb @@ -0,0 +1,109 @@ +class Pry + module Helpers + def self.tablify_or_one_line(heading, things) + plain_heading = Pry::Helpers::Text.strip_color(heading) + attempt = Table.new(things, :column_count => things.size) + if attempt.fits_on_line?(Terminal.width! - plain_heading.size - 2) + "#{heading}: #{attempt}\n" + else + "#{heading}: \n#{tablify_to_screen_width(things, :indent => ' ')}\n" + end + end + + def self.tablify_to_screen_width(things, options = {}) + things = things.compact + if indent = options[:indent] + usable_width = Terminal.width! - indent.size + tablify(things, usable_width).to_s.gsub(/^/, indent) + else + tablify(things, Terminal.width!).to_s + end + end + + def self.tablify(things, line_length) + table = Table.new(things, :column_count => things.size) + table.column_count -= 1 until 1 == table.column_count or + table.fits_on_line?(line_length) + table + end + + class Table + attr_reader :items, :column_count + def initialize items, args = {} + @column_count = args[:column_count] + self.items = items + end + + def to_s + rows_to_s.join("\n") + end + + def rows_to_s style = :color_on + widths = columns.map{|e| _max_width(e)} + @rows_without_colors.map do |r| + padded = [] + r.each_with_index do |e,i| + next unless e + item = e.ljust(widths[i]) + item.sub! e, _recall_color_for(e) if :color_on == style + padded << item + end + padded.join(Pry.config.ls.separator) + end + end + + def items= items + @items = items + _rebuild_colorless_cache + _recolumn + items + end + + def column_count= n + @column_count = n + _recolumn + end + + def fits_on_line? line_length + _max_width(rows_to_s :no_color) <= line_length + end + + def columns + @rows_without_colors.transpose + end + + def ==(other); items == other.to_a end + def to_a; items.to_a end + + private + def _max_width(things) + things.compact.map(&:size).max || 0 + end + + def _rebuild_colorless_cache + @colorless_cache = {} + @plain_items = [] + items.map do |e| + plain = Pry::Helpers::Text.strip_color(e) + @colorless_cache[plain] = e + @plain_items << plain + end + end + + def _recolumn + @rows_without_colors = [] + return if items.size.zero? + row_count = (items.size.to_f/column_count).ceil + row_count.times do |i| + row_indices = (0...column_count).map{|e| row_count*e+i} + @rows_without_colors << row_indices.map{|e| @plain_items[e]} + end + end + + def _recall_color_for thing + @colorless_cache[thing] + end + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/text.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/text.rb new file mode 100644 index 0000000..13867cf --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/helpers/text.rb @@ -0,0 +1,107 @@ +class Pry + module Helpers + + # The methods defined on {Text} are available to custom commands via {Pry::Command#text}. + module Text + + COLORS = + { + "black" => 0, + "red" => 1, + "green" => 2, + "yellow" => 3, + "blue" => 4, + "purple" => 5, + "magenta" => 5, + "cyan" => 6, + "white" => 7 + } + + class << self + + COLORS.each_pair do |color, value| + define_method color do |text| + "\033[0;#{30+value}m#{text}\033[0m" + end + + define_method "bright_#{color}" do |text| + "\033[1;#{30+value}m#{text}\033[0m" + end + end + + # Remove any color codes from _text_. + # + # @param [String, #to_s] text + # @return [String] _text_ stripped of any color codes. + def strip_color(text) + text.to_s.gsub(/\e\[.*?(\d)+m/ , '') + end + + # Returns _text_ as bold text for use on a terminal. + # + # @param [String, #to_s] text + # @return [String] _text_ + def bold(text) + "\e[1m#{text}\e[0m" + end + + # Returns `text` in the default foreground colour. + # Use this instead of "black" or "white" when you mean absence of colour. + # + # @param [String, #to_s] text + # @return [String] + def default(text) + text.to_s + end + alias_method :bright_default, :bold + + # Executes the block with `Pry.config.color` set to false. + # @yield + # @return [void] + def no_color(&block) + boolean = Pry.config.color + Pry.config.color = false + yield + ensure + Pry.config.color = boolean + end + + # Executes the block with `Pry.config.pager` set to false. + # @yield + # @return [void] + def no_pager(&block) + boolean = Pry.config.pager + Pry.config.pager = false + yield + ensure + Pry.config.pager = boolean + end + + # Returns _text_ in a numbered list, beginning at _offset_. + # + # @param [#each_line] text + # @param [Fixnum] offset + # @return [String] + def with_line_numbers(text, offset, color=:blue) + lines = text.each_line.to_a + max_width = (offset + lines.count).to_s.length + lines.each_with_index.map do |line, index| + adjusted_index = (index + offset).to_s.rjust(max_width) + "#{self.send(color, adjusted_index)}: #{line}" + end.join + end + + # Returns _text_ indented by _chars_ spaces. + # + # @param [String] text + # @param [Fixnum] chars + def indent(text, chars) + text.lines.map { |l| "#{' ' * chars}#{l}" }.join + end + end + + end + + end +end + diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/history.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/history.rb new file mode 100644 index 0000000..1bef4a2 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/history.rb @@ -0,0 +1,125 @@ +class Pry + # The History class is responsible for maintaining the user's input history, + # both internally and within Readline. + class History + attr_accessor :loader, :saver, :pusher, :clearer + + # @return [Fixnum] Number of lines in history when Pry first loaded. + attr_reader :original_lines + + def initialize(options={}) + @history = [] + @original_lines = 0 + @file_path = options[:file_path] + restore_default_behavior + end + + # Assign the default methods for loading, saving, pushing, and clearing. + def restore_default_behavior + Pry.config.input # force Readline to load if applicable + + @loader = method(:read_from_file) + @saver = method(:save_to_file) + + if defined?(Readline) + @pusher = method(:push_to_readline) + @clearer = method(:clear_readline) + else + @pusher = proc { } + @clearer = proc { } + end + end + + # Load the input history using `History.loader`. + # @return [Integer] The number of lines loaded + def load + @loader.call do |line| + @pusher.call(line.chomp) + @history << line.chomp + @original_lines += 1 + end + end + + # Add a line to the input history, ignoring blank and duplicate lines. + # @param [String] line + # @return [String] The same line that was passed in + def push(line) + unless line.empty? || (@history.last && line == @history.last) + @pusher.call(line) + @history << line + @saver.call(line) if Pry.config.history.should_save + end + line + end + alias << push + + # Clear this session's history. This won't affect the contents of the + # history file. + def clear + @clearer.call + @history = [] + end + + # @return [Fixnum] The number of lines in history. + def history_line_count + @history.count + end + + # @return [Fixnum] The number of lines in history from just this session. + def session_line_count + @history.count - @original_lines + end + + # Return an Array containing all stored history. + # @return [Array] An Array containing all lines of history loaded + # or entered by the user in the current session. + def to_a + @history.dup + end + + private + + # The default loader. Yields lines from `Pry.history.config.file`. + def read_from_file + filename = File.expand_path(Pry.config.history.file) + + if File.exists?(filename) + File.foreach(filename) { |line| yield(line) } + end + rescue => error + warn "History file not loaded: #{error.message}" + end + + # The default pusher. Appends the given line to Readline::HISTORY. + # @param [String] line + def push_to_readline(line) + Readline::HISTORY << line + end + + # The default clearer. Clears Readline::HISTORY. + def clear_readline + Readline::HISTORY.shift until Readline::HISTORY.empty? + end + + # The default saver. Appends the given line to `Pry.history.config.file`. + def save_to_file(line) + history_file.puts line if history_file + end + + # The history file, opened for appending. + def history_file + if defined?(@history_file) + @history_file + else + @history_file = File.open(file_path, 'a', 0600).tap { |f| f.sync = true } + end + rescue Errno::EACCES + warn 'History not saved; unable to open your history file for writing.' + @history_file = false + end + + def file_path + @file_path || Pry.config.history.file + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/history_array.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/history_array.rb new file mode 100644 index 0000000..60e41bc --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/history_array.rb @@ -0,0 +1,121 @@ +class Pry + # A history array is an array to which you can only add elements. Older + # entries are removed progressively, so that the array never contains more than + # N elements. + # + # History arrays are used by Pry to store the output of the last commands. + # + # @example + # ary = Pry::HistoryArray.new 10 + # ary << 1 << 2 << 3 + # ary[0] # => 1 + # ary[1] # => 2 + # 10.times { |n| ary << n } + # ary[0] # => nil + # ary[-1] # => 9 + class HistoryArray + include Enumerable + + # @param [Integer] size Maximum amount of objects in the array + def initialize(size) + @max_size = size + + @hash = {} + @count = 0 + end + + # Pushes an object at the end of the array + # @param [Object] value Object to be added + def <<(value) + @hash[@count] = value + + if @hash.size > max_size + @hash.delete(@count - max_size) + end + + @count += 1 + + self + end + + # @overload [](index) + # @param [Integer] index Index of the item to access. + # @return [Object, nil] Item at that index or nil if it has been removed. + # @overload [](index, size) + # @param [Integer] index Index of the first item to access. + # @param [Integer] size Amount of items to access + # @return [Array, nil] The selected items. Nil if index is greater than + # the size of the array. + # @overload [](range) + # @param [Range] range Range of indices to access. + # @return [Array, nil] The selected items. Nil if index is greater than + # the size of the array. + def [](index_or_range, size = nil) + if index_or_range.is_a? Integer + index = convert_index(index_or_range) + + if size + end_index = index + size + index > @count ? nil : (index...[end_index, @count].min).map do |n| + @hash[n] + end + else + @hash[index] + end + else + range = convert_range(index_or_range) + range.begin > @count ? nil : range.map { |n| @hash[n] } + end + end + + # @return [Integer] Amount of objects in the array + def size + @count + end + alias count size + alias length size + + def empty? + size == 0 + end + + def each + ((@count - size)...@count).each do |n| + yield @hash[n] + end + end + + def to_a + ((@count - size)...@count).map { |n| @hash[n] } + end + + # Returns [Hash] copy of the internal @hash history + def to_h + @hash.dup + end + + def pop! + @hash.delete @count - 1 + @count -= 1 + end + + def inspect + "#<#{self.class} size=#{size} first=#{@count - size} max_size=#{max_size}>" + end + + # @return [Integer] Maximum amount of objects in the array + attr_reader :max_size + + private + def convert_index(n) + n >= 0 ? n : @count + n + end + + def convert_range(range) + end_index = convert_index(range.end) + end_index += 1 unless range.exclude_end? + + Range.new(convert_index(range.begin), [end_index, @count].min, true) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/hooks.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/hooks.rb new file mode 100644 index 0000000..48291ee --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/hooks.rb @@ -0,0 +1,230 @@ +class Pry + + # Implements a hooks system for Pry. A hook is a callable that is + # associated with an event. A number of events are currently + # provided by Pry, these include: `:when_started`, `:before_session`, `:after_session`. + # A hook must have a name, and is connected with an event by the + # `Pry::Hooks#add_hook` method. + # @example Adding a hook for the `:before_session` event. + # Pry.config.hooks.add_hook(:before_session, :say_hi) do + # puts "hello" + # end + class Hooks + + # Converts a hash to a `Pry::Hooks` instance. All hooks defined + # this way are anonymous. This functionality is primarily to + # provide backwards-compatibility with the old hash-based hook + # system in Pry versions < 0.9.8 + # @param [Hash] hash The hash to convert to `Pry::Hooks`. + # @return [Pry::Hooks] The resulting `Pry::Hooks` instance. + def self.from_hash(hash) + return hash if hash.instance_of?(self) + instance = new + hash.each do |k, v| + instance.add_hook(k, nil, v) + end + instance + end + + def initialize + @hooks = {} + end + + # Ensure that duplicates have their @hooks object + def initialize_copy(orig) + hooks_dup = @hooks.dup + @hooks.each do |k, v| + hooks_dup[k] = v.dup + end + + @hooks = hooks_dup + end + + def hooks + @hooks + end + protected :hooks + + def errors + @errors ||= [] + end + + # Destructively merge the contents of two `Pry:Hooks` instances. + # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge + # @return [Pry:Hooks] Returns the receiver. + # @example + # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # Pry::Hooks.new.merge!(hooks) + def merge!(other) + @hooks.merge!(other.dup.hooks) do |key, v1, v2| + merge_arrays(v1, v2) + end + + self + end + + def merge_arrays(array1, array2) + uniq_keeping_last(array1 + array2, &:first) + end + private :merge_arrays + + def uniq_keeping_last(input, &block) + hash, output = {}, [] + input.reverse.each{ |i| hash[block[i]] ||= (output.unshift i) } + output + end + private :uniq_keeping_last + + # Return a new `Pry::Hooks` instance containing a merge of the contents of two `Pry:Hooks` instances, + # @param [Pry::Hooks] other The `Pry::Hooks` instance to merge + # @return [Pry::Hooks] The new hash. + # @example + # hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # Pry::Hooks.new.merge(hooks) + def merge(other) + self.dup.tap do |v| + v.merge!(other) + end + end + + # Add a new hook to be executed for the `name` even. + # @param [Symbol] event_name The name of the event. + # @param [Symbol] hook_name The name of the hook. + # @param [#call] callable The callable. + # @yield The block to use as the callable (if `callable` parameter not provided) + # @return [Pry:Hooks] Returns the receiver. + # @example + # Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + def add_hook(event_name, hook_name, callable=nil, &block) + @hooks[event_name] ||= [] + + # do not allow duplicates, but allow multiple `nil` hooks + # (anonymous hooks) + if hook_exists?(event_name, hook_name) && !hook_name.nil? + raise ArgumentError, "Hook with name '#{hook_name}' already defined!" + end + + if !block && !callable + raise ArgumentError, "Must provide a block or callable." + end + + # ensure we only have one anonymous hook + @hooks[event_name].delete_if { |h, k| h.nil? } if hook_name.nil? + + if block + @hooks[event_name] << [hook_name, block] + elsif callable + @hooks[event_name] << [hook_name, callable] + end + + self + end + + # Execute the list of hooks for the `event_name` event. + # @param [Symbol] event_name The name of the event. + # @param [Array] args The arguments to pass to each hook function. + # @return [Object] The return value of the last executed hook. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.exec_hook(:before_session) #=> OUTPUT: "hi!" + def exec_hook(event_name, *args, &block) + @hooks[event_name] ||= [] + + @hooks[event_name].map do |hook_name, callable| + begin + callable.call(*args, &block) + rescue RescuableException => e + errors << e + e + end + end.last + end + + # Return the number of hook functions registered for the `event_name` event. + # @param [Symbol] event_name The name of the event. + # @return [Fixnum] The number of hook functions for `event_name`. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.count(:before_session) #=> 1 + def hook_count(event_name) + @hooks[event_name] ||= [] + @hooks[event_name].size + end + + # Return a specific hook for a given event. + # @param [Symbol] event_name The name of the event. + # @param [Symbol] hook_name The name of the hook + # @return [#call] The requested hook. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.get_hook(:before_session, :say_hi).call #=> "hi!" + def get_hook(event_name, hook_name) + @hooks[event_name] ||= [] + hook = @hooks[event_name].find { |current_hook_name, callable| current_hook_name == hook_name } + hook.last if hook + end + + # Return the hash of hook names / hook functions for a + # given event. (Note that modifying the returned hash does not + # alter the hooks, use add_hook/delete_hook for that). + # @param [Symbol] event_name The name of the event. + # @return [Hash] The hash of hook names / hook functions. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.get_hooks(:before_session) #=> {:say_hi=>#} + def get_hooks(event_name) + @hooks[event_name] ||= [] + Hash[@hooks[event_name]] + end + + # Delete a hook for an event. + # @param [Symbol] event_name The name of the event. + # @param [Symbol] hook_name The name of the hook. + # to delete. + # @return [#call] The deleted hook. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.delete_hook(:before_session, :say_hi) + def delete_hook(event_name, hook_name) + @hooks[event_name] ||= [] + deleted_callable = nil + + @hooks[event_name].delete_if do |current_hook_name, callable| + if current_hook_name == hook_name + deleted_callable = callable + true + else + false + end + end + deleted_callable + end + + # Clear all hooks functions for a given event. + # @param [String] event_name The name of the event. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.delete_hook(:before_session) + def delete_hooks(event_name) + @hooks[event_name] = [] + end + + alias_method :clear, :delete_hooks + + # Remove all events and hooks, clearing out the Pry::Hooks + # instance completely. + # @example + # my_hooks = Pry::Hooks.new.add_hook(:before_session, :say_hi) { puts "hi!" } + # my_hooks.clear_all + def clear_all + @hooks = {} + end + + # @param [Symbol] event_name Name of the event. + # @param [Symbol] hook_name Name of the hook. + # @return [Boolean] Whether the hook by the name `hook_name` + def hook_exists?(event_name, hook_name) + !!(@hooks[event_name] && @hooks[event_name].find { |name, _| name == hook_name }) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/indent.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/indent.rb new file mode 100644 index 0000000..72fbf69 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/indent.rb @@ -0,0 +1,406 @@ +require 'coderay' + +class Pry + ## + # Pry::Indent is a class that can be used to indent a number of lines + # containing Ruby code similar as to how IRB does it (but better). The class + # works by tokenizing a string using CodeRay and then looping over those + # tokens. Based on the tokens in a line of code that line (or the next one) + # will be indented or un-indented by correctly. + # + class Indent + include Helpers::BaseHelpers + + # Raised if {#module_nesting} would not work. + class UnparseableNestingError < StandardError; end + + # @return [String] String containing the spaces to be inserted before the next line. + attr_reader :indent_level + + # @return [Array] The stack of open tokens. + attr_reader :stack + + # The amount of spaces to insert for each indent level. + SPACES = ' ' + + # Hash containing all the tokens that should increase the indentation + # level. The keys of this hash are open tokens, the values the matching + # tokens that should prevent a line from being indented if they appear on + # the same line. + OPEN_TOKENS = { + 'def' => 'end', + 'class' => 'end', + 'module' => 'end', + 'do' => 'end', + 'if' => 'end', + 'unless' => 'end', + 'while' => 'end', + 'until' => 'end', + 'for' => 'end', + 'case' => 'end', + 'begin' => 'end', + '[' => ']', + '{' => '}', + '(' => ')' + } + + # Which tokens can either be open tokens, or appear as modifiers on + # a single-line. + SINGLELINE_TOKENS = %w(if while until unless rescue) + + # Which tokens can be followed by an optional "do" keyword. + OPTIONAL_DO_TOKENS = %w(for while until) + + # Collection of token types that should be ignored. Without this list + # keywords such as "class" inside strings would cause the code to be + # indented incorrectly. + # + # :pre_constant and :preserved_constant are the CodeRay 0.9.8 and 1.0.0 + # classifications of "true", "false", and "nil". + IGNORE_TOKENS = [:space, :content, :string, :method, :ident, + :constant, :pre_constant, :predefined_constant] + + # Tokens that indicate the end of a statement (i.e. that, if they appear + # directly before an "if" indicates that that if applies to the same line, + # not the next line) + # + # :reserved and :keywords are the CodeRay 0.9.8 and 1.0.0 respectively + # classifications of "super", "next", "return", etc. + STATEMENT_END_TOKENS = IGNORE_TOKENS + [:regexp, :integer, :float, :keyword, + :delimiter, :reserved] + + # Collection of tokens that should appear dedented even though they + # don't affect the surrounding code. + MIDWAY_TOKENS = %w(when else elsif ensure rescue) + + # Clean the indentation of a fragment of ruby. + # + # @param [String] str + # @return [String] + def self.indent(str) + new.indent(str) + end + + # Get the module nesting at the given point in the given string. + # + # NOTE If the line specified contains a method definition, then the nesting + # at the start of the method definition is used. Otherwise the nesting from + # the end of the line is used. + # + # @param [String] str The ruby code to analyze + # @param [Fixnum] line_number The line number (starting from 1) + # @return [Array] + def self.nesting_at(str, line_number) + indent = new + lines = str.split("\n") + n = line_number - 1 + to_indent = lines[0...n] << (lines[n] || "").split("def").first(1) + indent.indent(to_indent.join("\n") << "\n") + indent.module_nesting + end + + def initialize + reset + end + + # reset internal state + def reset + @stack = [] + @indent_level = '' + @heredoc_queue = [] + @close_heredocs = {} + @string_start = nil + @awaiting_class = false + @module_nesting = [] + self + end + + # Indents a string and returns it. This string can either be a single line + # or multiple ones. + # + # @example + # str = <] + def module_nesting + @module_nesting.map do |(kind, token)| + raise UnparseableNestingError, @module_nesting.inspect if token.nil? + + "#{kind} #{token}" + end + end + + # Return a string which, when printed, will rewrite the previous line with + # the correct indentation. Mostly useful for fixing 'end'. + # + # @param [String] prompt The user's prompt + # @param [String] code The code the user just typed in. + # @param [Fixnum] overhang (0) The number of chars to erase afterwards (i.e., + # the difference in length between the old line and the new one). + # @return [String] + def correct_indentation(prompt, code, overhang=0) + prompt = prompt.delete("\001\002") + line_to_measure = Pry::Helpers::Text.strip_color(prompt) << code + whitespace = ' ' * overhang + + _, cols = Terminal.screen_size + + cols = cols.to_i + lines = (cols != 0 ? (line_to_measure.length / cols + 1) : 1).to_i + + if Pry::Helpers::BaseHelpers.windows_ansi? + move_up = "\e[#{lines}F" + move_down = "\e[#{lines}E" + else + move_up = "\e[#{lines}A\e[0G" + move_down = "\e[#{lines}B\e[0G" + end + + "#{move_up}#{prompt}#{colorize_code(code)}#{whitespace}#{move_down}" + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/input_completer.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/input_completer.rb new file mode 100644 index 0000000..363baa4 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/input_completer.rb @@ -0,0 +1,242 @@ +# taken from irb +# Implements tab completion for Readline in Pry +class Pry::InputCompleter + NUMERIC_REGEXP = /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/ + ARRAY_REGEXP = /^([^\]]*\])\.([^.]*)$/ + SYMBOL_REGEXP = /^(:[^:.]*)$/ + SYMBOL_METHOD_CALL_REGEXP = /^(:[^:.]+)\.([^.]*)$/ + REGEX_REGEXP = /^(\/[^\/]*\/)\.([^.]*)$/ + PROC_OR_HASH_REGEXP = /^([^\}]*\})\.([^.]*)$/ + TOPLEVEL_LOOKUP_REGEXP = /^::([A-Z][^:\.\(]*)$/ + CONSTANT_REGEXP = /^([A-Z][A-Za-z0-9]*)$/ + CONSTANT_OR_METHOD_REGEXP = /^([A-Z].*)::([^:.]*)$/ + HEX_REGEXP = /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/ + GLOBALVARIABLE_REGEXP = /^(\$[^.]*)$/ + VARIABLE_REGEXP = /^([^."].*)\.([^.]*)$/ + + ReservedWords = [ + "BEGIN", "END", + "alias", "and", + "begin", "break", + "case", "class", + "def", "defined", "do", + "else", "elsif", "end", "ensure", + "false", "for", + "if", "in", + "module", + "next", "nil", "not", + "or", + "redo", "rescue", "retry", "return", + "self", "super", + "then", "true", + "undef", "unless", "until", + "when", "while", + "yield" ] + + Operators = [ + "%", "&", "*", "**", "+", "-", "/", + "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>", + "[]", "[]=", "^", "!", "!=", "!~" + ] + + WORD_ESCAPE_STR = " \t\n\"\\'`><=;|&{(" + + def initialize(input, pry = nil) + @pry = pry + @input = input + @input.basic_word_break_characters = WORD_ESCAPE_STR if @input.respond_to?(:basic_word_break_characters=) + @input.completion_append_character = nil if @input.respond_to?(:completion_append_character=) + end + + # + # Return a new completion proc for use by Readline. + # + def call(str, options = {}) + custom_completions = options[:custom_completions] || [] + # if there are multiple contexts e.g. cd 1/2/3 + # get new target for 1/2 and find candidates for 3 + path, input = build_path(str) + + if path.call.empty? + target = options[:target] + else + # Assume the user is tab-completing the 'cd' command + begin + target = Pry::ObjectPath.new(path.call, @pry.binding_stack).resolve.last + # but if that doesn't work, assume they're doing division with no spaces + rescue Pry::CommandError + target = options[:target] + end + end + + begin + bind = target + # Complete stdlib symbols + case input + when REGEX_REGEXP # Regexp + receiver = $1 + message = Regexp.quote($2) + candidates = Regexp.instance_methods.collect(&:to_s) + select_message(path, receiver, message, candidates) + when ARRAY_REGEXP # Array + receiver = $1 + message = Regexp.quote($2) + candidates = Array.instance_methods.collect(&:to_s) + select_message(path, receiver, message, candidates) + when PROC_OR_HASH_REGEXP # Proc or Hash + receiver = $1 + message = Regexp.quote($2) + candidates = Proc.instance_methods.collect(&:to_s) + candidates |= Hash.instance_methods.collect(&:to_s) + select_message(path, receiver, message, candidates) + when SYMBOL_REGEXP # Symbol + if Symbol.respond_to?(:all_symbols) + sym = Regexp.quote($1) + candidates = Symbol.all_symbols.collect{|s| ":" << s.id2name} + candidates.grep(/^#{sym}/) + else + [] + end + when TOPLEVEL_LOOKUP_REGEXP # Absolute Constant or class methods + receiver = $1 + candidates = Object.constants.collect(&:to_s) + candidates.grep(/^#{receiver}/).collect{|e| "::" << e} + when CONSTANT_REGEXP # Constant + message = $1 + begin + context = target.eval("self") + context = context.class unless context.respond_to? :constants + candidates = context.constants.collect(&:to_s) + rescue + candidates = [] + end + candidates = candidates.grep(/^#{message}/).collect(&path) + when CONSTANT_OR_METHOD_REGEXP # Constant or class methods + receiver = $1 + message = Regexp.quote($2) + begin + candidates = eval("#{receiver}.constants.collect(&:to_s)", bind) + candidates |= eval("#{receiver}.methods.collect(&:to_s)", bind) + rescue Pry::RescuableException + candidates = [] + end + candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e} + when SYMBOL_METHOD_CALL_REGEXP # method call on a Symbol + receiver = $1 + message = Regexp.quote($2) + candidates = Symbol.instance_methods.collect(&:to_s) + select_message(path, receiver, message, candidates) + when NUMERIC_REGEXP + # Numeric + receiver = $1 + message = Regexp.quote($5) + begin + candidates = eval(receiver, bind).methods.collect(&:to_s) + rescue Pry::RescuableException + candidates = [] + end + select_message(path, receiver, message, candidates) + when HEX_REGEXP + # Numeric(0xFFFF) + receiver = $1 + message = Regexp.quote($2) + begin + candidates = eval(receiver, bind).methods.collect(&:to_s) + rescue Pry::RescuableException + candidates = [] + end + select_message(path, receiver, message, candidates) + when GLOBALVARIABLE_REGEXP # global + regmessage = Regexp.new(Regexp.quote($1)) + candidates = global_variables.collect(&:to_s).grep(regmessage) + when VARIABLE_REGEXP # variable + receiver = $1 + message = Regexp.quote($2) + + gv = eval("global_variables", bind).collect(&:to_s) + lv = eval("local_variables", bind).collect(&:to_s) + cv = eval("self.class.constants", bind).collect(&:to_s) + + if (gv | lv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver + # foo.func and foo is local var. OR + # Foo::Bar.func + begin + candidates = eval("#{receiver}.methods", bind).collect(&:to_s) + rescue Pry::RescuableException + candidates = [] + end + else + # func1.func2 + candidates = [] + ObjectSpace.each_object(Module){|m| + begin + name = m.name.to_s + rescue Pry::RescuableException + name = "" + end + next if name != "IRB::Context" and + /^(IRB|SLex|RubyLex|RubyToken)/ =~ name + + # jruby doesn't always provide #instance_methods() on each + # object. + if m.respond_to?(:instance_methods) + candidates.concat m.instance_methods(false).collect(&:to_s) + end + } + candidates.sort! + candidates.uniq! + end + select_message(path, receiver, message, candidates) + when /^\.([^.]*)$/ + # Unknown(maybe String) + receiver = "" + message = Regexp.quote($1) + candidates = String.instance_methods(true).collect(&:to_s) + select_message(path, receiver, message, candidates) + else + candidates = eval( + "methods | private_methods | local_variables | " \ + "self.class.constants | instance_variables", + bind + ).collect(&:to_s) + + if eval("respond_to?(:class_variables)", bind) + candidates += eval("class_variables", bind).collect(&:to_s) + end + candidates = (candidates|ReservedWords|custom_completions).grep(/^#{Regexp.quote(input)}/) + candidates.collect(&path) + end + rescue Pry::RescuableException + [] + end + end + + def select_message(path, receiver, message, candidates) + candidates.grep(/^#{message}/).collect { |e| + case e + when /^[a-zA-Z_]/ + path.call(receiver + "." << e) + when /^[0-9]/ + when *Operators + #receiver + " " << e + end + }.compact + end + + # build_path seperates the input into two parts: path and input. + # input is the partial string that should be completed + # path is a proc that takes an input and builds a full path. + def build_path(input) + # check to see if the input is a regex + return proc {|i| i.to_s }, input if input[/\/\./] + trailing_slash = input.end_with?('/') + contexts = input.chomp('/').split(/\//) + input = contexts[-1] + path = proc do |i| + p = contexts[0..-2].push(i).join('/') + p += '/' if trailing_slash && !i.nil? + p + end + return path, input + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/input_lock.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/input_lock.rb new file mode 100644 index 0000000..8adfed4 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/input_lock.rb @@ -0,0 +1,132 @@ +require 'thread' + +class Pry + # There is one InputLock per input (such as STDIN) as two REPLs on the same + # input makes things delirious. InputLock serializes accesses to the input so + # that threads to not conflict with each other. The latest thread to request + # ownership of the input wins. + class InputLock + class Interrupt < Exception; end + + class << self + attr_accessor :input_locks + attr_accessor :global_lock + end + + self.input_locks = {} + self.global_lock = Mutex.new + + def self.for(input) + # XXX This method leaks memory, as we never unregister an input once we + # are done with it. Fortunately, the leak is tiny (or so we hope). In + # usual scenarios, we would leak the StringIO that is passed to be + # evaluated from the command line. + global_lock.synchronize do + input_locks[input] ||= Pry::InputLock.new + end + end + + def initialize + @mutex = Mutex.new + @cond = ConditionVariable.new + @owners = [] + @interruptible = false + end + + # Adds ourselves to the ownership list. The last one in the list may access + # the input through interruptible_region(). + def __with_ownership(&block) + @mutex.synchronize do + # Three cases: + # 1) There are no owners, in this case we are good to go. + # 2) The current owner of the input is not reading the input (it might + # just be evaluating some ruby that the user typed). + # The current owner will figure out that it cannot go back to reading + # the input since we are adding ourselves to the @owners list, which + # in turns makes us the current owner. + # 3) The owner of the input is in the interruptible region, reading from + # the input. It's safe to send an Interrupt exception to interrupt + # the owner. It will then proceed like in case 2). + # We wait until the owner sets the interruptible flag back + # to false, meaning that he's out of the interruptible region. + # Note that the owner may receive multiple interrupts since, but that + # should be okay (and trying to avoid it is futile anyway). + while @interruptible + @owners.last.raise Interrupt + @cond.wait(@mutex) + end + @owners << Thread.current + end + + block.call + + ensure + @mutex.synchronize do + # We are releasing any desire to have the input ownership by removing + # ourselves from the list. + @owners.delete(Thread.current) + + # We need to wake up the thread at the end of the @owners list, but + # sadly Ruby doesn't allow us to choose which one we wake up, so we wake + # them all up. + @cond.broadcast + end + end + + def with_ownership(&block) + # If we are in a nested with_ownership() call (nested pry context), we do nothing. + nested = @mutex.synchronize { @owners.include?(Thread.current) } + nested ? block.call : __with_ownership(&block) + end + + def enter_interruptible_region + @mutex.synchronize do + # We patiently wait until we are the owner. This may happen as another + # thread calls with_ownership() because of a binding.pry happening in + # another thread. + @cond.wait(@mutex) until @owners.last == Thread.current + + # We are the legitimate owner of the input. We mark ourselves as + # interruptible, so other threads can send us an Interrupt exception + # while we are blocking from reading the input. + @interruptible = true + end + end + + def leave_interruptible_region + @mutex.synchronize do + # We check if we are still the owner, because we could have received an + # Interrupt right after the following @cond.broadcast, making us retry. + @interruptible = false if @owners.last == Thread.current + @cond.broadcast + end + rescue Interrupt + # We need to guard against a spurious interrupt delivered while we are + # trying to acquire the lock (the rescue block is no longer in our scope). + retry + end + + def interruptible_region(&block) + enter_interruptible_region + + # XXX Note that there is a chance that we get the interrupt right after + # the readline call succeeded, but we'll never know, and we will retry the + # call, discarding that piece of input. + block.call + + rescue Interrupt + # We were asked to back off. The one requesting the interrupt will be + # waiting on the conditional for the interruptible flag to change to false. + # Note that there can be some inefficiency, as we could immediately + # succeed in enter_interruptible_region(), even before the one requesting + # the ownership has the chance to register itself as an owner. + # To mitigate the issue, we sleep a little bit. + leave_interruptible_region + sleep 0.01 + retry + + ensure + leave_interruptible_region + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/inspector.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/inspector.rb new file mode 100644 index 0000000..c56b02f --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/inspector.rb @@ -0,0 +1,27 @@ +class Pry::Inspector + MAP = { + "default" => { + value: Pry::DEFAULT_PRINT, + description: <<-DESCRIPTION.each_line.map(&:lstrip!) + The default Pry inspector. It has paging and color support, and uses + pretty_inspect when printing an object. + DESCRIPTION + }, + + "simple" => { + value: Pry::SIMPLE_PRINT, + description: <<-DESCRIPTION.each_line.map(&:lstrip) + A simple inspector that uses #puts and #inspect when printing an + object. It has no pager, color, or pretty_inspect support. + DESCRIPTION + }, + + "clipped" => { + value: Pry::CLIPPED_PRINT, + description: <<-DESCRIPTION.each_line.map(&:lstrip) + The clipped inspector has the same features as the 'simple' inspector + but prints large objects as a smaller string. + DESCRIPTION + } + } +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/last_exception.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/last_exception.rb new file mode 100644 index 0000000..2841113 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/last_exception.rb @@ -0,0 +1,61 @@ +# +# {Pry::LastException} is a proxy class who wraps an Exception object for +# {Pry#last_exception}. it extends the exception object with methods that +# help pry commands be useful. +# +# the original exception object is not modified and method calls are forwarded +# to the wrapped exception object. +# +class Pry::LastException < BasicObject + attr_accessor :bt_index + + def initialize(e) + @e = e + @bt_index = 0 + @file, @line = bt_source_location_for(0) + end + + def method_missing(name, *args, &block) + if @e.respond_to?(name) + @e.public_send(name, *args, &block) + else + super + end + end + + def respond_to_missing?(name, include_private = false) + @e.respond_to?(name) + end + + # + # @return [String] + # returns the path to a file for the current backtrace. see {#bt_index}. + # + def file + @file + end + + # + # @return [Fixnum] + # returns the line for the current backtrace. see {#bt_index}. + # + def line + @line + end + + # @return [Exception] + # returns the wrapped exception + # + def wrapped_exception + @e + end + + def bt_source_location_for(index) + backtrace[index] =~ /(.*):(\d+)/ + [$1, $2.to_i] + end + + def inc_bt_index + @bt_index = (@bt_index + 1) % backtrace.size + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/method.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/method.rb new file mode 100644 index 0000000..03eb60a --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/method.rb @@ -0,0 +1,546 @@ +require 'pry/helpers/documentation_helpers' + +class Pry + class << self + # If the given object is a `Pry::Method`, return it unaltered. If it's + # anything else, return it wrapped in a `Pry::Method` instance. + def Method(obj) + if obj.is_a? Pry::Method + obj + else + Pry::Method.new(obj) + end + end + end + + # This class wraps the normal `Method` and `UnboundMethod` classes + # to provide extra functionality useful to Pry. + class Method + require 'pry/method/weird_method_locator' + require 'pry/method/disowned' + require 'pry/method/patcher' + + extend Helpers::BaseHelpers + include Helpers::BaseHelpers + include Helpers::DocumentationHelpers + include CodeObject::Helpers + + class << self + # Given a string representing a method name and optionally a binding to + # search in, find and return the requested method wrapped in a `Pry::Method` + # instance. + # + # @param [String] name The name of the method to retrieve. + # @param [Binding] target The context in which to search for the method. + # @param [Hash] options + # @option options [Boolean] :instance Look for an instance method if `name` doesn't + # contain any context. + # @option options [Boolean] :methods Look for a bound/singleton method if `name` doesn't + # contain any context. + # @return [Pry::Method, nil] A `Pry::Method` instance containing the requested + # method, or `nil` if name is `nil` or no method could be located matching the parameters. + def from_str(name, target=TOPLEVEL_BINDING, options={}) + if name.nil? + nil + elsif name.to_s =~ /(.+)\#(\S+)\Z/ + context, meth_name = $1, $2 + from_module(target.eval(context), meth_name, target) + elsif name.to_s =~ /(.+)(\[\])\Z/ + context, meth_name = $1, $2 + from_obj(target.eval(context), meth_name, target) + elsif name.to_s =~ /(.+)(\.|::)(\S+)\Z/ + context, meth_name = $1, $3 + from_obj(target.eval(context), meth_name, target) + elsif options[:instance] + from_module(target.eval("self"), name, target) + elsif options[:methods] + from_obj(target.eval("self"), name, target) + else + from_str(name, target, :instance => true) or + from_str(name, target, :methods => true) + end + + rescue Pry::RescuableException + nil + end + + # Given a `Binding`, try to extract the `::Method` it originated from and + # use it to instantiate a `Pry::Method`. Return `nil` if this isn't + # possible. + # + # @param [Binding] b + # @return [Pry::Method, nil] + # + def from_binding(b) + meth_name = b.eval('::Kernel.__method__') + if [:__script__, nil].include?(meth_name) + nil + else + method = begin + if Object === b.eval('self') + new(Kernel.instance_method(:method).bind(b.eval("self")).call(meth_name)) + else + new(b.eval('class << self; self; end.instance_method(::Kernel.__method__).bind(self)')) + end + rescue NameError, NoMethodError + Disowned.new(b.eval('self'), meth_name.to_s) + end + + if WeirdMethodLocator.weird_method?(method, b) + WeirdMethodLocator.new(method, b).get_method || method + else + method + end + end + end + + # In order to support 2.0 Refinements we need to look up methods + # inside the relevant Binding. + # @param [Object] obj The owner/receiver of the method. + # @param [Symbol] method_name The name of the method. + # @param [Symbol] method_type The type of method: :method or :instance_method + # @param [Binding] target The binding where the method is looked up. + # @return [Method, UnboundMethod] The 'refined' method object. + def lookup_method_via_binding(obj, method_name, method_type, target=TOPLEVEL_BINDING) + Pry.current[:obj] = obj + Pry.current[:name] = method_name + receiver = obj.is_a?(Module) ? "Module" : "Kernel" + target.eval("::#{receiver}.instance_method(:#{method_type}).bind(Pry.current[:obj]).call(Pry.current[:name])") + ensure + Pry.current[:obj] = Pry.current[:name] = nil + end + + # Given a `Class` or `Module` and the name of a method, try to + # instantiate a `Pry::Method` containing the instance method of + # that name. Return `nil` if no such method exists. + # + # @param [Class, Module] klass + # @param [String] name + # @param [Binding] target The binding where the method is looked up. + # @return [Pry::Method, nil] + def from_class(klass, name, target=TOPLEVEL_BINDING) + new(lookup_method_via_binding(klass, name, :instance_method, target)) rescue nil + end + alias from_module from_class + + # Given an object and the name of a method, try to instantiate + # a `Pry::Method` containing the method of that name bound to + # that object. Return `nil` if no such method exists. + # + # @param [Object] obj + # @param [String] name + # @param [Binding] target The binding where the method is looked up. + # @return [Pry::Method, nil] + def from_obj(obj, name, target=TOPLEVEL_BINDING) + new(lookup_method_via_binding(obj, name, :method, target)) rescue nil + end + + # Get all of the instance methods of a `Class` or `Module` + # @param [Class,Module] klass + # @param [Boolean] include_super Whether to include methods from ancestors. + # @return [Array[Pry::Method]] + def all_from_class(klass, include_super=true) + %w(public protected private).map do |visibility| + safe_send(klass, :"#{visibility}_instance_methods", include_super).map do |method_name| + new(safe_send(klass, :instance_method, method_name), :visibility => visibility.to_sym) + end + end.flatten(1) + end + + # + # Get all of the methods on an `Object` + # + # @param [Object] obj + # + # @param [Boolean] include_super + # indicates whether or not to include methods from ancestors. + # + # @return [Array[Pry::Method]] + # + def all_from_obj(obj, include_super=true) + all_from_class(singleton_class_of(obj), include_super) + end + + # + # @deprecated + # please use {#all_from_obj} instead. + # the `method_type` argument is ignored. + # + def all_from_common(obj, method_type = nil, include_super=true) + all_from_obj(obj, include_super) + end + + # Get every `Class` and `Module`, in order, that will be checked when looking + # for an instance method to call on this object. + # @param [Object] obj + # @return [Array[Class, Module]] + def resolution_order(obj) + if Class === obj + singleton_class_resolution_order(obj) + instance_resolution_order(Class) + else + klass = singleton_class_of(obj) rescue obj.class + instance_resolution_order(klass) + end + end + + # Get every `Class` and `Module`, in order, that will be checked when looking + # for methods on instances of the given `Class` or `Module`. + # This does not treat singleton classes of classes specially. + # @param [Class, Module] klass + # @return [Array[Class, Module]] + def instance_resolution_order(klass) + # include klass in case it is a singleton class, + ([klass] + Pry::Method.safe_send(klass, :ancestors)).uniq + end + + def method_definition?(name, definition_line) + singleton_method_definition?(name, definition_line) || + instance_method_definition?(name, definition_line) + end + + def singleton_method_definition?(name, definition_line) + /^define_singleton_method\(?\s*[:\"\']#{Regexp.escape(name)}|^def\s*self\.#{Regexp.escape(name)}/ =~ definition_line.strip + end + + def instance_method_definition?(name, definition_line) + /^define_method\(?\s*[:\"\']#{Regexp.escape(name)}|^def\s*#{Regexp.escape(name)}/ =~ definition_line.strip + end + + # Get the singleton classes of superclasses that could define methods on + # the given class object, and any modules they include. + # If a module is included at multiple points in the ancestry, only + # the lowest copy will be returned. + def singleton_class_resolution_order(klass) + ancestors = Pry::Method.safe_send(klass, :ancestors) + resolution_order = ancestors.grep(Class).map do |anc| + [singleton_class_of(anc), *singleton_class_of(anc).included_modules] + end.flatten(1) + + resolution_order.reverse.uniq.reverse - Class.included_modules + end + + def singleton_class_of(obj) + begin + class << obj; self; end + rescue TypeError # can't define singleton. Fixnum, Symbol, Float, ... + obj.class + end + end + end + + # A new instance of `Pry::Method` wrapping the given `::Method`, `UnboundMethod`, or `Proc`. + # + # @param [::Method, UnboundMethod, Proc] method + # @param [Hash] known_info Can be used to pre-cache expensive to compute stuff. + # @return [Pry::Method] + def initialize(method, known_info={}) + @method = method + @visibility = known_info[:visibility] + end + + # Get the name of the method as a String, regardless of the underlying Method#name type. + # @return [String] + def name + @method.name.to_s + end + + # Get the owner of the method as a Pry::Module + # @return [Pry::Module] + def wrapped_owner + @wrapped_owner ||= Pry::WrappedModule.new(owner) + end + + # Get underlying object wrapped by this Pry::Method instance + # @return [Method, UnboundMethod, Proc] + def wrapped + @method + end + + # Is the method undefined? (aka `Disowned`) + # @return [Boolean] false + def undefined? + false + end + + # Get the name of the method including the class on which it was defined. + # @example + # method(:puts).method_name + # => "Kernel.puts" + # @return [String] + def name_with_owner + "#{wrapped_owner.method_prefix}#{name}" + end + + # @return [String, nil] The source code of the method, or `nil` if it's unavailable. + def source + @source ||= case source_type + when :c + c_source + when :ruby + ruby_source + end + end + + # Update the live copy of the method's source. + def redefine(source) + Patcher.new(self).patch_in_ram source + Pry::Method(owner.instance_method(name)) + end + + # Can we get the source code for this method? + # @return [Boolean] + def source? + !!source + rescue MethodSource::SourceNotFoundError + false + end + + # @return [String, nil] The documentation for the method, or `nil` if it's + # unavailable. + def doc + @doc ||= case source_type + when :c + info = pry_doc_info + info.docstring if info + when :ruby + get_comment_content(comment) + end + end + + # @return [Symbol] The source type of the method. The options are + # `:ruby` for Ruby methods or `:c` for methods written in C. + def source_type + source_location.nil? ? :c : :ruby + end + + # @return [String, nil] The name of the file the method is defined in, or + # `nil` if the filename is unavailable. + def source_file + if source_location.nil? + if !rbx? and source_type == :c + info = pry_doc_info + info.file if info + end + else + source_location.first + end + end + + # @return [Fixnum, nil] The line of code in `source_file` which begins + # the method's definition, or `nil` if that information is unavailable. + def source_line + source_location.nil? ? nil : source_location.last + end + + # @return [Range, nil] The range of lines in `source_file` which contain + # the method's definition, or `nil` if that information is unavailable. + def source_range + source_location.nil? ? nil : (source_line)..(source_line + source.lines.count - 1) + end + + # @return [Symbol] The visibility of the method. May be `:public`, + # `:protected`, or `:private`. + def visibility + @visibility ||= if owner.public_instance_methods.any? { |m| m.to_s == name } + :public + elsif owner.protected_instance_methods.any? { |m| m.to_s == name } + :protected + elsif owner.private_instance_methods.any? { |m| m.to_s == name } + :private + else + :none + end + end + + # @return [String] A representation of the method's signature, including its + # name and parameters. Optional and "rest" parameters are marked with `*` + # and block parameters with `&`. If the parameter names are unavailable, + # they're given numbered names instead. + # Paraphrased from `awesome_print` gem. + def signature + if respond_to?(:parameters) + args = parameters.inject([]) do |arr, (type, name)| + name ||= (type == :block ? 'block' : "arg#{arr.size + 1}") + arr << case type + when :req then name.to_s + when :opt then "#{name}=?" + when :rest then "*#{name}" + when :block then "&#{name}" + else '?' + end + end + else + args = (1..arity.abs).map { |i| "arg#{i}" } + args[-1] = "*#{args[-1]}" if arity < 0 + end + + "#{name}(#{args.join(', ')})" + end + + # @return [Pry::Method, nil] The wrapped method that is called when you + # use "super" in the body of this method. + def super(times=1) + if UnboundMethod === @method + sup = super_using_ancestors(Pry::Method.instance_resolution_order(owner), times) + else + sup = super_using_ancestors(Pry::Method.resolution_order(receiver), times) + sup &&= sup.bind(receiver) + end + Pry::Method.new(sup) if sup + end + + # @return [String, nil] The original name the method was defined under, + # before any aliasing, or `nil` if it can't be determined. + def original_name + return nil if source_type != :ruby + method_name_from_first_line(source.lines.first) + end + + # @return [Boolean] Was the method defined outside a source file? + def dynamically_defined? + !!(source_file and source_file =~ /(\(.*\))|<.*>/) + end + + # @return [Boolean] Whether the method is unbound. + def unbound_method? + is_a?(::UnboundMethod) + end + + # @return [Boolean] Whether the method is bound. + def bound_method? + is_a?(::Method) + end + + # @return [Boolean] Whether the method is a singleton method. + def singleton_method? + wrapped_owner.singleton_class? + end + + # @return [Boolean] Was the method defined within the Pry REPL? + def pry_method? + source_file == Pry.eval_path + end + + # @return [Array] All known aliases for the method. + def aliases + owner = @method.owner + # Avoid using `to_sym` on {Method#name}, which returns a `String`, because + # it won't be garbage collected. + name = @method.name + + all_methods_to_compare = owner.instance_methods | owner.private_instance_methods + alias_list = all_methods_to_compare.combination(2).select do |pair| + pair.include?(name) && + owner.instance_method(pair.first) == owner.instance_method(pair.last) + end.flatten + alias_list.delete(name) + + alias_list.map(&:to_s) + end + + # @return [Boolean] Is the method definitely an alias? + def alias? + name != original_name + end + + # @return [Boolean] + def ==(obj) + if obj.is_a? Pry::Method + obj == @method + else + @method == obj + end + end + + # @param [Class] klass + # @return [Boolean] + def is_a?(klass) + klass == Pry::Method or @method.is_a?(klass) + end + alias kind_of? is_a? + + # @param [String, Symbol] method_name + # @return [Boolean] + def respond_to?(method_name) + super or @method.respond_to?(method_name) + end + + # Delegate any unknown calls to the wrapped method. + def method_missing(method_name, *args, &block) + @method.send(method_name, *args, &block) + end + + def comment + Pry::Code.from_file(source_file).comment_describing(source_line) + end + + private + + # @return [YARD::CodeObjects::MethodObject] + # @raise [CommandError] when the method can't be found or `pry-doc` isn't installed. + def pry_doc_info + if Pry.config.has_pry_doc + Pry::MethodInfo.info_for(@method) or raise CommandError, "Cannot locate this method: #{name}. (source_location returns nil)" + else + fail_msg = "Cannot locate this method: #{name}." + if mri? + fail_msg += ' Try `gem-install pry-doc` to get access to Ruby Core documentation.' + end + raise CommandError, fail_msg + end + end + + # @param [Class, Module] ancestors The ancestors to investigate + # @return [Method] The unwrapped super-method + def super_using_ancestors(ancestors, times=1) + next_owner = self.owner + times.times do + i = ancestors.index(next_owner) + 1 + while ancestors[i] && !(ancestors[i].method_defined?(name) || ancestors[i].private_method_defined?(name)) + i += 1 + end + next_owner = ancestors[i] or return nil + end + + safe_send(next_owner, :instance_method, name) rescue nil + end + + # @param [String] first_ln The first line of a method definition. + # @return [String, nil] + def method_name_from_first_line(first_ln) + return nil if first_ln.strip !~ /^def / + + tokens = CodeRay.scan(first_ln, :ruby) + tokens = tokens.tokens.each_slice(2) if tokens.respond_to?(:tokens) + tokens.each_cons(2) do |t1, t2| + if t2.last == :method || t2.last == :ident && t1 == [".", :operator] + return t2.first + end + end + + nil + end + + def c_source + info = pry_doc_info + if info and info.source + strip_comments_from_c_code(info.source) + end + end + + def ruby_source + # clone of MethodSource.source_helper that knows to use our + # hacked version of source_location for rbx core methods, and + # our input buffer for methods defined in (pry) + file, line = *source_location + raise SourceNotFoundError, "Could not locate source for #{name_with_owner}!" unless file + + begin + code = Pry::Code.from_file(file).expression_at(line) + rescue SyntaxError => e + raise MethodSource::SourceNotFoundError.new(e.message) + end + strip_leading_whitespace(code) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/method/disowned.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/disowned.rb new file mode 100644 index 0000000..35908c9 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/disowned.rb @@ -0,0 +1,53 @@ +class Pry + class Method + # A Disowned Method is one that's been removed from the class on which it was defined. + # + # e.g. + # class C + # def foo + # C.send(:undefine_method, :foo) + # Pry::Method.from_binding(binding) + # end + # end + # + # In this case we assume that the "owner" is the singleton class of the receiver. + # + # This occurs mainly in Sinatra applications. + class Disowned < Method + attr_reader :receiver, :name + + # Create a new Disowned method. + # + # @param [Object] receiver + # @param [String] method_name + def initialize(receiver, method_name, binding=nil) + @receiver, @name = receiver, method_name + end + + # Is the method undefined? (aka `Disowned`) + # @return [Boolean] true + def undefined? + true + end + + # Can we get the source for this method? + # @return [Boolean] false + def source? + false + end + + # Get the hypothesized owner of the method. + # + # @return [Object] + def owner + class << receiver; self; end + end + + # Raise a more useful error message instead of trying to forward to nil. + def method_missing(meth_name, *args, &block) + raise "Cannot call '#{meth_name}' on an undef'd method." if method(:name).respond_to?(meth_name) + Object.instance_method(:method_missing).bind(self).call(meth_name, *args, &block) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/method/patcher.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/patcher.rb new file mode 100644 index 0000000..3f736f6 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/patcher.rb @@ -0,0 +1,125 @@ +class Pry + class Method + class Patcher + attr_accessor :method + + @@source_cache = {} + + def initialize(method) + @method = method + end + + def self.code_for(filename) + @@source_cache[filename] + end + + # perform the patch + def patch_in_ram(source) + if method.alias? + with_method_transaction do + redefine source + end + else + redefine source + end + end + + private + + def redefine(source) + @@source_cache[cache_key] = source + TOPLEVEL_BINDING.eval wrap(source), cache_key + end + + def cache_key + "pry-redefined(0x#{method.owner.object_id.to_s(16)}##{method.name})" + end + + # Run some code ensuring that at the end target#meth_name will not have changed. + # + # When we're redefining aliased methods we will overwrite the method at the + # unaliased name (so that super continues to work). By wrapping that code in a + # transation we make that not happen, which means that alias_method_chains, etc. + # continue to work. + # + # @param [String] meth_name The method name before aliasing + # @param [Module] target The owner of the method + + def with_method_transaction + temp_name = "__pry_#{method.original_name}__" + method = self.method + method.owner.class_eval do + alias_method temp_name, method.original_name + yield + alias_method method.name, method.original_name + alias_method method.original_name, temp_name + end + + ensure + method.send(:remove_method, temp_name) rescue nil + end + + # Update the definition line so that it can be eval'd directly on the Method's + # owner instead of from the original context. + # + # In particular this takes `def self.foo` and turns it into `def foo` so that we + # don't end up creating the method on the singleton class of the singleton class + # by accident. + # + # This is necessarily done by String manipulation because we can't find out what + # syntax is needed for the argument list by ruby-level introspection. + # + # @param [String] line The original definition line. e.g. def self.foo(bar, baz=1) + # @return [String] The new definition line. e.g. def foo(bar, baz=1) + def definition_for_owner(line) + if line =~ /\Adef (?:.*?\.)?#{Regexp.escape(method.original_name)}(?=[\(\s;]|$)/ + "def #{method.original_name}#{$'}" + else + raise CommandError, "Could not find original `def #{method.original_name}` line to patch." + end + end + + # Apply wrap_for_owner and wrap_for_nesting successively to `source` + # @param [String] source + # @return [String] The wrapped source. + def wrap(source) + wrap_for_nesting(wrap_for_owner(source)) + end + + # Update the source code so that when it has the right owner when eval'd. + # + # This (combined with definition_for_owner) is backup for the case that + # wrap_for_nesting fails, to ensure that the method will stil be defined in + # the correct place. + # + # @param [String] source The source to wrap + # @return [String] + def wrap_for_owner(source) + Pry.current[:pry_owner] = method.owner + owner_source = definition_for_owner(source) + visibility_fix = "#{method.visibility.to_s} #{method.name.to_sym.inspect}" + "Pry.current[:pry_owner].class_eval do; #{owner_source}\n#{visibility_fix}\nend" + end + + # Update the new source code to have the correct Module.nesting. + # + # This method uses syntactic analysis of the original source file to determine + # the new nesting, so that we can tell the difference between: + # + # class A; def self.b; end; end + # class << A; def b; end; end + # + # The resulting code should be evaluated in the TOPLEVEL_BINDING. + # + # @param [String] source The source to wrap. + # @return [String] + def wrap_for_nesting(source) + nesting = Pry::Code.from_file(method.source_file).nesting_at(method.source_line) + + (nesting + [source] + nesting.map{ "end" } + [""]).join(";") + rescue Pry::Indent::UnparseableNestingError + source + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/method/weird_method_locator.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/weird_method_locator.rb new file mode 100644 index 0000000..b64b710 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/method/weird_method_locator.rb @@ -0,0 +1,186 @@ +class Pry + class Method + + # This class is responsible for locating the *real* `Pry::Method` + # object captured by a binding. + # + # Given a `Binding` from inside a method and a 'seed' Pry::Method object, + # there are primarily two situations where the seed method doesn't match + # the Binding: + # 1. The Pry::Method is from a subclass 2. The Pry::Method represents a method of the same name + # while the original was renamed to something else. For 1. we + # search vertically up the inheritance chain, + # and for 2. we search laterally along the object's method table. + # + # When we locate the method that matches the Binding we wrap it in + # Pry::Method and return it, or return nil if we fail. + class WeirdMethodLocator + class << self + + # Whether the given method object matches the associated binding. + # If the method object does not match the binding, then it's + # most likely not the method captured by the binding, and we + # must commence a search. + # + # @param [Pry::Method] method + # @param [Binding] b + # @return [Boolean] + def normal_method?(method, b) + method && (method.source_file && method.source_range rescue false) && + File.expand_path(method.source_file) == File.expand_path(b.eval('__FILE__')) && + method.source_range.include?(b.eval('__LINE__')) + end + + def weird_method?(method, b) + !normal_method?(method, b) + end + end + + attr_accessor :method + attr_accessor :target + + # @param [Pry::Method] method The seed method. + # @param [Binding] target The Binding that captures the method + # we want to locate. + def initialize(method, target) + @method, @target = method, target + end + + # @return [Pry::Method, nil] The Pry::Method that matches the + # given binding. + def get_method + find_method_in_superclass || find_renamed_method + end + + # @return [Boolean] Whether the Pry::Method is unrecoverable + # This usually happens when the method captured by the Binding + # has been subsequently deleted. + def lost_method? + !!(get_method.nil? && renamed_method_source_location) + end + + private + + def normal_method?(method) + self.class.normal_method?(method, target) + end + + def target_self + target.eval('self') + end + + def target_file + pry_file? ? target.eval('__FILE__') : File.expand_path(target.eval('__FILE__')) + end + + def target_line + target.eval('__LINE__') + end + + def pry_file? + Pry.eval_path == target.eval('__FILE__') + end + + # it's possible in some cases that the method we find by this approach is a sub-method of + # the one we're currently in, consider: + # + # class A; def b; binding.pry; end; end + # class B < A; def b; super; end; end + # + # Given that we can normally find the source_range of methods, and that we know which + # __FILE__ and __LINE__ the binding is at, we can hope to disambiguate these cases. + # + # This obviously won't work if the source is unavaiable for some reason, or if both + # methods have the same __FILE__ and __LINE__, or if we're in rbx where b.eval('__LINE__') + # is broken. + # + # @return [Pry::Method, nil] The Pry::Method representing the + # superclass method. + def find_method_in_superclass + guess = method + + while guess + # needs rescue if this is a Disowned method or a C method or something... + # TODO: Fix up the exception handling so we don't need a bare rescue + if normal_method?(guess) + return guess + else + guess = guess.super + end + end + + # Uhoh... none of the methods in the chain had the right __FILE__ and __LINE__ + # This may be caused by rbx https://github.com/rubinius/rubinius/issues/953, + # or other unknown circumstances (TODO: we should warn the user when this happens) + nil + end + + # This is the case where the name of a method has changed + # (via alias_method) so we locate the Method object for the + # renamed method. + # + # @return [Pry::Method, nil] The Pry::Method representing the + # renamed method + def find_renamed_method + return if !valid_file?(target_file) + alias_name = all_methods_for(target_self).find do |v| + expanded_source_location(target_self.method(v).source_location) == renamed_method_source_location + end + + alias_name && Pry::Method(target_self.method(alias_name)) + end + + def expanded_source_location(sl) + return if !sl + + if pry_file? + sl + else + [File.expand_path(sl.first), sl.last] + end + end + + # Use static analysis to locate the start of the method definition. + # We have the `__FILE__` and `__LINE__` from the binding and the + # original name of the method so we search up until we find a + # def/define_method, etc defining a method of the appropriate name. + # + # @return [Array] The `source_location` of the + # renamed method + def renamed_method_source_location + return @original_method_source_location if defined?(@original_method_source_location) + + source_index = lines_for_file(target_file)[0..(target_line - 1)].rindex do |v| + Pry::Method.method_definition?(method.name, v) + end + + @original_method_source_location = source_index && + [target_file, index_to_line_number(source_index)] + end + + def index_to_line_number(index) + # Pry.line_buffer is 0-indexed + pry_file? ? index : index + 1 + end + + def valid_file?(file) + (File.exists?(file) && !File.directory?(file)) || Pry.eval_path == file + end + + def lines_for_file(file) + @lines_for_file ||= {} + @lines_for_file[file] ||= if Pry.eval_path == file + Pry.line_buffer + else + File.readlines(file) + end + end + + def all_methods_for(obj) + obj.public_methods(false) + + obj.private_methods(false) + + obj.protected_methods(false) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/module_candidate.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/module_candidate.rb new file mode 100644 index 0000000..4c97f13 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/module_candidate.rb @@ -0,0 +1,136 @@ +require 'pry/helpers/documentation_helpers' +require 'forwardable' + +class Pry + class WrappedModule + + # This class represents a single candidate for a module/class definition. + # It provides access to the source, documentation, line and file + # for a monkeypatch (reopening) of a class/module. + class Candidate + include Pry::Helpers::DocumentationHelpers + include Pry::CodeObject::Helpers + extend Forwardable + + # @return [String] The file where the module definition is located. + attr_reader :file + alias_method :source_file, :file + + # @return [Fixnum] The line where the module definition is located. + attr_reader :line + alias_method :source_line, :line + + # Methods to delegate to associated `Pry::WrappedModule + # instance`. + private_delegates = [:lines_for_file, :method_candidates, + :yard_docs?] + + public_delegates = [:wrapped, :module?, :class?, :name, :nonblank_name, + :number_of_candidates] + + def_delegators :@wrapper, *(private_delegates + public_delegates) + private(*private_delegates) + public(*public_delegates) + + # @raise [Pry::CommandError] If `rank` is out of bounds. + # @param [Pry::WrappedModule] wrapper The associated + # `Pry::WrappedModule` instance that owns the candidates. + # @param [Fixnum] rank The rank of the candidate to + # retrieve. Passing 0 returns 'primary candidate' (the candidate with largest + # number of methods), passing 1 retrieves candidate with + # second largest number of methods, and so on, up to + # `Pry::WrappedModule#number_of_candidates() - 1` + def initialize(wrapper, rank) + @wrapper = wrapper + + if number_of_candidates <= 0 + raise CommandError, "Cannot find a definition for #{name} module!" + elsif rank > (number_of_candidates - 1) + raise CommandError, "No such module candidate. Allowed candidates range is from 0 to #{number_of_candidates - 1}" + end + + @rank = rank + @file, @line = source_location + end + + # @raise [Pry::CommandError] If source code cannot be found. + # @return [String] The source for the candidate, i.e the + # complete module/class definition. + def source + return nil if file.nil? + return @source if @source + + @source = strip_leading_whitespace(Pry::Code.from_file(file).expression_at(line, number_of_lines_in_first_chunk)) + end + + # @raise [Pry::CommandError] If documentation cannot be found. + # @return [String] The documentation for the candidate. + def doc + return nil if file.nil? + return @doc if @doc + + @doc = get_comment_content(Pry::Code.from_file(file).comment_describing(line)) + end + + # @return [Array, nil] A `[String, Fixnum]` pair representing the + # source location (file and line) for the candidate or `nil` + # if no source location found. + def source_location + return @source_location if @source_location + + file, line = first_method_source_location + return nil if !file.is_a?(String) + + @source_location = [file, first_line_of_module_definition(file, line)] + rescue Pry::RescuableException + nil + end + + private + + # Locate the first line of the module definition. + # @param [String] file The file that contains the module + # definition (somewhere). + # @param [Fixnum] line The module definition should appear + # before this line (if it exists). + # @return [Fixnum] The line where the module is defined. This + # line number is one-indexed. + def first_line_of_module_definition(file, line) + searchable_lines = lines_for_file(file)[0..(line - 2)] + searchable_lines.rindex { |v| class_regexes.any? { |r| r =~ v } } + 1 + end + + def class_regexes + mod_type_string = wrapped.class.to_s.downcase + [/^\s*#{mod_type_string}\s+(?:(?:\w*)::)*?#{wrapped.name.split(/::/).last}/, + /^\s*(::)?#{wrapped.name.split(/::/).last}\s*?=\s*?#{wrapped.class}/, + /^\s*(::)?#{wrapped.name.split(/::/).last}\.(class|instance)_eval/] + end + + # This method is used by `Candidate#source_location` as a + # starting point for the search for the candidate's definition. + # @return [Array] The source location of the base method used to + # calculate the source location of the candidate. + def first_method_source_location + @first_method_source_location ||= method_candidates[@rank].first.source_location + end + + # @return [Array] The source location of the last method in this + # candidate's module definition. + def last_method_source_location + @end_method_source_location ||= method_candidates[@rank].last.source_location + end + + # Return the number of lines between the start of the class definition + # and the start of the last method. We use this value so we can + # quickly grab these lines from the file (without having to + # check each intervening line for validity, which is expensive) speeding up source extraction. + # @return [Fixum] Number of lines. + def number_of_lines_in_first_chunk + end_method_line = last_method_source_location.last + + end_method_line - line + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/object_path.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/object_path.rb new file mode 100644 index 0000000..5bffb02 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/object_path.rb @@ -0,0 +1,82 @@ +class Pry + # `ObjectPath` implements the resolution of "object paths", which are strings + # that are similar to filesystem paths but meant for traversing Ruby objects. + # Examples of valid object paths include: + # + # x + # @foo/@bar + # "string"/upcase + # Pry/Method + # + # Object paths are mostly relevant in the context of the `cd` command. + # @see https://github.com/pry/pry/wiki/State-navigation + class ObjectPath + SPECIAL_TERMS = ["", "::", ".", ".."] + + # @param [String] path_string The object path expressed as a string. + # @param [Array] current_stack The current state of the binding + # stack. + def initialize(path_string, current_stack) + @path_string = path_string + @current_stack = current_stack + end + + # @return [Array] a new stack resulting from applying the given + # path to the current stack. + def resolve + scanner = StringScanner.new(@path_string.strip) + stack = @current_stack.dup + + begin + next_segment = "" + + loop do + # Scan for as long as we don't see a slash + next_segment << scanner.scan(/[^\/]*/) + + if complete?(next_segment) || scanner.eos? + scanner.getch # consume the slash + break + else + next_segment << scanner.getch # append the slash + end + end + + case next_segment.chomp + when "" + stack = [stack.first] + when "::" + stack.push(TOPLEVEL_BINDING) + when "." + next + when ".." + stack.pop unless stack.size == 1 + else + stack.push(Pry.binding_for(stack.last.eval(next_segment))) + end + rescue RescuableException => e + return handle_failure(next_segment, e) + end until scanner.eos? + + stack + end + + private + + def complete?(segment) + SPECIAL_TERMS.include?(segment) || Pry::Code.complete_expression?(segment) + end + + def handle_failure(context, err) + msg = [ + "Bad object path: #{@path_string.inspect}", + "Failed trying to resolve: #{context.inspect}", + "Exception: #{err.inspect}" + ].join("\n") + + raise CommandError.new(msg).tap { |e| + e.set_backtrace err.backtrace + } + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/output.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/output.rb new file mode 100644 index 0000000..b5f6bb3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/output.rb @@ -0,0 +1,50 @@ +class Pry + class Output + attr_reader :_pry_ + + def initialize(_pry_) + @_pry_ = _pry_ + end + + def puts(*objs) + return print "\n" if objs.empty? + + objs.each do |obj| + if ary = Array.try_convert(obj) + puts(*ary) + else + print "#{obj.to_s.chomp}\n" + end + end + + nil + end + + def print(*objs) + objs.each do |obj| + _pry_.config.output.print decolorize_maybe(obj.to_s) + end + + nil + end + alias << print + alias write print + + # If _pry_.config.color is currently false, removes ansi escapes from the string. + def decolorize_maybe(str) + if _pry_.config.color + str + else + Helpers::Text.strip_color str + end + end + + def method_missing(name, *args, &block) + _pry_.config.output.send(name, *args, &block) + end + + def respond_to_missing?(*a) + _pry_.config.respond_to?(*a) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/pager.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/pager.rb new file mode 100644 index 0000000..0c9c73d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/pager.rb @@ -0,0 +1,235 @@ +require 'pry/terminal' + +# A pager is an `IO`-like object that accepts text and either prints it +# immediately, prints it one page at a time, or streams it to an external +# program to print one page at a time. +class Pry::Pager + class StopPaging < StandardError + end + + attr_reader :_pry_ + + def initialize(_pry_) + @_pry_ = _pry_ + end + + # Send the given text through the best available pager (if `Pry.config.pager` is + # enabled). + # If you want to send text through in chunks as you generate it, use `open` to + # get a writable object instead. + # @param [String] text A piece of text to run through a pager. + # @param [IO] output (`$stdout`) An object to send output to. + def page(text) + open do |pager| + pager << text + end + end + + # Yields a pager object (`NullPager`, `SimplePager`, or `SystemPager`). All + # pagers accept output with `#puts`, `#print`, `#write`, and `#<<`. + # @param [IO] output (`$stdout`) An object to send output to. + def open + pager = best_available + yield pager + rescue StopPaging + ensure + pager.close if pager + end + + private + + attr_reader :output + def enabled?; !!@enabled; end + + # Return an instance of the "best" available pager class -- `SystemPager` if + # possible, `SimplePager` if `SystemPager` isn't available, and `NullPager` + # if the user has disabled paging. All pagers accept output with `#puts`, + # `#print`, `#write`, and `#<<`. You must call `#close` when you're done + # writing output to a pager, and you must rescue `Pry::Pager::StopPaging`. + # These requirements can be avoided by using `.open` instead. + # @param [#<<] output ($stdout) An object to send output to. + def best_available + if !_pry_.config.pager + NullPager.new(_pry_.output) + elsif !SystemPager.available? || Pry::Helpers::BaseHelpers.jruby? + SimplePager.new(_pry_.output) + else + SystemPager.new(_pry_.output) + end + end + + # `NullPager` is a "pager" that actually just prints all output as it comes + # in. Used when `Pry.config.pager` is false. + class NullPager + def initialize(out) + @out = out + end + + def puts(str) + print "#{str.chomp}\n" + end + + def print(str) + write str + end + alias << print + + def write(str) + @out.write str + end + + def close + end + + private + + def height + @height ||= Pry::Terminal.height! + end + + def width + @width ||= Pry::Terminal.width! + end + end + + # `SimplePager` is a straightforward pure-Ruby pager. We use it on JRuby and + # when we can't find a usable external pager. + class SimplePager < NullPager + def initialize(*) + super + @tracker = PageTracker.new(height - 3, width) + end + + def write(str) + str.lines.each do |line| + @out.print line + @tracker.record line + + if @tracker.page? + @out.print "\n" + @out.print "\e[0m" + @out.print " --- Press enter to continue " \ + "( q to break ) --- \n" + raise StopPaging if Readline.readline("").chomp == "q" + @tracker.reset + end + end + end + end + + # `SystemPager` buffers output until we're pretty sure it's at least a page + # long, then invokes an external pager and starts streaming output to it. If + # `#close` is called before then, it just prints out the buffered content. + class SystemPager < NullPager + def self.default_pager + pager = ENV["PAGER"] || "" + + # Default to less, and make sure less is being passed the correct options + if pager.strip.empty? or pager =~ /^less\b/ + pager = "less -R -F -X" + end + + pager + end + + def self.available? + if @system_pager.nil? + @system_pager = begin + pager_executable = default_pager.split(' ').first + `which #{pager_executable}` + $?.success? + rescue + false + end + else + @system_pager + end + end + + def initialize(*) + super + @tracker = PageTracker.new(height, width) + @buffer = "" + end + + def write(str) + if invoked_pager? + write_to_pager str + else + @tracker.record str + @buffer << str + + if @tracker.page? + write_to_pager @buffer + end + end + rescue Errno::EPIPE + raise StopPaging + end + + def close + if invoked_pager? + pager.close + else + @out.puts @buffer + end + end + + private + + def write_to_pager(text) + pager.write @out.decolorize_maybe(text) + end + + def invoked_pager? + @pager + end + + def pager + @pager ||= IO.popen(self.class.default_pager, 'w') + end + end + + # `PageTracker` tracks output to determine whether it's likely to take up a + # whole page. This doesn't need to be super precise, but we can use it for + # `SimplePager` and to avoid invoking the system pager unnecessarily. + # + # One simplifying assumption is that we don't need `#page?` to return `true` + # on the basis of an incomplete line. Long lines should be counted as + # multiple lines, but we don't have to transition from `false` to `true` + # until we see a newline. + class PageTracker + def initialize(rows, cols) + @rows, @cols = rows, cols + reset + end + + def record(str) + str.lines.each do |line| + if line.end_with? "\n" + @row += ((@col + line_length(line) - 1) / @cols) + 1 + @col = 0 + else + @col += line_length(line) + end + end + end + + def page? + @row >= @rows + end + + def reset + @row = 0 + @col = 0 + end + + private + + # Approximation of the printable length of a given line, without the + # newline and without ANSI color codes. + def line_length(line) + line.chomp.gsub(/\e\[[\d;]*m/, '').length + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/plugins.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/plugins.rb new file mode 100644 index 0000000..0813be3 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/plugins.rb @@ -0,0 +1,103 @@ +class Pry + class PluginManager + PRY_PLUGIN_PREFIX = /^pry-/ + + # Placeholder when no associated gem found, displays warning + class NoPlugin + def initialize(name) + @name = name + end + + def method_missing(*args) + warn "Warning: The plugin '#{@name}' was not found! (no gem found)" + end + end + + class Plugin + attr_accessor :name, :gem_name, :enabled, :spec, :active + + def initialize(name, gem_name, spec, enabled) + @name, @gem_name, @enabled, @spec = name, gem_name, enabled, spec + end + + # Disable a plugin. (prevents plugin from being loaded, cannot + # disable an already activated plugin) + def disable! + self.enabled = false + end + + # Enable a plugin. (does not load it immediately but puts on + # 'white list' to be loaded) + def enable! + self.enabled = true + end + + # Load the Command line options defined by this plugin (if they exist) + def load_cli_options + cli_options_file = File.join(spec.full_gem_path, "lib/#{spec.name}/cli.rb") + require cli_options_file if File.exists?(cli_options_file) + end + # Activate the plugin (require the gem - enables/loads the + # plugin immediately at point of call, even if plugin is + # disabled) + # Does not reload plugin if it's already active. + def activate! + # Create the configuration object for the plugin. + Pry.config.send("#{gem_name.gsub('-', '_')}=", Pry::Config.from_hash({})) + + begin + require gem_name if !active? + rescue LoadError => e + warn "Found plugin #{gem_name}, but could not require '#{gem_name}'" + warn e + rescue => e + warn "require '#{gem_name}' # Failed, saying: #{e}" + end + + self.active = true + self.enabled = true + end + + alias active? active + alias enabled? enabled + end + + def initialize + @plugins = [] + end + + # Find all installed Pry plugins and store them in an internal array. + def locate_plugins + Gem.refresh + (Gem::Specification.respond_to?(:each) ? Gem::Specification : Gem.source_index.find_name('')).each do |gem| + next if gem.name !~ PRY_PLUGIN_PREFIX + plugin_name = gem.name.split('-', 2).last + @plugins << Plugin.new(plugin_name, gem.name, gem, true) if !gem_located?(gem.name) + end + @plugins + end + + # @return [Hash] A hash with all plugin names (minus the 'pry-') as + # keys and Plugin objects as values. + def plugins + h = Hash.new { |_, key| NoPlugin.new(key) } + @plugins.each do |plugin| + h[plugin.name] = plugin + end + h + end + + # Require all enabled plugins, disabled plugins are skipped. + def load_plugins + @plugins.each do |plugin| + plugin.activate! if plugin.enabled? + end + end + + private + def gem_located?(gem_name) + @plugins.any? { |plugin| plugin.gem_name == gem_name } + end + end + +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/prompt.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/prompt.rb new file mode 100644 index 0000000..62f0bc1 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/prompt.rb @@ -0,0 +1,26 @@ +class Pry::Prompt + MAP = { + "default" => { + value: Pry::DEFAULT_PROMPT, + description: "The default Pry prompt. Includes information about the\n" \ + "current expression number, evaluation context, and nesting\n" \ + "level, plus a reminder that you're using Pry." + }, + + "simple" => { + value: Pry::SIMPLE_PROMPT, + description: "A simple '>>'." + }, + + "nav" => { + value: Pry::NAV_PROMPT, + description: "A prompt that displays the binding stack as a path and\n" \ + "includes information about _in_ and _out_." + }, + + "none" => { + value: Pry::NO_PROMPT, + description: "Wave goodbye to the Pry prompt." + } + } +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_class.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_class.rb new file mode 100644 index 0000000..e9e97b9 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_class.rb @@ -0,0 +1,375 @@ +require 'pry/config' +class Pry + + HOME_RC_FILE = ENV["PRYRC"] || "~/.pryrc" + LOCAL_RC_FILE = "./.pryrc" + + class << self + extend Forwardable + attr_accessor :custom_completions + attr_accessor :current_line + attr_accessor :line_buffer + attr_accessor :eval_path + attr_accessor :cli + attr_accessor :quiet + attr_accessor :last_internal_error + attr_accessor :config + attr_writer :history + + def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins + + extend Pry::Config::Convenience + config_shortcut *Pry::Config.shortcuts + + def prompt=(value) + config.prompt = value + end + + def prompt + config.prompt + end + + def history + @history ||= History.new + end + end + + # + # @return [main] + # returns the special instance of Object, "main". + # + def self.main + @main ||= TOPLEVEL_BINDING.eval "self" + end + + # + # @return [Pry::Config] + # Returns a value store for an instance of Pry running on the current thread. + # + def self.current + Thread.current[:__pry__] ||= Pry::Config.from_hash({}, nil) + end + + # Load the given file in the context of `Pry.toplevel_binding` + # @param [String] file The unexpanded file path. + def self.load_file_at_toplevel(file) + toplevel_binding.eval(File.read(file), file) + rescue RescuableException => e + puts "Error loading #{file}: #{e}\n#{e.backtrace.first}" + end + + # Load HOME_RC_FILE and LOCAL_RC_FILE if appropriate + # This method can also be used to reload the files if they have changed. + def self.load_rc_files + rc_files_to_load.each do |file| + critical_section do + load_file_at_toplevel(file) + end + end + end + + # Load the local RC file (./.pryrc) + def self.rc_files_to_load + files = [] + files << HOME_RC_FILE if Pry.config.should_load_rc + files << LOCAL_RC_FILE if Pry.config.should_load_local_rc + files.map { |file| real_path_to(file) }.compact.uniq + end + + # Expand a file to its canonical name (following symlinks as appropriate) + def self.real_path_to(file) + expanded = Pathname.new(File.expand_path(file)).realpath.to_s + # For rbx 1.9 mode [see rubinius issue #2165] + File.exist?(expanded) ? expanded : nil + rescue Errno::ENOENT + nil + end + + # Load any Ruby files specified with the -r flag on the command line. + def self.load_requires + Pry.config.requires.each do |file| + require file + end + end + + # Trap interrupts on jruby, and make them behave like MRI so we can + # catch them. + def self.load_traps + trap('INT'){ raise Interrupt } + end + + def self.load_win32console + begin + require 'win32console' + # The mswin and mingw versions of pry require win32console, so this should + # only fail on jruby (where win32console doesn't work). + # Instead we'll recommend ansicon, which does. + rescue LoadError + warn <<-WARNING if Pry.config.windows_console_warning +For a better Pry experience on Windows, please use ansicon: + https://github.com/adoxa/ansicon +If you use an alternative to ansicon and don't want to see this warning again, +you can add "Pry.config.windows_console_warning = false" to your .pryrc. + WARNING + end + end + + # Do basic setup for initial session. + # Including: loading .pryrc, loading plugins, loading requires, and + # loading history. + def self.initial_session_setup + return unless initial_session? + @initial_session = false + + # note these have to be loaded here rather than in pry_instance as + # we only want them loaded once per entire Pry lifetime. + load_rc_files + load_plugins if Pry.config.should_load_plugins + load_requires if Pry.config.should_load_requires + load_history if Pry.config.history.should_load + load_traps if Pry.config.should_trap_interrupts + load_win32console if Pry::Helpers::BaseHelpers.windows? && !Pry::Helpers::BaseHelpers.windows_ansi? + end + + # Start a Pry REPL. + # This method also loads `~/.pryrc` and `./.pryrc` as necessary the + # first time it is invoked. + # @param [Object, Binding] target The receiver of the Pry session + # @param [Hash] options + # @option options (see Pry#initialize) + # @example + # Pry.start(Object.new, :input => MyInput.new) + def self.start(target=nil, options={}) + return if ENV['DISABLE_PRY'] + options = options.to_hash + + if in_critical_section? + output.puts "ERROR: Pry started inside Pry." + output.puts "This can happen if you have a binding.pry inside a #to_s or #inspect function." + return + end + + options[:target] = Pry.binding_for(target || toplevel_binding) + options[:hooks] = Pry::Hooks.from_hash options.delete(:hooks) if options.key?(:hooks) + initial_session_setup + + # Unless we were given a backtrace, save the current one + if options[:backtrace].nil? + options[:backtrace] = caller + + # If Pry was started via `binding.pry`, elide that from the backtrace + if options[:backtrace].first =~ /pry.*core_extensions.*pry/ + options[:backtrace].shift + end + end + + driver = options[:driver] || Pry::REPL + + # Enter the matrix + driver.start(options) + rescue Pry::TooSafeException + puts "ERROR: Pry cannot work with $SAFE > 0" + raise + end + + # Execute the file through the REPL loop, non-interactively. + # @param [String] file_name File name to load through the REPL. + def self.load_file_through_repl(file_name) + require "pry/repl_file_loader" + REPLFileLoader.new(file_name).load + end + + # + # An inspector that clips the output to `max_length` chars. + # In case of > `max_length` chars the `# notation is used. + # + # @param [Object] obj + # The object to view. + # + # @param [Hash] options + # @option options [Integer] :max_length (60) + # The maximum number of chars before clipping occurs. + # + # @option options [Boolean] :id (false) + # Boolean to indicate whether or not a hex reprsentation of the object ID + # is attached to the return value when the length of inspect is greater than + # value of `:max_length`. + # + # @return [String] + # The string representation of `obj`. + # + def self.view_clip(obj, options = {}) + max = options.fetch :max_length, 60 + id = options.fetch :id, false + if obj.kind_of?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max + obj.name.to_s + elsif Pry.main == obj + # special-case to support jruby. + # fixed as of https://github.com/jruby/jruby/commit/d365ebd309cf9df3dde28f5eb36ea97056e0c039 + # we can drop in the future. + obj.to_s + elsif Pry.config.prompt_safe_objects.any? { |v| v === obj } && obj.inspect.length <= max + obj.inspect + else + id == true ? "#<#{obj.class}:0x%x>" % (obj.object_id << 1) : "#<#{obj.class}>" + end + rescue RescuableException + "unknown" + end + + # Load Readline history if required. + def self.load_history + Pry.history.load + end + + # @return [Boolean] Whether this is the first time a Pry session has + # been started since loading the Pry class. + def self.initial_session? + @initial_session + end + + # Run a Pry command from outside a session. The commands available are + # those referenced by `Pry.config.commands` (the default command set). + # @param [String] command_string The Pry command (including arguments, + # if any). + # @param [Hash] options Optional named parameters. + # @return [Object] The return value of the Pry command. + # @option options [Object, Binding] :target The object to run the + # command under. Defaults to `TOPLEVEL_BINDING` (main). + # @option options [Boolean] :show_output Whether to show command + # output. Defaults to true. + # @example Run at top-level with no output. + # Pry.run_command "ls" + # @example Run under Pry class, returning only public methods. + # Pry.run_command "ls -m", :target => Pry + # @example Display command output. + # Pry.run_command "ls -av", :show_output => true + def self.run_command(command_string, options={}) + options = { + :target => TOPLEVEL_BINDING, + :show_output => true, + :output => Pry.config.output, + :commands => Pry.config.commands + }.merge!(options) + + # :context for compatibility with <= 0.9.11.4 + target = options[:context] || options[:target] + output = options[:show_output] ? options[:output] : StringIO.new + + pry = Pry.new(:output => output, :target => target, :commands => options[:commands]) + pry.eval command_string + end + + def self.default_editor_for_platform + return ENV['VISUAL'] if ENV['VISUAL'] and not ENV['VISUAL'].empty? + return ENV['EDITOR'] if ENV['EDITOR'] and not ENV['EDITOR'].empty? + if Helpers::BaseHelpers.windows? + 'notepad' + else + %w(editor nano vi).detect do |editor| + system("which #{editor} > /dev/null 2>&1") + end + end + end + + def self.auto_resize! + Pry.config.input # by default, load Readline + + if !defined?(Readline) || Pry.config.input != Readline + warn "Sorry, you must be using Readline for Pry.auto_resize! to work." + return + end + + if Readline::VERSION =~ /edit/i + warn <<-EOT +Readline version #{Readline::VERSION} detected - will not auto_resize! correctly. + For the fix, use GNU Readline instead: + https://github.com/guard/guard/wiki/Add-proper-Readline-support-to-Ruby-on-Mac-OS-X + EOT + return + end + + trap :WINCH do + begin + Readline.set_screen_size(*Terminal.size!) + rescue => e + warn "\nPry.auto_resize!'s Readline.set_screen_size failed: #{e}" + end + begin + Readline.refresh_line + rescue => e + warn "\nPry.auto_resize!'s Readline.refresh_line failed: #{e}" + end + end + end + + # Set all the configurable options back to their default values + def self.reset_defaults + @initial_session = true + self.config = Pry::Config.new Pry::Config::Default.new + self.cli = false + self.current_line = 1 + self.line_buffer = [""] + self.eval_path = "(pry)" + end + + # Basic initialization. + def self.init + @plugin_manager ||= PluginManager.new + reset_defaults + locate_plugins + end + + # Return a `Binding` object for `target` or return `target` if it is + # already a `Binding`. + # In the case where `target` is top-level then return `TOPLEVEL_BINDING` + # @param [Object] target The object to get a `Binding` object for. + # @return [Binding] The `Binding` object. + def self.binding_for(target) + if Binding === target + target + else + if Pry.main == target + TOPLEVEL_BINDING + else + target.__binding__ + end + end + end + + def self.toplevel_binding + unless defined?(@toplevel_binding) && @toplevel_binding + # Grab a copy of the TOPLEVEL_BINDING without any local variables. + # This binding has a default definee of Object, and new methods are + # private (just as in TOPLEVEL_BINDING). + TOPLEVEL_BINDING.eval <<-RUBY + def self.__pry__ + binding + end + Pry.toplevel_binding = __pry__ + class << self; undef __pry__; end + RUBY + end + @toplevel_binding.eval('private') + @toplevel_binding + end + + def self.toplevel_binding=(binding) + @toplevel_binding = binding + end + + def self.in_critical_section? + Thread.current[:pry_critical_section] ||= 0 + Thread.current[:pry_critical_section] > 0 + end + + def self.critical_section(&block) + Thread.current[:pry_critical_section] ||= 0 + Thread.current[:pry_critical_section] += 1 + yield + ensure + Thread.current[:pry_critical_section] -= 1 + end +end + +Pry.init diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_instance.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_instance.rb new file mode 100644 index 0000000..7122b59 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/pry_instance.rb @@ -0,0 +1,654 @@ +# -*- coding: utf-8 -*- +## +# Pry is a powerful alternative to the standard IRB shell for Ruby. It +# features syntax highlighting, a flexible plugin architecture, runtime +# invocation and source and documentation browsing. +# +# Pry can be started similar to other command line utilities by simply running +# the following command: +# +# pry +# +# Once inside Pry you can invoke the help message: +# +# help +# +# This will show a list of available commands and their usage. For more +# information about Pry you can refer to the following resources: +# +# * http://pry.github.com/ +# * https://github.com/pry/pry +# * the IRC channel, which is #pry on the Freenode network +# + +class Pry + attr_accessor :binding_stack + attr_accessor :custom_completions + attr_accessor :eval_string + attr_accessor :backtrace + attr_accessor :suppress_output + attr_accessor :last_result + attr_accessor :last_file + attr_accessor :last_dir + + attr_reader :last_exception + attr_reader :command_state + attr_reader :exit_value + attr_reader :input_array + attr_reader :output_array + attr_reader :config + + extend Pry::Config::Convenience + config_shortcut *Pry::Config.shortcuts + EMPTY_COMPLETIONS = [].freeze + + # Create a new {Pry} instance. + # @param [Hash] options + # @option options [#readline] :input + # The object to use for input. + # @option options [#puts] :output + # The object to use for output. + # @option options [Pry::CommandBase] :commands + # The object to use for commands. + # @option options [Hash] :hooks + # The defined hook Procs. + # @option options [Array] :prompt + # The array of Procs to use for prompts. + # @option options [Proc] :print + # The Proc to use for printing return values. + # @option options [Boolean] :quiet + # Omit the `whereami` banner when starting. + # @option options [Array] :backtrace + # The backtrace of the session's `binding.pry` line, if applicable. + # @option options [Object] :target + # The initial context for this session. + def initialize(options={}) + @binding_stack = [] + @indent = Pry::Indent.new + @command_state = {} + @eval_string = "" + @backtrace = options.delete(:backtrace) || caller + target = options.delete(:target) + @config = Pry::Config.new + config.merge!(options) + push_prompt(config.prompt) + @input_array = Pry::HistoryArray.new config.memory_size + @output_array = Pry::HistoryArray.new config.memory_size + @custom_completions = config.command_completions + set_last_result nil + @input_array << nil + push_initial_binding(target) + exec_hook(:when_started, target, options, self) + end + + # The current prompt. + # This is the prompt at the top of the prompt stack. + # + # @example + # self.prompt = Pry::SIMPLE_PROMPT + # self.prompt # => Pry::SIMPLE_PROMPT + # + # @return [Array] Current prompt. + def prompt + prompt_stack.last + end + + def prompt=(new_prompt) + if prompt_stack.empty? + push_prompt new_prompt + else + prompt_stack[-1] = new_prompt + end + end + + # Initialize this instance by pushing its initial context into the binding + # stack. If no target is given, start at the top level. + def push_initial_binding(target=nil) + push_binding(target || Pry.toplevel_binding) + end + + # The currently active `Binding`. + # @return [Binding] The currently active `Binding` for the session. + def current_binding + binding_stack.last + end + alias current_context current_binding # support previous API + + # Push a binding for the given object onto the stack. If this instance is + # currently stopped, mark it as usable again. + def push_binding(object) + @stopped = false + binding_stack << Pry.binding_for(object) + end + + # + # Generate completions. + # + # @param [String] input + # What the user has typed so far + # + # @return [Array] + # Possible completions + # + def complete(str) + return EMPTY_COMPLETIONS unless config.completer + Pry.critical_section do + completer = config.completer.new(config.input, self) + completer.call str, target: current_binding, custom_completions: custom_completions.call.push(*sticky_locals.keys) + end + end + + # + # Injects a local variable into the provided binding. + # + # @param [String] name + # The name of the local to inject. + # + # @param [Object] value + # The value to set the local to. + # + # @param [Binding] b + # The binding to set the local on. + # + # @return [Object] + # The value the local was set to. + # + def inject_local(name, value, b) + value = Proc === value ? value.call : value + if b.respond_to?(:local_variable_set) + b.local_variable_set name, value + else # < 2.1 + begin + Pry.current[:pry_local] = value + b.eval "#{name} = ::Pry.current[:pry_local]" + ensure + Pry.current[:pry_local] = nil + end + end + end + + # @return [Integer] The maximum amount of objects remembered by the inp and + # out arrays. Defaults to 100. + def memory_size + @output_array.max_size + end + + def memory_size=(size) + @input_array = Pry::HistoryArray.new(size) + @output_array = Pry::HistoryArray.new(size) + end + + # Inject all the sticky locals into the current binding. + def inject_sticky_locals! + sticky_locals.each_pair do |name, value| + inject_local(name, value, current_binding) + end + end + + # Add a sticky local to this Pry instance. + # A sticky local is a local that persists between all bindings in a session. + # @param [Symbol] name The name of the sticky local. + # @yield The block that defines the content of the local. The local + # will be refreshed at each tick of the repl loop. + def add_sticky_local(name, &block) + config.extra_sticky_locals[name] = block + end + + def sticky_locals + { _in_: input_array, + _out_: output_array, + _pry_: self, + _ex_: last_exception && last_exception.wrapped_exception, + _file_: last_file, + _dir_: last_dir, + _: proc { last_result }, + __: proc { output_array[-2] } + }.merge(config.extra_sticky_locals) + end + + # Reset the current eval string. If the user has entered part of a multiline + # expression, this discards that input. + def reset_eval_string + @eval_string = "" + end + + # Pass a line of input to Pry. + # + # This is the equivalent of `Binding#eval` but with extra Pry! + # + # In particular: + # 1. Pry commands will be executed immediately if the line matches. + # 2. Partial lines of input will be queued up until a complete expression has + # been accepted. + # 3. Output is written to `#output` in pretty colours, not returned. + # + # Once this method has raised an exception or returned false, this instance + # is no longer usable. {#exit_value} will return the session's breakout + # value if applicable. + # + # @param [String?] line The line of input; `nil` if the user types `` + # @option options [Boolean] :generated Whether this line was generated automatically. + # Generated lines are not stored in history. + # @return [Boolean] Is Pry ready to accept more input? + # @raise [Exception] If the user uses the `raise-up` command, this method + # will raise that exception. + def eval(line, options={}) + return false if @stopped + + exit_value = nil + exception = catch(:raise_up) do + exit_value = catch(:breakout) do + handle_line(line, options) + # We use 'return !@stopped' here instead of 'return true' so that if + # handle_line has stopped this pry instance (e.g. by opening _pry_.repl and + # then popping all the bindings) we still exit immediately. + return !@stopped + end + exception = false + end + + @stopped = true + @exit_value = exit_value + + # TODO: make this configurable? + raise exception if exception + return false + end + + def handle_line(line, options) + if line.nil? + config.control_d_handler.call(@eval_string, self) + return + end + + ensure_correct_encoding!(line) + Pry.history << line unless options[:generated] + + @suppress_output = false + inject_sticky_locals! + begin + if !process_command_safely(line.lstrip) + @eval_string << "#{line.chomp}\n" if !line.empty? || !@eval_string.empty? + end + rescue RescuableException => e + self.last_exception = e + result = e + + Pry.critical_section do + show_result(result) + end + return + end + + # This hook is supposed to be executed after each line of ruby code + # has been read (regardless of whether eval_string is yet a complete expression) + exec_hook :after_read, eval_string, self + + begin + complete_expr = Pry::Code.complete_expression?(@eval_string) + rescue SyntaxError => e + output.puts "SyntaxError: #{e.message.sub(/.*syntax error, */m, '')}" + reset_eval_string + end + + if complete_expr + if @eval_string =~ /;\Z/ || @eval_string.empty? || @eval_string =~ /\A *#.*\n\z/ + @suppress_output = true + end + + # A bug in jruby makes java.lang.Exception not rescued by + # `rescue Pry::RescuableException` clause. + # + # * https://github.com/pry/pry/issues/854 + # * https://jira.codehaus.org/browse/JRUBY-7100 + # + # Until that gets fixed upstream, treat java.lang.Exception + # as an additional exception to be rescued explicitly. + # + # This workaround has a side effect: java exceptions specified + # in `Pry.config.exception_whitelist` are ignored. + jruby_exceptions = [] + if Pry::Helpers::BaseHelpers.jruby? + jruby_exceptions << Java::JavaLang::Exception + end + + begin + # Reset eval string, in case we're evaluating Ruby that does something + # like open a nested REPL on this instance. + eval_string = @eval_string + reset_eval_string + + result = evaluate_ruby(eval_string) + rescue RescuableException, *jruby_exceptions => e + # Eliminate following warning: + # warning: singleton on non-persistent Java type X + # (http://wiki.jruby.org/Persistence) + if Pry::Helpers::BaseHelpers.jruby? && e.class.respond_to?('__persistent__') + e.class.__persistent__ = true + end + self.last_exception = e + result = e + end + + Pry.critical_section do + show_result(result) + end + end + + throw(:breakout) if current_binding.nil? + end + private :handle_line + + # Potentially deprecated — Use `Pry::REPL.new(pry, :target => target).start` + # (If nested sessions are going to exist, this method is fine, but a goal is + # to come up with an alternative to nested sessions altogether.) + def repl(target = nil) + Pry::REPL.new(self, :target => target).start + end + + def evaluate_ruby(code) + inject_sticky_locals! + exec_hook :before_eval, code, self + + result = current_binding.eval(code, Pry.eval_path, Pry.current_line) + set_last_result(result, code) + ensure + update_input_history(code) + exec_hook :after_eval, result, self + end + + # Output the result or pass to an exception handler (if result is an exception). + def show_result(result) + if last_result_is_exception? + exception_handler.call(output, result, self) + elsif should_print? + print.call(output, result, self) + else + # nothin' + end + rescue RescuableException => e + # Being uber-paranoid here, given that this exception arose because we couldn't + # serialize something in the user's program, let's not assume we can serialize + # the exception either. + begin + output.puts "(pry) output error: #{e.inspect}" + rescue RescuableException => e + if last_result_is_exception? + output.puts "(pry) output error: failed to show exception" + else + output.puts "(pry) output error: failed to show result" + end + end + ensure + output.flush if output.respond_to?(:flush) + end + + # Force `eval_string` into the encoding of `val`. [Issue #284] + def ensure_correct_encoding!(val) + if @eval_string.empty? && + val.respond_to?(:encoding) && + val.encoding != @eval_string.encoding + @eval_string.force_encoding(val.encoding) + end + end + private :ensure_correct_encoding! + + # If the given line is a valid command, process it in the context of the + # current `eval_string` and binding. + # @param [String] val The line to process. + # @return [Boolean] `true` if `val` is a command, `false` otherwise + def process_command(val) + val = val.chomp + result = commands.process_line(val, + :target => current_binding, + :output => output, + :eval_string => @eval_string, + :pry_instance => self + ) + + # set a temporary (just so we can inject the value we want into eval_string) + Pry.current[:pry_cmd_result] = result + + # note that `result` wraps the result of command processing; if a + # command was matched and invoked then `result.command?` returns true, + # otherwise it returns false. + if result.command? + if !result.void_command? + # the command that was invoked was non-void (had a return value) and so we make + # the value of the current expression equal to the return value + # of the command. + @eval_string.replace "::Pry.current[:pry_cmd_result].retval\n" + end + true + else + false + end + end + + # Same as process_command, but outputs exceptions to `#output` instead of + # raising. + # @param [String] val The line to process. + # @return [Boolean] `true` if `val` is a command, `false` otherwise + def process_command_safely(val) + process_command(val) + rescue CommandError, Slop::InvalidOptionError, MethodSource::SourceNotFoundError => e + Pry.last_internal_error = e + output.puts "Error: #{e.message}" + true + end + + # Run the specified command. + # @param [String] val The command (and its params) to execute. + # @return [Pry::Command::VOID_VALUE] + # @example + # pry_instance.run_command("ls -m") + def run_command(val) + commands.process_line(val, + :eval_string => @eval_string, + :target => current_binding, + :pry_instance => self, + :output => output + ) + Pry::Command::VOID_VALUE + end + + # Execute the specified hook. + # @param [Symbol] name The hook name to execute + # @param [*Object] args The arguments to pass to the hook + # @return [Object, Exception] The return value of the hook or the exception raised + # + # If executing a hook raises an exception, we log that and then continue sucessfully. + # To debug such errors, use the global variable $pry_hook_error, which is set as a + # result. + def exec_hook(name, *args, &block) + e_before = hooks.errors.size + hooks.exec_hook(name, *args, &block).tap do + hooks.errors[e_before..-1].each do |e| + output.puts "#{name} hook failed: #{e.class}: #{e.message}" + output.puts "#{e.backtrace.first}" + output.puts "(see _pry_.hooks.errors to debug)" + end + end + end + + # Set the last result of an eval. + # This method should not need to be invoked directly. + # @param [Object] result The result. + # @param [String] code The code that was run. + def set_last_result(result, code="") + @last_result_is_exception = false + @output_array << result + + self.last_result = result unless code =~ /\A\s*\z/ + end + + # + # Set the last exception for a session. + # + # @param [Exception] e + # the last exception. + # + def last_exception=(e) + last_exception = Pry::LastException.new(e) + @last_result_is_exception = true + @output_array << last_exception + @last_exception = last_exception + end + + # Update Pry's internal state after evalling code. + # This method should not need to be invoked directly. + # @param [String] code The code we just eval'd + def update_input_history(code) + # Always push to the @input_array as the @output_array is always pushed to. + @input_array << code + if code + Pry.line_buffer.push(*code.each_line) + Pry.current_line += code.each_line.count + end + end + + # @return [Boolean] True if the last result is an exception that was raised, + # as opposed to simply an instance of Exception (like the result of + # Exception.new) + def last_result_is_exception? + @last_result_is_exception + end + + # Whether the print proc should be invoked. + # Currently only invoked if the output is not suppressed. + # @return [Boolean] Whether the print proc should be invoked. + def should_print? + !@suppress_output + end + + # Returns the appropriate prompt to use. + # @return [String] The prompt. + def select_prompt + object = current_binding.eval('self') + + open_token = @indent.open_delimiters.any? ? @indent.open_delimiters.last : + @indent.stack.last + + c = Pry::Config.from_hash({ + :object => object, + :nesting_level => binding_stack.size - 1, + :open_token => open_token, + :session_line => Pry.history.session_line_count + 1, + :history_line => Pry.history.history_line_count + 1, + :expr_number => input_array.count, + :_pry_ => self, + :binding_stack => binding_stack, + :input_array => input_array, + :eval_string => @eval_string, + :cont => !@eval_string.empty?}) + + Pry.critical_section do + # If input buffer is empty then use normal prompt + if eval_string.empty? + generate_prompt(Array(prompt).first, c) + + # Otherwise use the wait prompt (indicating multi-line expression) + else + generate_prompt(Array(prompt).last, c) + end + end + end + + def generate_prompt(prompt_proc, conf) + if prompt_proc.arity == 1 + prompt_proc.call(conf) + else + prompt_proc.call(conf.object, conf.nesting_level, conf._pry_) + end + end + private :generate_prompt + + # the array that the prompt stack is stored in + def prompt_stack + @prompt_stack ||= Array.new + end + private :prompt_stack + + # Pushes the current prompt onto a stack that it can be restored from later. + # Use this if you wish to temporarily change the prompt. + # @param [Array] new_prompt + # @return [Array] new_prompt + # @example + # new_prompt = [ proc { '>' }, proc { '>>' } ] + # push_prompt(new_prompt) # => new_prompt + def push_prompt(new_prompt) + prompt_stack.push new_prompt + end + + # Pops the current prompt off of the prompt stack. + # If the prompt you are popping is the last prompt, it will not be popped. + # Use this to restore the previous prompt. + # @return [Array] Prompt being popped. + # @example + # prompt1 = [ proc { '>' }, proc { '>>' } ] + # prompt2 = [ proc { '$' }, proc { '>' } ] + # pry = Pry.new :prompt => prompt1 + # pry.push_prompt(prompt2) + # pry.pop_prompt # => prompt2 + # pry.pop_prompt # => prompt1 + # pry.pop_prompt # => prompt1 + def pop_prompt + prompt_stack.size > 1 ? prompt_stack.pop : prompt + end + + # Returns the currently configured pager + # @example + # _pry_.pager.page text + def pager + Pry::Pager.new(self) + end + + # Returns an output device + # @example + # _pry_.output.puts "ohai!" + def output + Pry::Output.new(self) + end + + # Raise an exception out of Pry. + # + # See Kernel#raise for documentation of parameters. + # See rb_make_exception for the inbuilt implementation. + # + # This is necessary so that the raise-up command can tell the + # difference between an exception the user has decided to raise, + # and a mistake in specifying that exception. + # + # (i.e. raise-up RunThymeError.new should not be the same as + # raise-up NameError, "unititialized constant RunThymeError") + # + def raise_up_common(force, *args) + exception = if args == [] + last_exception || RuntimeError.new + elsif args.length == 1 && args.first.is_a?(String) + RuntimeError.new(args.first) + elsif args.length > 3 + raise ArgumentError, "wrong number of arguments" + elsif !args.first.respond_to?(:exception) + raise TypeError, "exception class/object expected" + elsif args.length === 1 + args.first.exception + else + args.first.exception(args[1]) + end + + raise TypeError, "exception object expected" unless exception.is_a? Exception + + exception.set_backtrace(args.length === 3 ? args[2] : caller(1)) + + if force || binding_stack.one? + binding_stack.clear + throw :raise_up, exception + else + binding_stack.pop + raise exception + end + end + def raise_up(*args); raise_up_common(false, *args); end + def raise_up!(*args); raise_up_common(true, *args); end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/rbx_path.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/rbx_path.rb new file mode 100644 index 0000000..bd969c6 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/rbx_path.rb @@ -0,0 +1,22 @@ +class Pry + module RbxPath + module_function + def is_core_path?(path) + Pry::Helpers::BaseHelpers.rbx? && (path.start_with?("kernel") || path.start_with?("lib")) && File.exist?(convert_path_to_full(path)) + end + + def convert_path_to_full(path) + if path.start_with?("kernel") + File.join File.dirname(Rubinius::KERNEL_PATH), path + elsif path.start_with?("lib") + File.join File.dirname(Rubinius::LIB_PATH), path + else + path + end + end + + def rvm_ruby?(path) + !!(path =~ /\.rvm/) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/repl.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/repl.rb new file mode 100644 index 0000000..4748785 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/repl.rb @@ -0,0 +1,202 @@ +require 'forwardable' + +class Pry + class REPL + extend Forwardable + def_delegators :@pry, :input, :output + + # @return [Pry] The instance of {Pry} that the user is controlling. + attr_accessor :pry + + # Instantiate a new {Pry} instance with the given options, then start a + # {REPL} instance wrapping it. + # @option options See {Pry#initialize} + def self.start(options) + new(Pry.new(options)).start + end + + # Create an instance of {REPL} wrapping the given {Pry}. + # @param [Pry] pry The instance of {Pry} that this {REPL} will control. + # @param [Hash] options Options for this {REPL} instance. + # @option options [Object] :target The initial target of the session. + def initialize(pry, options = {}) + @pry = pry + @indent = Pry::Indent.new + + if options[:target] + @pry.push_binding options[:target] + end + end + + # Start the read-eval-print loop. + # @return [Object?] If the session throws `:breakout`, return the value + # thrown with it. + # @raise [Exception] If the session throws `:raise_up`, raise the exception + # thrown with it. + def start + prologue + Pry::InputLock.for(:all).with_ownership { repl } + ensure + epilogue + end + + private + + # Set up the repl session. + # @return [void] + def prologue + pry.exec_hook :before_session, pry.output, pry.current_binding, pry + + # Clear the line before starting Pry. This fixes issue #566. + if pry.config.correct_indent + Kernel.print Pry::Helpers::BaseHelpers.windows_ansi? ? "\e[0F" : "\e[0G" + end + end + + # The actual read-eval-print loop. + # + # The {REPL} instance is responsible for reading and looping, whereas the + # {Pry} instance is responsible for evaluating user input and printing + # return values and command output. + # + # @return [Object?] If the session throws `:breakout`, return the value + # thrown with it. + # @raise [Exception] If the session throws `:raise_up`, raise the exception + # thrown with it. + def repl + loop do + case val = read + when :control_c + output.puts "" + pry.reset_eval_string + when :no_more_input + output.puts "" if output.tty? + break + else + output.puts "" if val.nil? && output.tty? + return pry.exit_value unless pry.eval(val) + end + end + end + + # Clean up after the repl session. + # @return [void] + def epilogue + pry.exec_hook :after_session, pry.output, pry.current_binding, pry + end + + # Read a line of input from the user. + # @return [String] The line entered by the user. + # @return [nil] On ``. + # @return [:control_c] On ``. + # @return [:no_more_input] On EOF. + def read + @indent.reset if pry.eval_string.empty? + current_prompt = pry.select_prompt + indentation = pry.config.auto_indent ? @indent.current_prefix : '' + + val = read_line("#{current_prompt}#{indentation}") + + # Return nil for EOF, :no_more_input for error, or :control_c for + return val unless String === val + + if pry.config.auto_indent + original_val = "#{indentation}#{val}" + indented_val = @indent.indent(val) + + if output.tty? && pry.config.correct_indent && Pry::Helpers::BaseHelpers.use_ansi_codes? + output.print @indent.correct_indentation( + current_prompt, indented_val, + original_val.length - indented_val.length + ) + output.flush + end + else + indented_val = val + end + + indented_val + end + + # Manage switching of input objects on encountering `EOFError`s. + # @return [Object] Whatever the given block returns. + # @return [:no_more_input] Indicates that no more input can be read. + def handle_read_errors + should_retry = true + exception_count = 0 + + begin + yield + rescue EOFError + pry.config.input = Pry.config.input + if !should_retry + output.puts "Error: Pry ran out of things to read from! " \ + "Attempting to break out of REPL." + return :no_more_input + end + should_retry = false + retry + + # Handle like Bash: empty the current input buffer, but don't + # quit. This is only for MRI 1.9; other versions of Ruby don't let you + # send Interrupt from within Readline. + rescue Interrupt + return :control_c + + # If we get a random error when trying to read a line we don't want to + # automatically retry, as the user will see a lot of error messages + # scroll past and be unable to do anything about it. + rescue RescuableException => e + puts "Error: #{e.message}" + output.puts e.backtrace + exception_count += 1 + if exception_count < 5 + retry + end + puts "FATAL: Pry failed to get user input using `#{input}`." + puts "To fix this you may be able to pass input and output file " \ + "descriptors to pry directly. e.g." + puts " Pry.config.input = STDIN" + puts " Pry.config.output = STDOUT" + puts " binding.pry" + return :no_more_input + end + end + + # Returns the next line of input to be sent to the {Pry} instance. + # @param [String] current_prompt The prompt to use for input. + # @return [String?] The next line of input, or `nil` on . + def read_line(current_prompt) + handle_read_errors do + if defined? Coolline and input.is_a? Coolline + input.completion_proc = proc do |cool| + completions = @pry.complete cool.completed_word + completions.compact + end + elsif input.respond_to? :completion_proc= + input.completion_proc = proc do |input| + @pry.complete input + end + end + + if defined?(Readline) and input == Readline + input_readline(current_prompt, false) # false since we'll add it manually + elsif defined? Coolline and input.is_a? Coolline + input_readline(current_prompt) + else + if input.method(:readline).arity == 1 + input_readline(current_prompt) + else + input_readline + end + end + end + end + + def input_readline(*args) + Pry::InputLock.for(:all).interruptible_region do + input.readline(*args) + end + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/repl_file_loader.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/repl_file_loader.rb new file mode 100644 index 0000000..cd8de9a --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/repl_file_loader.rb @@ -0,0 +1,74 @@ +class Pry + + # A class to manage the loading of files through the REPL loop. + # This is an interesting trick as it processes your file as if it + # was user input in an interactive session. As a result, all Pry + # commands are available, and they are executed non-interactively. Furthermore + # the session becomes interactive when the repl loop processes a + # 'make-interactive' command in the file. The session also becomes + # interactive when an exception is encountered, enabling you to fix + # the error before returning to non-interactive processing with the + # 'make-non-interactive' command. + + class REPLFileLoader + def initialize(file_name) + full_name = File.expand_path(file_name) + raise RuntimeError, "No such file: #{full_name}" if !File.exists?(full_name) + + define_additional_commands + @content = File.read(full_name) + end + + # Switch to interactive mode, i.e take input from the user + # and use the regular print and exception handlers. + # @param [Pry] _pry_ the Pry instance to make interactive. + def interactive_mode(_pry_) + _pry_.config.input = Pry.config.input + _pry_.config.print = Pry.config.print + _pry_.config.exception_handler = Pry.config.exception_handler + Pry::REPL.new(_pry_).start + end + + # Switch to non-interactive mode. Essentially + # this means there is no result output + # and that the session becomes interactive when an exception is encountered. + # @param [Pry] _pry_ the Pry instance to make non-interactive. + def non_interactive_mode(_pry_, content) + _pry_.print = proc {} + _pry_.exception_handler = proc do |o, e, _p_| + _p_.run_command "cat --ex" + o.puts "...exception encountered, going interactive!" + interactive_mode(_pry_) + end + + content.lines.each do |line| + break unless _pry_.eval line, :generated => true + end + + unless _pry_.eval_string.empty? + _pry_.output.puts "#{_pry_.eval_string}...exception encountered, going interactive!" + interactive_mode(_pry_) + end + end + + # Define a few extra commands useful for flipping back & forth + # between interactive/non-interactive modes + def define_additional_commands + s = self + + Pry::Commands.command "make-interactive", "Make the session interactive" do + s.interactive_mode(_pry_) + end + + Pry::Commands.command "load-file", "Load another file through the repl" do |file_name| + s.non_interactive_mode(_pry_, File.read(File.expand_path(file_name))) + end + end + + # Actually load the file through the REPL by setting file content + # as the REPL input stream. + def load + non_interactive_mode(Pry.new, @content) + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/rubygem.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/rubygem.rb new file mode 100644 index 0000000..36f788d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/rubygem.rb @@ -0,0 +1,82 @@ +require 'rubygems' + +class Pry + module Rubygem + + class << self + def installed?(name) + if Gem::Specification.respond_to?(:find_all_by_name) + Gem::Specification.find_all_by_name(name).any? + else + Gem.source_index.find_name(name).first + end + end + + # Get the gem spec object for the given gem name. + # + # @param [String] name + # @return [Gem::Specification] + def spec(name) + specs = if Gem::Specification.respond_to?(:each) + Gem::Specification.find_all_by_name(name) + else + Gem.source_index.find_name(name) + end + + first_spec = specs.sort_by{ |spec| Gem::Version.new(spec.version) }.last + + first_spec or raise CommandError, "Gem `#{name}` not found" + end + + # List gems matching a pattern. + # + # @param [Regexp] pattern + # @return [Array] + def list(pattern = /.*/) + if Gem::Specification.respond_to?(:each) + Gem::Specification.select{|spec| spec.name =~ pattern } + else + Gem.source_index.gems.values.select{|spec| spec.name =~ pattern } + end + end + + # Completion function for gem-cd and gem-open. + # + # @param [String] so_far what the user's typed so far + # @return [Array] completions + def complete(so_far) + if so_far =~ / ([^ ]*)\z/ + self.list(%r{\A#{$2}}).map(&:name) + else + self.list.map(&:name) + end + end + + # Installs a gem with all its dependencies. + # + # @param [String] name + # @return [void] + def install(name) + gemrc_opts = Gem.configuration['gem'].split(' ') + destination = if gemrc_opts.include?('--user-install') + Gem.user_dir + elsif File.writable?(Gem.dir) + Gem.dir + else + Gem.user_dir + end + installer = Gem::DependencyInstaller.new(:install_dir => destination) + installer.install(name) + rescue Errno::EACCES + raise CommandError, + "Insufficient permissions to install #{ Pry::Helpers::Text.green(name) }." + rescue Gem::GemNotFoundException + raise CommandError, + "Gem #{ Pry::Helpers::Text.green(name) } not found. Aborting installation." + else + Gem.refresh + end + end + + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/terminal.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/terminal.rb new file mode 100644 index 0000000..67f2979 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/terminal.rb @@ -0,0 +1,79 @@ +class Pry::Terminal + class << self + # Return a pair of [rows, columns] which gives the size of the window. + # + # If the window size cannot be determined, return nil. + def screen_size + rows, cols = actual_screen_size + if rows && cols + [rows.to_i, cols.to_i] + else + nil + end + end + + # Return a screen size or a default if that fails. + def size! default = [27, 80] + screen_size || default + end + + # Return a screen width or the default if that fails. + def width! + size![1] + end + + # Return a screen height or the default if that fails. + def height! + size![0] + end + + def actual_screen_size + # The best way, if possible (requires non-jruby ≥1.9 or io-console gem) + screen_size_according_to_io_console or + # Fall back to the old standby, though it might be stale: + screen_size_according_to_env or + # Fall further back, though this one is also out of date without something + # calling Readline.set_screen_size + screen_size_according_to_readline or + # Windows users can otherwise run ansicon and get a decent answer: + screen_size_according_to_ansicon_env + end + + def screen_size_according_to_io_console + return if Pry::Helpers::BaseHelpers.jruby? + require 'io/console' + $stdout.winsize if $stdout.tty? and $stdout.respond_to?(:winsize) + rescue LoadError + # They probably don't have the io/console stdlib or the io-console gem. + # We'll keep trying. + end + + def screen_size_according_to_env + size = [ENV['LINES'] || ENV['ROWS'], ENV['COLUMNS']] + size if nonzero_column?(size) + end + + def screen_size_according_to_readline + if defined?(Readline) && Readline.respond_to?(:get_screen_size) + size = Readline.get_screen_size + size if nonzero_column?(size) + end + rescue Java::JavaLang::NullPointerException + # This rescue won't happen on jrubies later than: + # https://github.com/jruby/jruby/pull/436 + nil + end + + def screen_size_according_to_ansicon_env + return unless ENV['ANSICON'] =~ /\((.*)x(.*)\)/ + size = [$2, $1] + size if nonzero_column?(size) + end + + private + + def nonzero_column?(size) + size[1].to_i > 0 + end + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/test/helper.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/test/helper.rb new file mode 100644 index 0000000..8ddf144 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/test/helper.rb @@ -0,0 +1,170 @@ +require 'pry' + +# in case the tests call reset_defaults, ensure we reset them to +# amended (test friendly) values +class << Pry + alias_method :orig_reset_defaults, :reset_defaults + def reset_defaults + orig_reset_defaults + + Pry.config.color = false + Pry.config.pager = false + Pry.config.should_load_rc = false + Pry.config.should_load_local_rc= false + Pry.config.should_load_plugins = false + Pry.config.history.should_load = false + Pry.config.history.should_save = false + Pry.config.correct_indent = false + Pry.config.hooks = Pry::Hooks.new + Pry.config.collision_warning = false + end +end +Pry.reset_defaults + +# A global space for storing temporary state during tests. + +module PryTestHelpers + + module_function + + # inject a variable into a binding + def inject_var(name, value, b) + Pry.current[:pry_local] = value + b.eval("#{name} = ::Pry.current[:pry_local]") + ensure + Pry.current[:pry_local] = nil + end + + def constant_scope(*names) + names.each do |name| + Object.remove_const name if Object.const_defined?(name) + end + + yield + ensure + names.each do |name| + Object.remove_const name if Object.const_defined?(name) + end + end + + # Open a temp file and yield it to the block, closing it after + # @return [String] The path of the temp file + def temp_file(ext='.rb') + file = Tempfile.new(['pry', ext]) + yield file + ensure + file.close(true) if file + File.unlink("#{file.path}c") if File.exists?("#{file.path}c") # rbx + end + + def unindent(*args) + Pry::Helpers::CommandHelpers.unindent(*args) + end + + def mock_command(cmd, args=[], opts={}) + output = StringIO.new + pry = Pry.new(output: output) + ret = cmd.new(opts.merge(pry_instance: pry, :output => output)).call_safely(*args) + Struct.new(:output, :return).new(output.string, ret) + end + + def mock_exception(*mock_backtrace) + StandardError.new.tap do |e| + e.define_singleton_method(:backtrace) { mock_backtrace } + end + end +end + +def pry_tester(*args, &block) + if args.length == 0 || args[0].is_a?(Hash) + args.unshift(Pry.toplevel_binding) + end + + PryTester.new(*args).tap do |t| + (class << t; self; end).class_eval(&block) if block + end +end + +def pry_eval(*eval_strs) + if eval_strs.first.is_a? String + binding = Pry.toplevel_binding + else + binding = Pry.binding_for(eval_strs.shift) + end + + pry_tester(binding).eval(*eval_strs) +end + +class PryTester + extend Forwardable + + attr_reader :pry, :out + + def_delegators :@pry, :eval_string, :eval_string= + + def initialize(target = TOPLEVEL_BINDING, options = {}) + @pry = Pry.new(options.merge(:target => target)) + @history = options[:history] + + @pry.inject_sticky_locals! + reset_output + end + + def eval(*strs) + reset_output + result = nil + + strs.flatten.each do |str| + str = "#{str.strip}\n" + @history.push str if @history + + if @pry.process_command(str) + result = last_command_result_or_output + else + result = @pry.evaluate_ruby(str) + end + end + + result + end + + def push(*lines) + Array(lines).flatten.each do |line| + @pry.eval(line) + end + end + + def push_binding(context) + @pry.push_binding context + end + + def last_output + @out.string if @out + end + + def process_command(command_str) + @pry.process_command(command_str) or raise "Not a valid command" + last_command_result_or_output + end + + def last_command_result + result = Pry.current[:pry_cmd_result] + result.retval if result + end + + protected + + def last_command_result_or_output + result = last_command_result + if result != Pry::Command::VOID_VALUE + result + else + last_output + end + end + + def reset_output + @out = StringIO.new + @pry.output = @out + end +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/version.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/version.rb new file mode 100644 index 0000000..9930e64 --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/version.rb @@ -0,0 +1,3 @@ +class Pry + VERSION = "0.10.0" +end diff --git a/vendor/bundle/gems/pry-0.10.0/lib/pry/wrapped_module.rb b/vendor/bundle/gems/pry-0.10.0/lib/pry/wrapped_module.rb new file mode 100644 index 0000000..6022c5d --- /dev/null +++ b/vendor/bundle/gems/pry-0.10.0/lib/pry/wrapped_module.rb @@ -0,0 +1,373 @@ +require 'pry/module_candidate' + +class Pry + class << self + # If the given object is a `Pry::WrappedModule`, return it unaltered. If it's + # anything else, return it wrapped in a `Pry::WrappedModule` instance. + def WrappedModule(obj) + if obj.is_a? Pry::WrappedModule + obj + else + Pry::WrappedModule.new(obj) + end + end + end + + class WrappedModule + include Helpers::BaseHelpers + include CodeObject::Helpers + + attr_reader :wrapped + + # Convert a string to a module. + # + # @param [String] mod_name + # @param [Binding] target The binding where the lookup takes place. + # @return [Module, nil] The module or `nil` (if conversion failed). + # @example + # Pry::WrappedModule.from_str("Pry::Code") + def self.from_str(mod_name, target=TOPLEVEL_BINDING) + if safe_to_evaluate?(mod_name, target) + Pry::WrappedModule.new(target.eval(mod_name)) + else + nil + end + rescue RescuableException + nil + end + + class << self + private + + # We use this method to decide whether code is safe to eval. Method's are + # generally not, but everything else is. + # TODO: is just checking != "method" enough?? + # TODO: see duplication of this method in Pry::CodeObject + # @param [String] str The string to lookup. + # @param [Binding] target Where the lookup takes place. + # @return [Boolean] + def safe_to_evaluate?(str, target) + return true if str.strip == "self" + kind = target.eval("defined?(#{str})") + kind =~ /variable|constant/ + end + end + + # @raise [ArgumentError] if the argument is not a `Module` + # @param [Module] mod + def initialize(mod) + raise ArgumentError, "Tried to initialize a WrappedModule with a non-module #{mod.inspect}" unless ::Module === mod + @wrapped = mod + @memoized_candidates = [] + @host_file_lines = nil + @source = nil + @source_location = nil + @doc = nil + end + + # Returns an array of the names of the constants accessible in the wrapped + # module. This avoids the problem of accidentally calling the singleton + # method `Module.constants`. + # @param [Boolean] inherit Include the names of constants from included + # modules? + def constants(inherit = true) + Module.instance_method(:constants).bind(@wrapped).call(inherit) + end + + # The prefix that would appear before methods defined on this class. + # + # i.e. the "String." or "String#" in String.new and String#initialize. + # + # @return String + def method_prefix + if singleton_class? + if Module === singleton_instance + "#{WrappedModule.new(singleton_instance).nonblank_name}." + else + "self." + end + else + "#{nonblank_name}#" + end + end + + # The name of the Module if it has one, otherwise #. + # + # @return [String] + def nonblank_name + if name.to_s == "" + wrapped.inspect + else + name + end + end + + # Is this a singleton class? + # @return [Boolean] + def singleton_class? + if Pry::Method.safe_send(wrapped, :respond_to?, :singleton_class?) + Pry::Method.safe_send(wrapped, :singleton_class?) + else + wrapped != Pry::Method.safe_send(wrapped, :ancestors).first + end + end + + # Is this strictly a module? (does not match classes) + # @return [Boolean] + def module? + wrapped.instance_of?(Module) + end + + # Is this strictly a class? + # @return [Boolean] + def class? + wrapped.instance_of?(Class) + end + + # Get the instance associated with this singleton class. + # + # @raise ArgumentError: tried to get instance of non singleton class + # + # @return [Object] + def singleton_instance + raise ArgumentError, "tried to get instance of non singleton class" unless singleton_class? + + if Helpers::BaseHelpers.jruby? + wrapped.to_java.attached + else + @singleton_instance ||= ObjectSpace.each_object(wrapped).detect{ |x| (class << x; self; end) == wrapped } + end + end + + # Forward method invocations to the wrapped module + def method_missing(method_name, *args, &block) + wrapped.send(method_name, *args, &block) + end + + def respond_to?(method_name) + super || wrapped.respond_to?(method_name) + end + + # Retrieve the source location of a module. Return value is in same + # format as Method#source_location. If the source location + # cannot be found this method returns `nil`. + # + # @param [Module] mod The module (or class). + # @return [Array, nil] The source location of the + # module (or class), or `nil` if no source location found. + def source_location + @source_location ||= primary_candidate.source_location + rescue Pry::RescuableException + nil + end + + # @return [String, nil] The associated file for the module (i.e + # the primary candidate: highest ranked monkeypatch). + def file + Array(source_location).first + end + alias_method :source_file, :file + + # @return [Fixnum, nil] The associated line for the module (i.e + # the primary candidate: highest ranked monkeypatch). + def line + Array(source_location).last + end + alias_method :source_line, :line + + # Returns documentation for the module. + # This documentation is for the primary candidate, if + # you would like documentation for other candidates use + # `WrappedModule#candidate` to select the candidate you're + # interested in. + # @raise [Pry::CommandError] If documentation cannot be found. + # @return [String] The documentation for the module. + def doc + @doc ||= primary_candidate.doc + end + + # Returns the source for the module. + # This source is for the primary candidate, if + # you would like source for other candidates use + # `WrappedModule#candidate` to select the candidate you're + # interested in. + # @raise [Pry::CommandError] If source cannot be found. + # @return [String] The source for the module. + def source + @source ||= primary_candidate.source + end + + # @return [String] Return the associated file for the + # module from YARD, if one exists. + def yard_file + YARD::Registry.at(name).file if yard_docs? + end + + # @return [Fixnum] Return the associated line for the + # module from YARD, if one exists. + def yard_line + YARD::Registry.at(name).line if yard_docs? + end + + # @return [String] Return the YARD docs for this module. + def yard_doc + YARD::Registry.at(name).docstring.to_s if yard_docs? + end + + # Return a candidate for this module of specified rank. A `rank` + # of 0 is equivalent to the 'primary candidate', which is the + # module definition with the highest number of methods. A `rank` + # of 1 is the module definition with the second highest number of + # methods, and so on. Module candidates are necessary as modules + # can be reopened multiple times and in multiple places in Ruby, + # the candidate API gives you access to the module definition + # representing each of those reopenings. + # @raise [Pry::CommandError] If the `rank` is out of range. That + # is greater than `number_of_candidates - 1`. + # @param [Fixnum] rank + # @return [Pry::WrappedModule::Candidate] + def candidate(rank) + @memoized_candidates[rank] ||= Candidate.new(self, rank) + end + + # @return [Fixnum] The number of candidate definitions for the + # current module. + def number_of_candidates + method_candidates.count + end + + # @note On JRuby 1.9 and higher, in certain conditions, this method chucks + # away its ability to be quick (when there are lots of monkey patches, + # like in Rails). However, it should be efficient enough on other rubies. + # @see https://github.com/jruby/jruby/issues/525 + # @return [Enumerator, Array] on JRuby 1.9 and higher returns Array, on + # other rubies returns Enumerator + def candidates + enum = Enumerator.new do |y| + (0...number_of_candidates).each do |num| + y.yield candidate(num) + end + end + Pry::Helpers::BaseHelpers.jruby_19? ? enum.to_a : enum + end + + # @return [Boolean] Whether YARD docs are available for this module. + def yard_docs? + !!(defined?(YARD) && YARD::Registry.at(name)) + end + + # @param [Fixnum] times How far to travel up the ancestor chain. + # @return [Pry::WrappedModule, nil] The wrapped module that is the + # superclass. + # When `self` is a `Module` then return the + # nth ancestor, otherwise (in the case of classes) return the + # nth ancestor that is a class. + def super(times=1) + return self if times.zero? + + if wrapped.is_a?(Class) + sup = ancestors.select { |v| v.is_a?(Class) }[times] + else + sup = ancestors[times] + end + + Pry::WrappedModule(sup) if sup + end + + private + + # @return [Pry::WrappedModule::Candidate] The candidate with the + # highest rank, that is the 'monkey patch' of this module with the + # highest number of methods, which contains a source code line that + # defines the module. It is considered the 'canonical' definition + # for the module. In the absense of a suitable candidate, the + # candidate of rank 0 will be returned, or a CommandError raised if + # there are no candidates at all. + def primary_candidate + @primary_candidate ||= candidates.find { |c| c.file } || + # This will raise an exception if there is no candidate at all. + candidate(0) + end + + # @return [Array>] The array of `Pry::Method` objects, + # there are two associated with each candidate. The first is the 'base + # method' for a candidate and it serves as the start point for + # the search in uncovering the module definition. The second is + # the last method defined for that candidate and it is used to + # speed up source code extraction. + def method_candidates + @method_candidates ||= all_source_locations_by_popularity.map do |group| + methods_sorted_by_source_line = group.last.sort_by(&:source_line) + [methods_sorted_by_source_line.first, methods_sorted_by_source_line.last] + end + end + + # A helper method. + def all_source_locations_by_popularity + return @all_source_locations_by_popularity if @all_source_locations_by_popularity + + ims = all_relevant_methods_for(wrapped) + @all_source_locations_by_popularity = ims.group_by { |v| Array(v.source_location).first }. + sort_by do |path, methods| + expanded = File.expand_path(path) + load_order = $LOADED_FEATURES.index{ |file| expanded.end_with?(file) } + + [-methods.size, load_order || (1.0 / 0.0)] + end + end + + # We only want methods that have a non-nil `source_location`. We also + # skip some spooky internal methods. + # (i.e we skip `__class_init__` because it's an odd rbx specific thing that causes tests to fail.) + # @return [Array] + def all_relevant_methods_for(mod) + methods = all_methods_for(mod).select(&:source_location). + reject{ |x| x.name == '__class_init__' || method_defined_by_forwardable_module?(x) } + + return methods unless methods.empty? + + safe_send(mod, :constants).map do |const_name| + if const = nested_module?(mod, const_name) + all_relevant_methods_for(const) + else + [] + end + end.flatten + end + + # Return all methods (instance methods and class methods) for a + # given module. + # @return [Array] + def all_methods_for(mod) + Pry::Method.all_from_obj(mod, false) + Pry::Method.all_from_class(mod, false) + end + + def nested_module?(parent, name) + return if safe_send(parent, :autoload?, name) + child = safe_send(parent, :const_get, name) + return unless Module === child + return unless safe_send(child, :name) == "#{safe_send(parent, :name)}::#{name}" + child + end + + # Detect methods that are defined with `def_delegator` from the Forwardable + # module. We want to reject these methods as they screw up module + # extraction since the `source_location` for such methods points at forwardable.rb + # TODO: make this more robust as valid user-defined files called + # forwardable.rb are also skipped. + def method_defined_by_forwardable_module?(method) + method.source_location.first =~ /forwardable\.rb/ + end + + # memoized lines for file + def lines_for_file(file) + @lines_for_file ||= {} + + if file == Pry.eval_path + @lines_for_file[file] ||= Pry.line_buffer.drop(1) + else + @lines_for_file[file] ||= File.readlines(file) + end + end + end +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/.gitignore b/vendor/bundle/gems/pry-byebug-1.3.3/.gitignore new file mode 100644 index 0000000..9033d2d --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/.gitignore @@ -0,0 +1,18 @@ +tmp +pkg +doc + +.bundle +.config +.yardoc +.gdb_history +.rvmrc +.ruby-gemset +.ruby-version + +Gemfile.lock +InstalledFiles +_yardoc +coverage +lib/bundler/man +rdoc diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/.travis.yml b/vendor/bundle/gems/pry-byebug-1.3.3/.travis.yml new file mode 100644 index 0000000..2e83117 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/.travis.yml @@ -0,0 +1,7 @@ +rvm: +- 2.0.0 +- 2.1 +- ruby-head +matrix: + allow_failures: + - rvm: ruby-head diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/CHANGELOG.md b/vendor/bundle/gems/pry-byebug-1.3.3/CHANGELOG.md new file mode 100644 index 0000000..404b864 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/CHANGELOG.md @@ -0,0 +1,83 @@ +## 1.3.3 (2014-25-06) + +* Relaxes pry dependency to support pry 0.10 series and further minor version +level releases. + + +## 1.3.2 (2014-24-02) + +* Bumps byebug dependency to get rid of bug in byebug. + + +## 1.3.1 (2014-08-02) + +* Fix #22 (thanks @andreychernih) + + +## 1.3.0 (2014-05-02) + +* Add breakpoints on method names (thanks @andreychernih & @palkan) +* Fix "undefined method `interface`" error (huge thanks to @andreychernih) + + +## 1.2.1 (2013-30-12) + +* Fix for "uncaught throw :breakout_nav" (thanks @lukebergen) + + +## 1.2.0 (2013-24-09) + +* Compatibility with byebug's 2.x series + + +## 1.1.2 (2013-11-07) + +* Allow pry-byebug to use backwards compatible versions of byebug + + +## 1.1.1 (2013-02-07) + +* Adds some initial tests to the test suite +* Fixes bug when doing "step n" or "next n" where n > 1 right after binding.pry + + +## 1.1.0 (2013-06-06) + +* Adds a test suite (thanks @teeparham!) +* Uses byebug ~> 1.4.0 +* Uses s, n, f and c aliases by default (thanks @jgakos!) + + +## 1.0.0, 1.0.1 (2013-05-07) + +* Forked from [pry-debugger](https://github.com/nixme/pry-debugger) to support + byebug +* Dropped pry-remote support + + +## 0.2.2 (2013-03-07) + +* Relaxed [byebug][byebug] dependency. + + +## 0.2.1 (2012-12-26) + +* Support breakpoints on methods defined in the pry console. (@banister) +* Fix support for specifying breakpoints by *file:line_number*. (@nviennot) +* Validate breakpoint conditionals are real Ruby expressions. +* Support for debugger ~> 1.2.0. (@jshou) +* Safer `alias_method_chain`-style patching of `Pry.start` and + `PryRemote::Server#teardown`. (@benizi) + + +## 0.2.0 (2012-06-11) + +* Breakpoints +* **finish** command +* Internal cleanup and bug fixes + + +## 0.1.0 (2012-06-07) + +* First release. **step**, **next**, and **continue** commands. + [pry-remote 0.1.4][pry-remote] support. diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/Gemfile b/vendor/bundle/gems/pry-byebug-1.3.3/Gemfile new file mode 100644 index 0000000..1fa34e1 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/Gemfile @@ -0,0 +1,9 @@ +source 'https://rubygems.org' + +gemspec + +gem 'rake', '~> 10.2' + +group :development, :test do + gem 'mocha', '~> 1.0' +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/LICENSE b/vendor/bundle/gems/pry-byebug-1.3.3/LICENSE new file mode 100644 index 0000000..bc6dfb7 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/LICENSE @@ -0,0 +1,20 @@ +MIT/Expat License + +Copyright (c) David Rodríguez + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/README.md b/vendor/bundle/gems/pry-byebug-1.3.3/README.md new file mode 100644 index 0000000..3bfaab3 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/README.md @@ -0,0 +1,115 @@ +pry-byebug [![Gem Version][1]][2] [![Build Status][3]][4] +============ + +_Fast execution control in Pry_ + +Adds **step**, **next**, **finish** and **continue** commands and +**breakpoints** to [Pry][pry] using [byebug][byebug]. + +To use, invoke pry normally. No need to start your script or app differently. + +```ruby +def some_method + binding.pry # Execution will stop here. + puts 'Hello World' # Run 'step' or 'next' in the console to move here. +end +``` + +For a complete debugging environment, add +[pry-stack_explorer][pry-stack_explorer] for call-stack frame navigation. + + +## Installation + +Drop + +```ruby +gem 'pry-byebug' +``` + +in your Gemfile and run + + bundle install + +_Make sure you include the gem globally or inside the `:test` group if you plan +to use it to debug your tests!_ + + +## Execution Commands + +**step:** Step execution into the next line or method. Takes an optional numeric +argument to step multiple times. Aliased to `s` + +**next:** Step over to the next line within the same frame. Also takes an +optional numeric argument to step multiple lines. Aliased to `n` + +**finish:** Execute until current stack frame returns. Aliased to `f` + +**continue:** Continue program execution and end the Pry session. Aliased to `c` + + +## Breakpoints + +You can set and adjust breakpoints directly from a Pry session using the +following commands: + +**break:** Set a new breakpoint from a line number in the current file, a file +and line number, or a method. Pass an optional expression to create a +conditional breakpoint. Edit existing breakpoints via various flags. + +Examples: + +``` +break SomeClass#run Break at the start of `SomeClass#run`. +break Foo#bar if baz? Break at `Foo#bar` only if `baz?`. +break app/models/user.rb:15 Break at line 15 in user.rb. +break 14 Break at line 14 in the current file. + +break --condition 4 x > 2 Change condition on breakpoint #4 to 'x > 2'. +break --condition 3 Remove the condition on breakpoint #3. + +break --delete 5 Delete breakpoint #5. +break --disable-all Disable all breakpoints. + +break List all breakpoints. (Same as `breakpoints`) +break --show 2 Show details about breakpoint #2. +``` + +Type `break --help` from a Pry session to see all available options. + + +**breakpoints**: List all defined breakpoints. Pass `-v` or `--verbose` to see +the source code around each breakpoint. + + +## Caveats + +Only supports MRI 2.0.0 or newer. For MRI 1.9.3 or older, use +[pry-debugger][pry-debugger] + + +## Contributors + +* Tee Parham (@teeparham) +* Gopal Patel (@nixme) +* John Mair (@banister) +* Nicolas Viennot (@nviennot) +* Benjamin R. Haskell (@benizi) +* Joshua Hou (@jshou) +* ...and others who helped with [pry-nav][pry-nav] + +Patches and bug reports are welcome. Just send a [pull request][pullrequests] or +file an [issue][issues]. [Project changelog][changelog]. + +[pry]: http://pry.github.com +[byebug]: https://github.com/deivid-rodriguez/byebug +[pry-debugger]: https://github.com/nixme/pry-debugger +[pry-stack_explorer]: https://github.com/pry/pry-stack_explorer +[pullrequests]: https://github.com/deivid-rodriguez/pry-byebug/pulls +[issues]: https://github.com/deivid-rodriguez/pry-byebug/issues +[changelog]: https://github.com/deivid-rodriguez/pry-byebug/blob/master/CHANGELOG.md +[pry-nav]: https://github.com/nixme/pry-nav +[1]: https://badge.fury.io/rb/pry-byebug.png +[2]: http://badge.fury.io/rb/pry-byebug +[3]: https://secure.travis-ci.org/deivid-rodriguez/pry-byebug.png +[4]: http://travis-ci.org/deivid-rodriguez/pry-byebug diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/Rakefile b/vendor/bundle/gems/pry-byebug-1.3.3/Rakefile new file mode 100644 index 0000000..cdc3988 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/Rakefile @@ -0,0 +1,10 @@ +require 'bundler/gem_tasks' +require 'rake/testtask' + +desc 'Run tests' +Rake::TestTask.new(:test) do |t| + t.libs << 'test' + t.pattern = 'test/**/*_test.rb' +end + +task default: :test diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug.rb new file mode 100644 index 0000000..b405b2a --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug.rb @@ -0,0 +1,3 @@ +require 'pry-byebug/base' +require 'pry-byebug/pry_ext' +require 'pry-byebug/commands' diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/base.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/base.rb new file mode 100644 index 0000000..ca37298 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/base.rb @@ -0,0 +1,13 @@ +module PryByebug + extend self + + # Checks that a binding is in a local file context. Extracted from + # https://github.com/pry/pry/blob/master/lib/pry/default_commands/context.rb + def check_file_context(target) + file = target.eval('__FILE__') + file == Pry.eval_path || (file !~ /(\(.*\))|<.*>/ && file != '' && file != '-e') + end + + # Reference to currently running pry-remote server. Used by the processor. + attr_accessor :current_remote_server +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/breakpoints.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/breakpoints.rb new file mode 100644 index 0000000..e717055 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/breakpoints.rb @@ -0,0 +1,140 @@ +module PryByebug + + # Wrapper for Byebug.breakpoints that respects our Processor and has better + # failure behavior. Acts as an Enumerable. + # + module Breakpoints + extend Enumerable + extend self + + class FileBreakpoint < SimpleDelegator + def source_code + Pry::Code.from_file(source).around(pos, 3).with_marker(pos) + end + + def to_s + "#{source} @ #{pos}" + end + end + + class MethodBreakpoint < SimpleDelegator + def initialize(byebug_bp, method) + __setobj__ byebug_bp + @method = method + end + + def source_code + Pry::Code.from_method(Pry::Method.from_str(@method)) + end + + def to_s + @method + end + end + + def breakpoints + @breakpoints ||= [] + end + + # Add method breakpoint. + def add_method(method, expression = nil) + validate_expression expression + Pry.processor.debugging = true + owner, name = method.split(/[\.#]/) + byebug_bp = Byebug.add_breakpoint(owner, name.to_sym, expression) + bp = MethodBreakpoint.new byebug_bp, method + breakpoints << bp + bp + end + + # Add file breakpoint. + def add_file(file, line, expression = nil) + real_file = (file != Pry.eval_path) + raise ArgumentError, 'Invalid file!' if real_file && !File.exist?(file) + validate_expression expression + + Pry.processor.debugging = true + + path = (real_file ? File.expand_path(file) : file) + bp = FileBreakpoint.new Byebug.add_breakpoint(path, line, expression) + breakpoints << bp + bp + end + + # Change the conditional expression for a breakpoint. + def change(id, expression = nil) + validate_expression expression + + breakpoint = find_by_id(id) + breakpoint.expr = expression + breakpoint + end + + # Delete an existing breakpoint with the given ID. + def delete(id) + deleted = Byebug.started? && + Byebug.remove_breakpoint(id) && + breakpoints.delete(find_by_id(id)) + raise ArgumentError, "No breakpoint ##{id}" if not deleted + Pry.processor.debugging = false if to_a.empty? + end + + # Delete all breakpoints. + def clear + @breakpoints = [] + Byebug.breakpoints.clear if Byebug.started? + Pry.processor.debugging = false + end + + # Enable a disabled breakpoint with the given ID. + def enable(id) + change_status id, true + end + + # Disable a breakpoint with the given ID. + def disable(id) + change_status id, false + end + + # Disable all breakpoints. + def disable_all + each do |breakpoint| + breakpoint.enabled = false + end + end + + def to_a + breakpoints + end + + def size + to_a.size + end + + def each(&block) + to_a.each(&block) + end + + def find_by_id(id) + breakpoint = find { |b| b.id == id } + raise ArgumentError, "No breakpoint ##{id}!" unless breakpoint + breakpoint + end + + + private + + def change_status(id, enabled = true) + breakpoint = find_by_id(id) + breakpoint.enabled = enabled + breakpoint + end + + def validate_expression(expression) + if expression && # `nil` implies no expression given, so pass + (expression.empty? || !Pry::Code.complete_expression?(expression)) + raise "Invalid breakpoint conditional: #{expression}" + end + end + end +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/cli.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/cli.rb new file mode 100644 index 0000000..d153748 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/cli.rb @@ -0,0 +1 @@ +require 'pry-byebug' \ No newline at end of file diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/commands.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/commands.rb new file mode 100644 index 0000000..9274377 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/commands.rb @@ -0,0 +1,260 @@ +require 'pry' +require 'pry-byebug/breakpoints' + +module PryByebug + Commands = Pry::CommandSet.new do + create_command 'step' do + description 'Step execution into the next line or method.' + + banner <<-BANNER + Usage: step [TIMES] + Aliases: s + + Step execution forward. By default, moves a single step. + + Examples: + + step Move a single step forward. + step 5 Execute the next 5 steps. + BANNER + + def process + check_file_context + breakout_navigation :step, args.first + end + end + alias_command 's', 'step' + + create_command 'next' do + description 'Execute the next line within the current stack frame.' + + banner <<-BANNER + Usage: next [LINES] + Aliases: n + + Step over within the same frame. By default, moves forward a single + line. + + Examples: + + next Move a single line forward. + next 4 Execute the next 4 lines. + BANNER + + def process + check_file_context + breakout_navigation :next, args.first + end + end + alias_command 'n', 'next' + + create_command 'finish' do + description 'Execute until current stack frame returns.' + + banner <<-BANNER + Usage: finish + Aliases: f + BANNER + + def process + check_file_context + breakout_navigation :finish + end + end + alias_command 'f', 'finish' + + create_command 'continue' do + description 'Continue program execution and end the Pry session.' + + banner <<-BANNER + Usage: continue + Aliases: c + BANNER + + def process + check_file_context + run 'exit-all' + end + end + alias_command 'c', 'continue' + + create_command 'break' do + description 'Set or edit a breakpoint.' + + banner <<-BANNER + Usage: break [if CONDITION] + break --condition N [CONDITION] + break [--show | --delete | --enable | --disable] N + break [--delete-all | --disable-all] + Aliases: breakpoint + + Set a breakpoint. Accepts a line number in the current file, a file and + line number, or a method, and an optional condition. + + Pass appropriate flags to manipulate existing breakpoints. + + Examples: + + break SomeClass#run Break at the start of `SomeClass#run`. + break Foo#bar if baz? Break at `Foo#bar` only if `baz?`. + break app/models/user.rb:15 Break at line 15 in user.rb. + break 14 Break at line 14 in the current file. + + break --condition 4 x > 2 Add/change condition on breakpoint #4. + break --condition 3 Remove the condition on breakpoint #3. + + break --delete 5 Delete breakpoint #5. + break --disable-all Disable all breakpoints. + + break List all breakpoints. (Same as `breakpoints`) + break --show 2 Show details about breakpoint #2. + BANNER + + def options(opt) + opt.on :c, :condition, 'Change the condition of a breakpoint.', :argument => true, :as => Integer + opt.on :s, :show, 'Show breakpoint details and source.', :argument => true, :as => Integer + opt.on :D, :delete, 'Delete a breakpoint.', :argument => true, :as => Integer + opt.on :d, :disable, 'Disable a breakpoint.', :argument => true, :as => Integer + opt.on :e, :enable, 'Enable a disabled breakpoint.', :argument => true, :as => Integer + opt.on :'disable-all', 'Disable all breakpoints.' + opt.on :'delete-all', 'Delete all breakpoints.' + method_options(opt) + end + + def process + Pry.processor.pry = _pry_ + + { :delete => :delete, + :disable => :disable, + :enable => :enable, + :'disable-all' => :disable_all, + :'delete-all' => :clear + }.each do |action, method| + if opts.present?(action) + Breakpoints.__send__ method, *(method == action ? [opts[action]] : []) + return run 'breakpoints' + end + end + + if opts.present?(:condition) + Breakpoints.change(opts[:condition], args.empty? ? nil : args.join(' ')) + run 'breakpoints' + elsif opts.present?(:show) + print_full_breakpoint Breakpoints.find_by_id(opts[:show]) + elsif args.empty? + run 'breakpoints' + else + new_breakpoint + end + end + + def new_breakpoint + place = args.shift + condition = args.join(' ') if 'if' == args.shift + + bp = + case place + when /^(\d+)$/ # Line number only + line = $1 + unless PryByebug.check_file_context(target) + raise ArgumentError, 'Line number declaration valid only in a file context.' + end + Breakpoints.add_file(target.eval('__FILE__'), line.to_i, condition) + when /^(.+):(\d+)$/ # File and line number + Breakpoints.add_file($1, $2.to_i, condition) + when /^(.*)[.#].+$/ # Method or class name + if $1.strip.empty? + unless PryByebug.check_file_context(target) + raise ArgumentError, 'Method name declaration valid only in a file context.' + end + place = target.eval('self.class.to_s') + place + end + Breakpoints.add_method(place,condition) + else + raise ArgumentError, 'Cannot identify arguments as breakpoint' + end + + print_full_breakpoint bp + end + end + alias_command 'breakpoint', 'break' + + + create_command 'breakpoints' do + description 'List defined breakpoints.' + + banner <<-BANNER + Usage: breakpoints [OPTIONS] + Aliases: breaks + + List registered breakpoints and their current status. + BANNER + + def options(opt) + opt.on :v, :verbose, 'Print source around each breakpoint.' + end + + def process + if Breakpoints.count > 0 + if opts.verbose? # Long-form with source output + Breakpoints.each { |b| print_full_breakpoint(b) } + else # Simple table output + max_width = [Math.log10(Breakpoints.count).ceil, 1].max + header = "#{' ' * (max_width - 1)}# Enabled At " + + output.puts + output.puts text.bold(header) + output.puts text.bold('-' * header.size) + Breakpoints.each do |breakpoint| + output.printf "%#{max_width}d ", breakpoint.id + output.print breakpoint.enabled? ? 'Yes ' : 'No ' + output.print breakpoint.to_s + output.print " (if #{breakpoint.expr})" if breakpoint.expr + output.puts + end + output.puts + end + else + output.puts text.bold('No breakpoints defined.') + end + end + end + alias_command 'breaks', 'breakpoints' + + helpers do + def breakout_navigation(action, times = nil) + _pry_.binding_stack.clear # Clear the binding stack. + throw :breakout_nav, { # Break out of the REPL loop and signal tracer + :action => action, + :times => times, + :pry => _pry_ + } + end + + # Ensures that a command is executed in a local file context. + def check_file_context + unless PryByebug.check_file_context(target) + raise Pry::CommandError, 'Cannot find local context. Did you use `binding.pry`?' + end + end + + # Print out full information about a breakpoint including surrounding code + # at that point. + def print_full_breakpoint(breakpoint) + line = breakpoint.pos + output.print text.bold("Breakpoint #{breakpoint.id}: ") + output.print "#{breakpoint.to_s} " + output.print breakpoint.enabled? ? '(Enabled)' : '(Disabled)' + output.puts ' :' + if (expr = breakpoint.expr) + output.puts "#{text.bold('Condition:')} #{expr}" + end + output.puts + output.puts breakpoint.source_code.with_line_numbers.to_s + output.puts + end + end + end +end + +Pry.commands.import PryByebug::Commands diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/processor.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/processor.rb new file mode 100644 index 0000000..31524dd --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/processor.rb @@ -0,0 +1,127 @@ +require 'pry' +require 'byebug' + +module PryByebug + class Processor < Byebug::Processor + attr_accessor :pry + + def initialize(interface = Byebug::LocalInterface.new) + super(interface) + + Byebug.handler = self + @always_enabled = true + @delayed = Hash.new(0) + end + + # Wrap a Pry REPL to catch navigational commands and act on them. + def run(initial = true, &block) + return_value = nil + + command = catch(:breakout_nav) do # Throws from PryByebug::Commands + return_value = yield + {} # Nothing thrown == no navigational command + end + + times = (command[:times] || 1).to_i # Command argument + times = 1 if times <= 0 + + if [:step, :next, :finish].include? command[:action] + @pry = command[:pry] # Pry instance to resume after stepping + Byebug.start unless Byebug.started? + + if initial + # Movement when on the initial binding.pry line will have a frame + # inside Byebug. If we step normally, it'll stop inside this + # Processor. So jump out and stop at the above frame, then step/next + # from our callback. + @delayed[command[:action]] = times + Byebug.current_context.step_out(2) + elsif :next == command[:action] + Byebug.current_context.step_over(times, 0) + + elsif :step == command[:action] + Byebug.current_context.step_into(times) + + elsif :finish == command[:action] + Byebug.current_context.step_out(0) + end + else + stop + end + + return_value + end + + # Adjust debugging. When set to false, the Processor will manage enabling + # and disabling the debugger itself. When set to true, byebug is always + # enabled. + def debugging=(enabled) + if enabled + @always_enabled = true + Byebug.start unless Byebug.started? + else + @always_enabled = false + # Byebug will get stopped if necessary in `stop` once the repl ends. + end + end + + # --- Callbacks from byebug C extension --- + def at_line(context, file, line) + # If any delayed nexts/steps, do 'em. + if @delayed[:next] > 1 + context.step_over(@delayed[:next] - 1, 0) + + elsif @delayed[:step] > 1 + context.step_into(@delayed[:step] - 1) + + elsif @delayed[:finish] > 1 + context.step_out(@delayed[:finish] - 1) + + # Otherwise, resume the pry session at the stopped line. + else + resume_pry context + end + + @delayed = Hash.new(0) + end + + # Called when a breakpoint is triggered. Note: `at_line`` is called + # immediately after with the context's `stop_reason == :breakpoint`. + def at_breakpoint(context, breakpoint) + @pry.output.print Pry::Helpers::Text.bold("\nBreakpoint #{breakpoint.id}. ") + @pry.output.puts (breakpoint.hit_count == 1 ? + 'First hit.' : + "Hit #{breakpoint.hit_count} times." ) + if (expr = breakpoint.expr) + @pry.output.print Pry::Helpers::Text.bold("Condition: ") + @pry.output.puts expr + end + end + + def at_catchpoint(context, exception) + # TODO + end + + private + + # + # Resume an existing Pry REPL at the paused point. + # + def resume_pry(context) + new_binding = context.frame_binding(0) + Byebug.stop unless @always_enabled + + run(false) do + @pry.repl new_binding + end + end + + # Cleanup when debugging is stopped and execution continues. + def stop + Byebug.stop if !@always_enabled && Byebug.started? + if PryByebug.current_remote_server # Cleanup DRb remote if running + PryByebug.current_remote_server.teardown + end + end + end +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_ext.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_ext.rb new file mode 100644 index 0000000..f017d44 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_ext.rb @@ -0,0 +1,23 @@ +require 'pry' +require 'pry-byebug/processor' + +class << Pry + alias_method :start_without_pry_byebug, :start + attr_reader :processor + + def start_with_pry_byebug(target = TOPLEVEL_BINDING, options = {}) + @processor ||= PryByebug::Processor.new + + if target.is_a?(Binding) && PryByebug.check_file_context(target) + # Wrap the processor around the usual Pry.start to catch navigation + # commands. + @processor.run(true) do + start_without_pry_byebug(target, options) + end + else + # No need for the tracer unless we have a file context to step through + start_without_pry_byebug(target, options) + end + end + alias_method :start, :start_with_pry_byebug +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_remote_ext.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_remote_ext.rb new file mode 100644 index 0000000..9d830ad --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/pry_remote_ext.rb @@ -0,0 +1,41 @@ +require 'pry-remote' + +module PryRemote + class Server + # Override the call to Pry.start to save off current Server, and not + # teardown the server right after Pry.start finishes. + def run + if PryByebug.current_remote_server + raise 'Already running a pry-remote session!' + else + PryByebug.current_remote_server = self + end + + setup + Pry.start @object, { + :input => client.input_proxy, + :output => client.output + } + end + + # Override to reset our saved global current server session. + alias_method :teardown_without_pry_byebug, :teardown + def teardown_with_pry_byebug + return if @torn + + teardown_without_pry_byebug + PryByebug.current_remote_server = nil + @torn = true + end + alias_method :teardown, :teardown_with_pry_byebug + end +end + +# Ensure cleanup when a program finishes without another break. For example, +# 'next' on the last line of a program won't hit PryByebug::Processor#run, +# which normally handles cleanup. +at_exit do + if PryByebug.current_remote_server + PryByebug.current_remote_server.teardown + end +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/version.rb b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/version.rb new file mode 100644 index 0000000..ca37adf --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/lib/pry-byebug/version.rb @@ -0,0 +1,3 @@ +module PryByebug + VERSION = '1.3.3' +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/pry-byebug.gemspec b/vendor/bundle/gems/pry-byebug-1.3.3/pry-byebug.gemspec new file mode 100644 index 0000000..5f031fc --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/pry-byebug.gemspec @@ -0,0 +1,23 @@ +require File.dirname(__FILE__) + '/lib/pry-byebug/version' + +Gem::Specification.new do |gem| + gem.name = 'pry-byebug' + gem.version = PryByebug::VERSION + gem.authors = ['David Rodríguez', 'Gopal Patel'] + gem.email = 'deivid.rodriguez@gmail.com' + gem.license = 'MIT' + gem.homepage = 'https://github.com/deivid-rodriguez/pry-byebug' + gem.summary = 'Fast debugging with Pry.' + gem.description = %q{Combine 'pry' with 'byebug'. Adds 'step', 'next', and + 'continue' commands to control execution.} + + gem.files = `git ls-files`.split("\n") + gem.test_files = `git ls-files -- test/*`.split("\n") + gem.require_paths = ['lib'] + + # Dependencies + gem.required_ruby_version = '>= 2.0.0' + + gem.add_runtime_dependency 'pry', '~> 0.10' + gem.add_runtime_dependency 'byebug', '~> 2.7' +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/base_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/base_test.rb new file mode 100644 index 0000000..7d838b6 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/base_test.rb @@ -0,0 +1,14 @@ +require 'test_helper' + +class BaseTest < MiniTest::Spec + def test_main_file_context + Pry.stubs eval_path: "
" + assert PryByebug.check_file_context(TOPLEVEL_BINDING) + end + + def test_other_file_context + Pry.stubs eval_path: "something" + refute PryByebug.check_file_context(TOPLEVEL_BINDING) + end +end + diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/breakpoints_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/breakpoints_test.rb new file mode 100644 index 0000000..3e61a7c --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/breakpoints_test.rb @@ -0,0 +1,34 @@ +require 'test_helper' + +class BreakpointsTest < MiniTest::Spec + def test_add_file_raises_argument_error + Pry.stubs eval_path: "something" + File.stubs :exist? + assert_raises(ArgumentError) do + PryByebug::Breakpoints.add_file("file", 1) + end + end + + class Tester + def self.class_method; end + def instance_method; end + end + + def test_add_method_adds_instance_method_breakpoint + Pry.stub :processor, PryByebug::Processor.new do + PryByebug::Breakpoints.add_method 'BreakpointsTest::Tester#instance_method' + bp = Byebug.breakpoints.last + assert_equal 'BreakpointsTest::Tester', bp.source + assert_equal 'instance_method', bp.pos + end + end + + def test_add_method_adds_class_method_breakpoint + Pry.stub :processor, PryByebug::Processor.new do + PryByebug::Breakpoints.add_method 'BreakpointsTest::Tester.class_method' + bp = Byebug.breakpoints.last + assert_equal 'BreakpointsTest::Tester', bp.source + assert_equal 'class_method', bp.pos + end + end +end diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/commands_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/commands_test.rb new file mode 100644 index 0000000..5f4109e --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/commands_test.rb @@ -0,0 +1,178 @@ +require 'test_helper' + +class CommandsTest < MiniTest::Spec + let(:step_file) do + (Pathname.new(__FILE__) + "../examples/stepping.rb").cleanpath.to_s + end + + let(:break_first_file) do + (Pathname.new(__FILE__) + "../examples/break1.rb").cleanpath.to_s + end + + let(:break_second_file) do + (Pathname.new(__FILE__) + "../examples/break2.rb").cleanpath.to_s + end + + before do + Pry.color = false + Pry.pager = false + Pry.hooks = Pry::DEFAULT_HOOKS + @output = StringIO.new + end + + describe 'Step Command' do + describe 'single step' do + before do + @input = InputTester.new 'step' + redirect_pry_io(@input, @output) do + load step_file + end + end + + it 'shows current line' do + @output.string.must_match /\=> 3:/ + end + end + + describe 'multiple step' do + before do + @input = InputTester.new 'step 2' + redirect_pry_io(@input, @output) do + load step_file + end + end + + it 'shows current line' do + @output.string.must_match /\=> 4:/ + end + end + end + + describe 'Next Command' do + describe 'single step' do + before do + @input = InputTester.new 'next' + redirect_pry_io(@input, @output) do + load step_file + end + end + + it 'shows current line' do + @output.string.must_match /\=> 3:/ + end + end + + describe 'multiple step' do + before do + @input = InputTester.new 'next 2' + redirect_pry_io(@input, @output) do + load step_file + end + end + + it 'shows current line' do + @output.string.must_match /\=> 20:/ + end + end + end + + describe 'Set Breakpoints' do + before do + @input = InputTester.new 'break --delete-all' + redirect_pry_io(@input, @output) do + load break_first_file + end + @output = StringIO.new + end + + describe 'set by line number' do + before do + @input = InputTester.new 'break 3' + redirect_pry_io(@input, @output) do + load break_first_file + end + end + + it 'shows breakpoint enabled' do + @output.string.must_match /^Breakpoint [\d]+: #{break_first_file} @ 3 \(Enabled\)/ + end + + it 'shows breakpoint hit' do + @output.string =~ /^Breakpoint ([\d]+): #{break_first_file} @ 3 \(Enabled\)/ + @output.string.must_match Regexp.new("^Breakpoint #{$1}\. First hit") + end + + it 'shows breakpoint line' do + @output.string.must_match /\=> 3:/ + end + end + + describe 'set by method_id' do + before do + @input = InputTester.new 'break BreakExample#a' + redirect_pry_io(@input, @output) do + load break_first_file + end + end + + it 'shows breakpoint enabled' do + @output.string.must_match /^Breakpoint [\d]+: BreakExample#a \(Enabled\)/ + end + + it 'shows breakpoint hit' do + @output.string =~ /^Breakpoint ([\d]+): BreakExample#a \(Enabled\)/ + @output.string.must_match Regexp.new("^Breakpoint #{$1}\. First hit") + end + + it 'shows breakpoint line' do + @output.string.must_match /\=> 4:/ + end + + describe 'when its a bang method' do + before do + @input = InputTester.new 'break BreakExample#c!' + redirect_pry_io(@input, @output) do + load break_first_file + end + end + + it 'shows breakpoint enabled' do + @output.string.must_match /^Breakpoint [\d]+: BreakExample#c! \(Enabled\)/ + end + + it 'shows breakpoint hit' do + @output.string =~ /^Breakpoint ([\d]+): BreakExample#c! \(Enabled\)/ + @output.string.must_match Regexp.new("^Breakpoint #{$1}\. First hit") + end + + it 'shows breakpoint line' do + @output.string.must_match /\=> 14:/ + end + end + end + + describe 'set by method_id within context' do + before do + @input = InputTester.new 'break #b' + redirect_pry_io(@input, @output) do + load break_second_file + end + end + + it 'shows breakpoint enabled' do + @output.string.must_match /^Breakpoint [\d]+: BreakExample#b \(Enabled\)/ + end + + it 'shows breakpoint hit' do + @output.string =~ /^Breakpoint ([\d]+): BreakExample#b \(Enabled\)/ + @output.string.must_match Regexp.new("^Breakpoint #{$1}\. First hit") + end + + it 'shows breakpoint line' do + @output.string.must_match /\=> 8:/ + end + end + + end +end + diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break1.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break1.rb new file mode 100644 index 0000000..bce68fe --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break1.rb @@ -0,0 +1,20 @@ +binding.pry + +class BreakExample + def a + z = 2 + b + end + + def b + v2 = 5 if 1 == 2 ; [1,2,3].map { |a| a.to_f } + c! + end + + def c! + z = 4 + 5 + end +end + +BreakExample.new.a diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break2.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break2.rb new file mode 100644 index 0000000..d10c399 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/break2.rb @@ -0,0 +1,18 @@ +class BreakExample + def a + binding.pry + z = 2 + b + end + + def b + c + end + + def c + z = 4 + 5 + end +end + +BreakExample.new.a diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/stepping.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/stepping.rb new file mode 100644 index 0000000..a062622 --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/examples/stepping.rb @@ -0,0 +1,25 @@ +binding.pry + +class SteppingExample + def a + z = 2 + b + end + + def b + v2 = 5 if 1 == 2 ; [1,2,3].map { |a| a.to_f } + c + end + + def c + z = 4 + 5 + end +end + +ex = SteppingExample.new.a +2.times do + ex += 1 +end + +ex diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/processor_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/processor_test.rb new file mode 100644 index 0000000..f943e4d --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/processor_test.rb @@ -0,0 +1,6 @@ +require 'test_helper' + +class ProcessorTest < MiniTest::Spec + +end + diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_ext_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_ext_test.rb new file mode 100644 index 0000000..3b5e43c --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_ext_test.rb @@ -0,0 +1,6 @@ +require 'test_helper' + +class PryExtTest < MiniTest::Spec + +end + diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_remote_ext_test.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_remote_ext_test.rb new file mode 100644 index 0000000..67e8c7c --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/pry_remote_ext_test.rb @@ -0,0 +1,6 @@ +require 'test_helper' + +class PryRemoteExtTest < MiniTest::Spec + +end + diff --git a/vendor/bundle/gems/pry-byebug-1.3.3/test/test_helper.rb b/vendor/bundle/gems/pry-byebug-1.3.3/test/test_helper.rb new file mode 100644 index 0000000..99070dc --- /dev/null +++ b/vendor/bundle/gems/pry-byebug-1.3.3/test/test_helper.rb @@ -0,0 +1,34 @@ +require 'pry/test/helper' +require 'minitest/autorun' +require 'pry-byebug' +require 'mocha/setup' + +# Set I/O streams. Out defaults to an anonymous StringIO. +def redirect_pry_io(new_in, new_out = StringIO.new) + old_in = Pry.input + old_out = Pry.output + + Pry.input = new_in + Pry.output = new_out + begin + yield + ensure + Pry.input = old_in + Pry.output = old_out + end +end + +class InputTester + def initialize(*actions) + @orig_actions = actions.dup + @actions = actions + end + + def readline(*) + @actions.shift + end + + def rewind + @actions = @orig_actions.dup + end +end diff --git a/vendor/bundle/gems/slop-3.6.0/.gitignore b/vendor/bundle/gems/slop-3.6.0/.gitignore new file mode 100644 index 0000000..e20dac6 --- /dev/null +++ b/vendor/bundle/gems/slop-3.6.0/.gitignore @@ -0,0 +1,7 @@ +.rvmrc +.yardoc +doc +*.swp +*.gem +*.rbc +Gemfile.lock diff --git a/vendor/bundle/gems/slop-3.6.0/.travis.yml b/vendor/bundle/gems/slop-3.6.0/.travis.yml new file mode 100644 index 0000000..6fba0ce --- /dev/null +++ b/vendor/bundle/gems/slop-3.6.0/.travis.yml @@ -0,0 +1,9 @@ +rvm: + - 1.9.3 + - 2.1 + - ruby-head + - jruby-19mode +notifications: + email: + on_success: change + on_failure: always diff --git a/vendor/bundle/gems/slop-3.6.0/CHANGES.md b/vendor/bundle/gems/slop-3.6.0/CHANGES.md new file mode 100644 index 0000000..c500beb --- /dev/null +++ b/vendor/bundle/gems/slop-3.6.0/CHANGES.md @@ -0,0 +1,309 @@ +3.6.0 (2014-06-18) +------------------ + +* Add example of rest arguments usage in the readme file #139 +* Default values on options are printed in the help message #134 + +3.5.0 (2014-03-12) +------------------ + +* Add support for `as: Regexp` #132 + +3.4.7 (2013-11-14) +------------------ + +* Ensure trash is cleared on every parse so you can parse multiple + times with the same instance (#130) + +3.4.5 (2013-05-14) +------------------ + +* Allow specifying long options starting with numbers (#110, Peter Zotov) +* Ensure short-options still consume trailing arguments, ie `-abc foo` + should assign `foo` to the option `c` if it expects an argument (#114). + +3.4.4 (2013-03-12) +------------------ + +* Disable the run callback when the help option is used and `-h` + or `--help` is passed. #106 +* Ensure default `--help` option exits by default (#107, Autumn Perrault). + +3.4.3 (2013-01-14) +------------------ + +* Ensure `parse!` removes commands and their options. + +3.4.2 (2013-01-14) +------------------ + +* Expose the Hash commands as public API. +* Deprecated `Slop.optspec`. +* Ensure help output prints to stdout, not stderr. + +3.4.1 (2013-01-13) +------------------ + +* Ensure options replace any existing duplicates +* Command config options now inherit config options from top level Slop. +* Command help output now adds command in usage string. + +3.4.0 (2013-01-12) +------------------ + +* Implement new command system (#95) +* Deprecate Slop::Commands +* Ensure 'no-foo' options are not inverted when parsing '--no-foo' (#86) +* Code refactoring and simplification (Kenichi Kamiya, #84, #85) + +3.3.3 (2012-08-29) +------------------ + +* Ensure autocreate arguments are not created as options (#77) +* Ensure options are not swallowed when using short options with argument + included (#74) + +3.3.2 (2012-06-26) +------------------ + +* Ensure multiple options are not executed unless they exist (#70) + +3.3.1 (2012-05-31) +------------------ + +* Stop multiple switches from trashing arguments (Conrad Irwin, #66) + +3.3.0 (2012-05-30) +------------------ + +* Fix `:as => :count` when using multiple switches. +* Ensure range typecast allows negative range values. +* Ignore nil objects send to #parse instead of choking. + +3.2.0 (2012-05-15) +------------------ + +* Ensure boolean options appear correctly in `to_hash` output. (#59) + +3.1.1 (2012-04-24) +------------------ + +* Ensure separators before any options are still being processed (#62) + +3.1.0 (2012-04-23) +------------------ + +* Allow options to be fetched via underscores instead of dashes + (as a fallback) (Eric Anderson, #51) +* Added `Slop#strict?` method. +* Added strict checks for Integer/Float type casting. (Amon Sha) +* Ensure separators are not replacing existing separators (#61) + +3.0.4 (2012-01-31) +------------------ + +* Ensure `option=argument` syntax does not consume following arguments (#55). + +3.0.3 (2012-01-30) +------------------ + +* Ensure options passed after option terminator do not raise an exception + (#54, Amon Sha) + +3.0.2 (2012-01-27) +------------------ + +* Ensure `--option=value` is being evaluated before multiple switches (#52) + +3.0.1 (2012-01-27) +------------------ + +* Ensure tests run green on 1.8.7 +* Ensure `:argument => :optional` works with `:option=` format. +* Ruby 1.8.7 compat fix (dont chain Enumerable methods!) (Eric Anderson) + +3.0.0 (2012-01-24) +------------------ + +* value_to_range returns an x..x range if the value looks like an integer. +* Lots of code refactoring +* Use TomDoc documentation +* Added `Slop::Commands` and removed existing command system +* Configuration options altered: + * `:optional` has been renamed to `:optional_argument` + * Added `:required` for mandatory options + * `:argument` now accepts an `:optional` symbol as well as boolean value +* Removed Slop instance methods: + * description=, description + * summary=, summary + * command + * on_empty + * on_noopts + * execute + * to_struct +* Added Slop instance methods: + * separator + * fetch_option + * add_callback + +2.4.3 (2012-01-16) +------------------ + +* Allow the `:as` option to accept an object responding to :call for + custom type conversions (#45) +* Ensure negative integers are not parsed as possible options (#46) + +2.4.2 (2011-12-18) +------------------ + +* Fix checking of required options (Dominik Honnef) + +2.4.1 (2011-12-08) +------------------ + +* Ensure optional arguments are returned correctly + +2.4.0 (2011-11-26) +------------------ + +* Avoid `define_method` for checking an options presence (and caching it) #37 +* Ensure the short option allows an appended `=` for accepting arguments +* Implement `respond_to?` + +2.3.1 (2011-11-11) +------------------ + +* Return `nil` for any options using casting which don't expect arguments (#33) +* Fix parenthesis warning on 1.8.7 (@shevegen) +* Ensure long argument is a string before attempting to use `#[]` method on it + +2.3.0 (2011-11-04) +------------------ + +* Allow flags to have suffixed `=` char for options which accept an argument + +2.2.0 (2011-11-02) +------------------ + +* Support `bup.options` style optspec parsing + * http://apenwarr.ca/log/?m=201111 + +* Allow `:as` to accept a `count` value (Conrad Irwin): + + `on :v, :verbose, :as => :count # -vv; opts[:verbose] #=> 2` + +2.1.0 (2011-08-03) +------------------ + +* Added `Slop#missing` for returning a list of missing options parsed +* Allow `Slop#present?` to accept multiple arguments +* Added `:all_accept_arguments` to Slop configuration options, this saves + having to specify that every option takes an argument +* Added `Slop#to_struct` for building new classes from options + +2.0.0 (2011-07-07) +------------------ + +* Deprecations: + * Removed `Slop::Options#to_hash` continue using `Slop#to_hash` directly. + This method also now returns symbols by default instead of strings. If + you want strings use `opts.to_hash(false)` + * `:multiple_switches` is now enabled by default, to parse `fbar` as the + option `f` with value `bar` you must disable `:multiple_switches` + * Removed `Slop::Options#to_help` and merged its contents into `Slop#help` + * Removed `lib/slop/options.rb` and merged `Slop::Options` into slop.rb + * Removed `lib/slop/option.rb` and merged `Slop::Option` into slop.rb + * These changes make Slop much easier to vendor in libraries +* `Slop::Option` now inherits from `Struct.new` +* Added Slop::Error subclassing from StandardError which all exception + classes should inherit from +* Added Slop::MissingOptionError and `:required` option to Slop::Option. + This exception is raised when a mandatory option is not used + +1.9.1 (2011-06-16) +------------------ + +* Ensure optional items with no arguments still return true when searching + for presence + +1.9.0 (2011-06-15) +------------------ + +* Add command completion and support for an error message when ambiguous + commands are used +* Add command aliases +* Fix: Ensure parsed elements are removed from original arguments when using + `:multiple_switches` +* Ensure anything after `--` is parsed as an argument and not option even + if prefixed with `/--?/` +* Performance improvements when making many calls to `Slop#option?` for + checking an options presence (Rob Gleeson) +* Ensure `execute` passes command arguments to the block +* Support for summary and description (Denis Defreyne) + +1.8.0 (2011-06-12) +------------------ + +* Added `execute` method to Slop for commands. This block will be invoked + when a specific command is used. The Slop object will be yielded to the + block +* Allow passing a class name to `on` to be used as an `:as` option. ie: + `on :people, 'Some people', Array` +* Get smart with parsing options optparse style: `on '--name NAME'` and + `on 'password [OPTIONAL]'` +* Feature: `:arguments` setting to enable argument passing for all options + +1.7.0 (2011-06-06) +------------------ + +* Feature: Autocreate (auto create options at parse time, making assumptions) +* Feature: When parsing options as arrays, push multiple arguments into a + single array + +1.6.1 (2011-06-01) +------------------ + +* Fix tests and using a temporary Array for ARGV, fixes RubyGems Test issues +* General cleanup of code + +1.6.0 (2011-05-18) +------------------ + +* Add `:ignore_case` to Slop options for case insensitive option matching +* Add `:on_noopts` for triggering an event when the arguments contain no + options +* Add `:unless` to Slop::Option for omitting execution of the Options block + when this object exists in the Array of items passed to Slop.new +* Bugfix: Do not parse negative integers as options. A valid option must + start with an alphabet character +* Bugfix: Allow a Range to accept a negative Integer at either end + +1.5.5 (2011-05-03) +------------------ + +* Bugfix: only attempt to extract options prefixed with `-` + +1.5.4 (2011-05-01) +------------------ + +* Bugfix: `parse!` should not remove items with the same value as items used + in option arguments. Fixes #22 (Utkarsh Kukreti) + +1.5.3 (2011-04-22) +------------------ + +* Bugfix: Use integers when fetching array indexes, not strings + +1.5.2 (2011-04-17) +------------------ + +* Bugfix: Ensure `ARGV` is empty when using the `on_empty` event + +1.5.0 (2011-04-15) +------------------ + +* Add `Slop#get` as alias to `Slop#[]` +* Add `Slop#present?` as alias for `Slop#