truex-skylight 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +277 -0
  3. data/CLA.md +9 -0
  4. data/CONTRIBUTING.md +1 -0
  5. data/LICENSE.md +79 -0
  6. data/README.md +4 -0
  7. data/bin/skylight +3 -0
  8. data/ext/extconf.rb +186 -0
  9. data/ext/libskylight.yml +6 -0
  10. data/ext/skylight_memprof.c +115 -0
  11. data/ext/skylight_native.c +416 -0
  12. data/ext/skylight_native.h +20 -0
  13. data/lib/skylight.rb +2 -0
  14. data/lib/skylight/api.rb +79 -0
  15. data/lib/skylight/cli.rb +146 -0
  16. data/lib/skylight/compat.rb +47 -0
  17. data/lib/skylight/config.rb +498 -0
  18. data/lib/skylight/core.rb +122 -0
  19. data/lib/skylight/data/cacert.pem +3894 -0
  20. data/lib/skylight/formatters/http.rb +17 -0
  21. data/lib/skylight/gc.rb +107 -0
  22. data/lib/skylight/helpers.rb +137 -0
  23. data/lib/skylight/instrumenter.rb +290 -0
  24. data/lib/skylight/middleware.rb +75 -0
  25. data/lib/skylight/native.rb +69 -0
  26. data/lib/skylight/normalizers.rb +133 -0
  27. data/lib/skylight/normalizers/action_controller/process_action.rb +35 -0
  28. data/lib/skylight/normalizers/action_controller/send_file.rb +76 -0
  29. data/lib/skylight/normalizers/action_view/render_collection.rb +18 -0
  30. data/lib/skylight/normalizers/action_view/render_partial.rb +18 -0
  31. data/lib/skylight/normalizers/action_view/render_template.rb +18 -0
  32. data/lib/skylight/normalizers/active_record/sql.rb +79 -0
  33. data/lib/skylight/normalizers/active_support/cache.rb +50 -0
  34. data/lib/skylight/normalizers/active_support/cache_clear.rb +16 -0
  35. data/lib/skylight/normalizers/active_support/cache_decrement.rb +16 -0
  36. data/lib/skylight/normalizers/active_support/cache_delete.rb +16 -0
  37. data/lib/skylight/normalizers/active_support/cache_exist.rb +16 -0
  38. data/lib/skylight/normalizers/active_support/cache_fetch_hit.rb +16 -0
  39. data/lib/skylight/normalizers/active_support/cache_generate.rb +16 -0
  40. data/lib/skylight/normalizers/active_support/cache_increment.rb +16 -0
  41. data/lib/skylight/normalizers/active_support/cache_read.rb +16 -0
  42. data/lib/skylight/normalizers/active_support/cache_read_multi.rb +16 -0
  43. data/lib/skylight/normalizers/active_support/cache_write.rb +16 -0
  44. data/lib/skylight/normalizers/default.rb +21 -0
  45. data/lib/skylight/normalizers/moped/query.rb +141 -0
  46. data/lib/skylight/probes.rb +91 -0
  47. data/lib/skylight/probes/excon.rb +25 -0
  48. data/lib/skylight/probes/excon/middleware.rb +65 -0
  49. data/lib/skylight/probes/net_http.rb +44 -0
  50. data/lib/skylight/probes/redis.rb +30 -0
  51. data/lib/skylight/probes/sequel.rb +30 -0
  52. data/lib/skylight/probes/sinatra.rb +74 -0
  53. data/lib/skylight/probes/tilt.rb +27 -0
  54. data/lib/skylight/railtie.rb +122 -0
  55. data/lib/skylight/sinatra.rb +4 -0
  56. data/lib/skylight/subscriber.rb +92 -0
  57. data/lib/skylight/trace.rb +191 -0
  58. data/lib/skylight/util.rb +16 -0
  59. data/lib/skylight/util/allocation_free.rb +17 -0
  60. data/lib/skylight/util/clock.rb +53 -0
  61. data/lib/skylight/util/gzip.rb +15 -0
  62. data/lib/skylight/util/hostname.rb +17 -0
  63. data/lib/skylight/util/http.rb +218 -0
  64. data/lib/skylight/util/inflector.rb +110 -0
  65. data/lib/skylight/util/logging.rb +87 -0
  66. data/lib/skylight/util/multi_io.rb +21 -0
  67. data/lib/skylight/util/native_ext_fetcher.rb +205 -0
  68. data/lib/skylight/util/platform.rb +67 -0
  69. data/lib/skylight/util/ssl.rb +50 -0
  70. data/lib/skylight/vendor/active_support/notifications.rb +207 -0
  71. data/lib/skylight/vendor/active_support/notifications/fanout.rb +159 -0
  72. data/lib/skylight/vendor/active_support/notifications/instrumenter.rb +72 -0
  73. data/lib/skylight/vendor/active_support/per_thread_registry.rb +52 -0
  74. data/lib/skylight/vendor/cli/highline.rb +1034 -0
  75. data/lib/skylight/vendor/cli/highline/color_scheme.rb +134 -0
  76. data/lib/skylight/vendor/cli/highline/compatibility.rb +16 -0
  77. data/lib/skylight/vendor/cli/highline/import.rb +41 -0
  78. data/lib/skylight/vendor/cli/highline/menu.rb +381 -0
  79. data/lib/skylight/vendor/cli/highline/question.rb +481 -0
  80. data/lib/skylight/vendor/cli/highline/simulate.rb +48 -0
  81. data/lib/skylight/vendor/cli/highline/string_extensions.rb +111 -0
  82. data/lib/skylight/vendor/cli/highline/style.rb +181 -0
  83. data/lib/skylight/vendor/cli/highline/system_extensions.rb +242 -0
  84. data/lib/skylight/vendor/cli/thor.rb +473 -0
  85. data/lib/skylight/vendor/cli/thor/actions.rb +318 -0
  86. data/lib/skylight/vendor/cli/thor/actions/create_file.rb +105 -0
  87. data/lib/skylight/vendor/cli/thor/actions/create_link.rb +60 -0
  88. data/lib/skylight/vendor/cli/thor/actions/directory.rb +119 -0
  89. data/lib/skylight/vendor/cli/thor/actions/empty_directory.rb +137 -0
  90. data/lib/skylight/vendor/cli/thor/actions/file_manipulation.rb +314 -0
  91. data/lib/skylight/vendor/cli/thor/actions/inject_into_file.rb +109 -0
  92. data/lib/skylight/vendor/cli/thor/base.rb +652 -0
  93. data/lib/skylight/vendor/cli/thor/command.rb +136 -0
  94. data/lib/skylight/vendor/cli/thor/core_ext/hash_with_indifferent_access.rb +80 -0
  95. data/lib/skylight/vendor/cli/thor/core_ext/io_binary_read.rb +12 -0
  96. data/lib/skylight/vendor/cli/thor/core_ext/ordered_hash.rb +100 -0
  97. data/lib/skylight/vendor/cli/thor/error.rb +28 -0
  98. data/lib/skylight/vendor/cli/thor/group.rb +282 -0
  99. data/lib/skylight/vendor/cli/thor/invocation.rb +172 -0
  100. data/lib/skylight/vendor/cli/thor/parser.rb +4 -0
  101. data/lib/skylight/vendor/cli/thor/parser/argument.rb +74 -0
  102. data/lib/skylight/vendor/cli/thor/parser/arguments.rb +171 -0
  103. data/lib/skylight/vendor/cli/thor/parser/option.rb +121 -0
  104. data/lib/skylight/vendor/cli/thor/parser/options.rb +218 -0
  105. data/lib/skylight/vendor/cli/thor/rake_compat.rb +72 -0
  106. data/lib/skylight/vendor/cli/thor/runner.rb +322 -0
  107. data/lib/skylight/vendor/cli/thor/shell.rb +88 -0
  108. data/lib/skylight/vendor/cli/thor/shell/basic.rb +393 -0
  109. data/lib/skylight/vendor/cli/thor/shell/color.rb +148 -0
  110. data/lib/skylight/vendor/cli/thor/shell/html.rb +127 -0
  111. data/lib/skylight/vendor/cli/thor/util.rb +270 -0
  112. data/lib/skylight/vendor/cli/thor/version.rb +3 -0
  113. data/lib/skylight/vendor/thread_safe.rb +126 -0
  114. data/lib/skylight/vendor/thread_safe/non_concurrent_cache_backend.rb +133 -0
  115. data/lib/skylight/vendor/thread_safe/synchronized_cache_backend.rb +76 -0
  116. data/lib/skylight/version.rb +4 -0
  117. data/lib/skylight/vm/gc.rb +70 -0
  118. data/lib/sql_lexer.rb +6 -0
  119. data/lib/sql_lexer/lexer.rb +579 -0
  120. data/lib/sql_lexer/string_scanner.rb +11 -0
  121. data/lib/sql_lexer/version.rb +3 -0
  122. metadata +179 -0
@@ -0,0 +1,48 @@
1
+ # simulate.rb
2
+ #
3
+ # Created by Andy Rossmeissl on 2012-04-29.
4
+ # Copyright 2005 Gray Productions. All rights reserved.
5
+ #
6
+ # This is Free Software. See LICENSE and COPYING for details.
7
+ #
8
+ # adapted from https://gist.github.com/194554
9
+ class HighLine
10
+
11
+ # Simulates Highline input for use in tests.
12
+ class Simulate
13
+
14
+ # Creates a simulator with an array of Strings as a script
15
+ def initialize(strings)
16
+ @strings = strings
17
+ end
18
+
19
+ # Simulate StringIO#gets by shifting a string off of the script
20
+ def gets
21
+ @strings.shift
22
+ end
23
+
24
+ # Simulate StringIO#getbyte by shifting a single character off of the next line of the script
25
+ def getbyte
26
+ line = gets
27
+ if line.length > 0
28
+ char = line.slice! 0
29
+ @strings.unshift line
30
+ char
31
+ end
32
+ end
33
+
34
+ # The simulator handles its own EOF
35
+ def eof?
36
+ false
37
+ end
38
+
39
+ # A wrapper method that temporarily replaces the Highline instance in $terminal with an instance of this object for the duration of the block
40
+ def self.with(*strings)
41
+ @input = $terminal.instance_variable_get :@input
42
+ $terminal.instance_variable_set :@input, new(strings)
43
+ yield
44
+ ensure
45
+ $terminal.instance_variable_set :@input, @input
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,111 @@
1
+ # Extensions for class String
2
+ #
3
+ # HighLine::String is a subclass of String with convenience methods added for colorization.
4
+ #
5
+ # Available convenience methods include:
6
+ # * 'color' method e.g. highline_string.color(:bright_blue, :underline)
7
+ # * colors e.g. highline_string.magenta
8
+ # * RGB colors e.g. highline_string.rgb_ff6000
9
+ # or highline_string.rgb(255,96,0)
10
+ # * background colors e.g. highline_string.on_magenta
11
+ # * RGB background colors e.g. highline_string.on_rgb_ff6000
12
+ # or highline_string.on_rgb(255,96,0)
13
+ # * styles e.g. highline_string.underline
14
+ #
15
+ # Additionally, convenience methods can be chained, for instance the following are equivalent:
16
+ # highline_string.bright_blue.blink.underline
17
+ # highline_string.color(:bright_blue, :blink, :underline)
18
+ # HighLine.color(highline_string, :bright_blue, :blink, :underline)
19
+ #
20
+ # For those less squeamish about possible conflicts, the same convenience methods can be
21
+ # added to the built-in String class, as follows:
22
+ #
23
+ # require 'highline'
24
+ # Highline.colorize_strings
25
+
26
+ class HighLine
27
+ def self.String(s)
28
+ HighLine::String.new(s)
29
+ end
30
+
31
+ module StringExtensions
32
+ def self.included(base)
33
+ HighLine::COLORS.each do |color|
34
+ color = color.downcase
35
+ base.class_eval <<-END
36
+ undef :#{color} if method_defined? :#{color}
37
+ def #{color}
38
+ color(:#{color})
39
+ end
40
+ END
41
+
42
+ base.class_eval <<-END
43
+ undef :on_#{color} if method_defined? :on_#{color}
44
+ def on_#{color}
45
+ on(:#{color})
46
+ end
47
+ END
48
+ HighLine::STYLES.each do |style|
49
+ style = style.downcase
50
+ base.class_eval <<-END
51
+ undef :#{style} if method_defined? :#{style}
52
+ def #{style}
53
+ color(:#{style})
54
+ end
55
+ END
56
+ end
57
+ end
58
+
59
+ base.class_eval do
60
+ undef :color if method_defined? :color
61
+ undef :foreground if method_defined? :foreground
62
+ def color(*args)
63
+ self.class.new(HighLine.color(self, *args))
64
+ end
65
+ alias_method :foreground, :color
66
+
67
+ undef :on if method_defined? :on
68
+ def on(arg)
69
+ color(('on_' + arg.to_s).to_sym)
70
+ end
71
+
72
+ undef :uncolor if method_defined? :uncolor
73
+ def uncolor
74
+ self.class.new(HighLine.uncolor(self))
75
+ end
76
+
77
+ undef :rgb if method_defined? :rgb
78
+ def rgb(*colors)
79
+ color_code = colors.map{|color| color.is_a?(Numeric) ? '%02x'%color : color.to_s}.join
80
+ raise "Bad RGB color #{colors.inspect}" unless color_code =~ /^[a-fA-F0-9]{6}/
81
+ color("rgb_#{color_code}".to_sym)
82
+ end
83
+
84
+ undef :on_rgb if method_defined? :on_rgb
85
+ def on_rgb(*colors)
86
+ color_code = colors.map{|color| color.is_a?(Numeric) ? '%02x'%color : color.to_s}.join
87
+ raise "Bad RGB color #{colors.inspect}" unless color_code =~ /^[a-fA-F0-9]{6}/
88
+ color("on_rgb_#{color_code}".to_sym)
89
+ end
90
+
91
+ # TODO Chain existing method_missing
92
+ undef :method_missing if method_defined? :method_missing
93
+ def method_missing(method, *args, &blk)
94
+ if method.to_s =~ /^(on_)?rgb_([0-9a-fA-F]{6})$/
95
+ color(method)
96
+ else
97
+ raise NoMethodError, "undefined method `#{method}' for #<#{self.class}:#{'%#x'%self.object_id}>"
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ class HighLine::String < ::String
105
+ include StringExtensions
106
+ end
107
+
108
+ def self.colorize_strings
109
+ ::String.send(:include, StringExtensions)
110
+ end
111
+ end
@@ -0,0 +1,181 @@
1
+ # color_scheme.rb
2
+ #
3
+ # Created by Richard LeBer on 2011-06-27.
4
+ # Copyright 2011. All rights reserved
5
+ #
6
+ # This is Free Software. See LICENSE and COPYING for details
7
+
8
+ class HighLine
9
+
10
+ def self.Style(*args)
11
+ args = args.compact.flatten
12
+ if args.size==1
13
+ arg = args.first
14
+ if arg.is_a?(Style)
15
+ Style.list[arg.name] || Style.index(arg)
16
+ elsif arg.is_a?(::String) && arg =~ /^\e\[/ # arg is a code
17
+ if styles = Style.code_index[arg]
18
+ styles.first
19
+ else
20
+ Style.new(:code=>arg)
21
+ end
22
+ elsif style = Style.list[arg]
23
+ style
24
+ elsif HighLine.color_scheme && HighLine.color_scheme[arg]
25
+ HighLine.color_scheme[arg]
26
+ elsif arg.is_a?(Hash)
27
+ Style.new(arg)
28
+ elsif arg.to_s.downcase =~ /^rgb_([a-f0-9]{6})$/
29
+ Style.rgb($1)
30
+ elsif arg.to_s.downcase =~ /^on_rgb_([a-f0-9]{6})$/
31
+ Style.rgb($1).on
32
+ else
33
+ raise NameError, "#{arg.inspect} is not a defined Style"
34
+ end
35
+ else
36
+ name = args
37
+ Style.list[name] || Style.new(:list=>args)
38
+ end
39
+ end
40
+
41
+ class Style
42
+
43
+ def self.index(style)
44
+ if style.name
45
+ @@styles ||= {}
46
+ @@styles[style.name] = style
47
+ end
48
+ if !style.list
49
+ @@code_index ||= {}
50
+ @@code_index[style.code] ||= []
51
+ @@code_index[style.code].reject!{|indexed_style| indexed_style.name == style.name}
52
+ @@code_index[style.code] << style
53
+ end
54
+ style
55
+ end
56
+
57
+ def self.rgb_hex(*colors)
58
+ colors.map do |color|
59
+ color.is_a?(Numeric) ? '%02x'%color : color.to_s
60
+ end.join
61
+ end
62
+
63
+ def self.rgb_parts(hex)
64
+ hex.scan(/../).map{|part| part.to_i(16)}
65
+ end
66
+
67
+ def self.rgb(*colors)
68
+ hex = rgb_hex(*colors)
69
+ name = ('rgb_' + hex).to_sym
70
+ if style = list[name]
71
+ style
72
+ else
73
+ parts = rgb_parts(hex)
74
+ new(:name=>name, :code=>"\e[38;5;#{rgb_number(parts)}m", :rgb=>parts)
75
+ end
76
+ end
77
+
78
+ def self.rgb_number(*parts)
79
+ parts = parts.flatten
80
+ 16 + parts.inject(0) {|kode, part| kode*6 + (part/256.0*6.0).floor}
81
+ end
82
+
83
+ def self.ansi_rgb_to_hex(ansi_number)
84
+ raise "Invalid ANSI rgb code #{ansi_number}" unless (16..231).include?(ansi_number)
85
+ parts = (ansi_number-16).to_s(6).rjust(3,'0').scan(/./).map{|d| (d.to_i*255.0/6.0).ceil}
86
+ rgb_hex(*parts)
87
+ end
88
+
89
+ def self.list
90
+ @@styles ||= {}
91
+ end
92
+
93
+ def self.code_index
94
+ @@code_index ||= {}
95
+ end
96
+
97
+ def self.uncolor(string)
98
+ string.gsub(/\e\[\d+(;\d+)*m/, '')
99
+ end
100
+
101
+ attr_reader :name, :list
102
+ attr_accessor :rgb, :builtin
103
+
104
+ # Single color/styles have :name, :code, :rgb (possibly), :builtin
105
+ # Compound styles have :name, :list, :builtin
106
+ def initialize(defn = {})
107
+ @definition = defn
108
+ @name = defn[:name]
109
+ @code = defn[:code]
110
+ @rgb = defn[:rgb]
111
+ @list = defn[:list]
112
+ @builtin = defn[:builtin]
113
+ if @rgb
114
+ hex = self.class.rgb_hex(@rgb)
115
+ @name ||= 'rgb_' + hex
116
+ elsif @list
117
+ @name ||= @list
118
+ end
119
+ self.class.index self unless defn[:no_index]
120
+ end
121
+
122
+ def dup
123
+ self.class.new(@definition)
124
+ end
125
+
126
+ def to_hash
127
+ @definition
128
+ end
129
+
130
+ def color(string)
131
+ code + string + HighLine::CLEAR
132
+ end
133
+
134
+ def code
135
+ if @list
136
+ @list.map{|element| HighLine.Style(element).code}.join
137
+ else
138
+ @code
139
+ end
140
+ end
141
+
142
+ def red
143
+ @rgb && @rgb[0]
144
+ end
145
+
146
+ def green
147
+ @rgb && @rgb[1]
148
+ end
149
+
150
+ def blue
151
+ @rgb && @rgb[2]
152
+ end
153
+
154
+ def variant(new_name, options={})
155
+ raise "Cannot create a variant of a style list (#{inspect})" if @list
156
+ new_code = options[:code] || code
157
+ if options[:increment]
158
+ raise "Unexpected code in #{inspect}" unless new_code =~ /^(.*?)(\d+)(.*)/
159
+ new_code = $1 + ($2.to_i + options[:increment]).to_s + $3
160
+ end
161
+ new_rgb = options[:rgb] || @rgb
162
+ self.class.new(self.to_hash.merge(:name=>new_name, :code=>new_code, :rgb=>new_rgb))
163
+ end
164
+
165
+ def on
166
+ new_name = ('on_'+@name.to_s).to_sym
167
+ self.class.list[new_name] ||= variant(new_name, :increment=>10)
168
+ end
169
+
170
+ def bright
171
+ raise "Cannot create a bright variant of a style list (#{inspect})" if @list
172
+ new_name = ('bright_'+@name.to_s).to_sym
173
+ if style = self.class.list[new_name]
174
+ style
175
+ else
176
+ new_rgb = @rgb == [0,0,0] ? [128, 128, 128] : @rgb.map {|color| color==0 ? 0 : [color+128,255].min }
177
+ variant(new_name, :increment=>60, :rgb=>new_rgb)
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,242 @@
1
+ # system_extensions.rb
2
+ #
3
+ # Created by James Edward Gray II on 2006-06-14.
4
+ # Copyright 2006 Gray Productions. All rights reserved.
5
+ #
6
+ # This is Free Software. See LICENSE and COPYING for details.
7
+
8
+ require "highline/compatibility"
9
+
10
+ class HighLine
11
+ module SystemExtensions
12
+ JRUBY = defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
13
+
14
+ if JRUBY
15
+ def initialize_system_extensions
16
+ require 'java'
17
+ require 'readline'
18
+ if JRUBY_VERSION =~ /^1.7/
19
+ java_import 'jline.console.ConsoleReader'
20
+
21
+ input = @input && @input.to_inputstream
22
+ output = @output && @output.to_outputstream
23
+
24
+ @java_console = ConsoleReader.new(input, output)
25
+ @java_console.set_history_enabled(false)
26
+ @java_console.set_bell_enabled(true)
27
+ @java_console.set_pagination_enabled(false)
28
+ @java_terminal = @java_console.getTerminal
29
+ elsif JRUBY_VERSION =~ /^1.6/
30
+ java_import 'java.io.OutputStreamWriter'
31
+ java_import 'java.nio.channels.Channels'
32
+ java_import 'jline.ConsoleReader'
33
+ java_import 'jline.Terminal'
34
+
35
+ @java_input = Channels.newInputStream(@input.to_channel)
36
+ @java_output = OutputStreamWriter.new(Channels.newOutputStream(@output.to_channel))
37
+ @java_terminal = Terminal.getTerminal
38
+ @java_console = ConsoleReader.new(@java_input, @java_output)
39
+ @java_console.setUseHistory(false)
40
+ @java_console.setBellEnabled(true)
41
+ @java_console.setUsePagination(false)
42
+ end
43
+ end
44
+ end
45
+
46
+ extend self
47
+
48
+ #
49
+ # This section builds character reading and terminal size functions
50
+ # to suit the proper platform we're running on. Be warned: Here be
51
+ # dragons!
52
+ #
53
+ if RUBY_PLATFORM =~ /mswin(?!ce)|mingw|bccwin/i
54
+ begin
55
+ require "fiddle"
56
+
57
+ module WinAPI
58
+ include Fiddle
59
+ Handle = RUBY_VERSION >= "2.0.0" ? Fiddle::Handle : DL::Handle
60
+ Kernel32 = Handle.new("kernel32")
61
+ Crt = Handle.new("msvcrt") rescue Handle.new("crtdll")
62
+
63
+ def self._getch
64
+ @@_m_getch ||= Function.new(Crt["_getch"], [], TYPE_INT)
65
+ @@_m_getch.call
66
+ end
67
+
68
+ def self.GetStdHandle(handle_type)
69
+ @@get_std_handle ||= Function.new(Kernel32["GetStdHandle"], [-TYPE_INT], -TYPE_INT)
70
+ @@get_std_handle.call(handle_type)
71
+ end
72
+
73
+ def self.GetConsoleScreenBufferInfo(cons_handle, lp_buffer)
74
+ @@get_console_screen_buffer_info ||=
75
+ Function.new(Kernel32["GetConsoleScreenBufferInfo"], [TYPE_LONG, TYPE_VOIDP], TYPE_INT)
76
+ @@get_console_screen_buffer_info.call(cons_handle, lp_buffer)
77
+ end
78
+ end
79
+ rescue LoadError
80
+ require "dl/import"
81
+
82
+ module WinAPI
83
+ if defined?(DL::Importer)
84
+ # Ruby 1.9
85
+ extend DL::Importer
86
+ else
87
+ # Ruby 1.8
88
+ extend DL::Importable
89
+ end
90
+ begin
91
+ dlload "msvcrt", "kernel32"
92
+ rescue DL::DLError
93
+ dlload "crtdll", "kernel32"
94
+ end
95
+ extern "unsigned long _getch()"
96
+ extern "unsigned long GetConsoleScreenBufferInfo(unsigned long, void*)"
97
+ extern "unsigned long GetStdHandle(unsigned long)"
98
+
99
+ # Ruby 1.8 DL::Importable.import does mname[0,1].downcase so FooBar becomes fooBar
100
+ if defined?(getConsoleScreenBufferInfo)
101
+ alias_method :GetConsoleScreenBufferInfo, :getConsoleScreenBufferInfo
102
+ module_function :GetConsoleScreenBufferInfo
103
+ end
104
+ if defined?(getStdHandle)
105
+ alias_method :GetStdHandle, :getStdHandle
106
+ module_function :GetStdHandle
107
+ end
108
+ end
109
+ end
110
+
111
+ CHARACTER_MODE = "Win32API" # For Debugging purposes only.
112
+
113
+ #
114
+ # Windows savvy getc().
115
+ #
116
+ # *WARNING*: This method ignores <tt>input</tt> and reads one
117
+ # character from +STDIN+!
118
+ #
119
+ def get_character( input = STDIN )
120
+ WinAPI._getch
121
+ end
122
+
123
+ # We do not define a raw_no_echo_mode for Windows as _getch turns off echo
124
+ def raw_no_echo_mode
125
+ end
126
+
127
+ def restore_mode
128
+ end
129
+
130
+ # A Windows savvy method to fetch the console columns, and rows.
131
+ def terminal_size
132
+ format = 'SSSSSssssSS'
133
+ buf = ([0] * format.size).pack(format)
134
+ stdout_handle = WinAPI.GetStdHandle(0xFFFFFFF5)
135
+
136
+ WinAPI.GetConsoleScreenBufferInfo(stdout_handle, buf)
137
+ _, _, _, _, _,
138
+ left, top, right, bottom, _, _ = buf.unpack(format)
139
+ return right - left + 1, bottom - top + 1
140
+ end
141
+ else # If we're not on Windows try...
142
+ begin
143
+ require "termios" # Unix, first choice termios.
144
+
145
+ CHARACTER_MODE = "termios" # For Debugging purposes only.
146
+
147
+ def raw_no_echo_mode
148
+ @state = Termios.getattr(@input)
149
+ new_settings = @state.dup
150
+ new_settings.c_lflag &= ~(Termios::ECHO | Termios::ICANON)
151
+ new_settings.c_cc[Termios::VMIN] = 1
152
+ Termios.setattr(@input, Termios::TCSANOW, new_settings)
153
+ end
154
+
155
+ def restore_mode
156
+ Termios.setattr(@input, Termios::TCSANOW, @state)
157
+ end
158
+ rescue LoadError # If our first choice fails, try using JLine
159
+ if JRUBY # if we are on JRuby. JLine is bundled with JRuby.
160
+ CHARACTER_MODE = "jline" # For Debugging purposes only.
161
+
162
+ def terminal_size
163
+ if JRUBY_VERSION =~ /^1.7/
164
+ [ @java_terminal.get_width, @java_terminal.get_height ]
165
+ else
166
+ [ @java_terminal.getTerminalWidth, @java_terminal.getTerminalHeight ]
167
+ end
168
+ end
169
+
170
+ def raw_no_echo_mode
171
+ @state = @java_console.getEchoCharacter
172
+ @java_console.setEchoCharacter 0
173
+ end
174
+
175
+ def restore_mode
176
+ @java_console.setEchoCharacter @state
177
+ end
178
+ else # If we are not on JRuby, try ncurses
179
+ begin
180
+ require 'ffi-ncurses'
181
+ CHARACTER_MODE = "ncurses" # For Debugging purposes only.
182
+
183
+ def raw_no_echo_mode
184
+ FFI::NCurses.initscr
185
+ FFI::NCurses.cbreak
186
+ end
187
+
188
+ def restore_mode
189
+ FFI::NCurses.endwin
190
+ end
191
+
192
+ #
193
+ # A ncurses savvy method to fetch the console columns, and rows.
194
+ #
195
+ def terminal_size
196
+ size = [80, 40]
197
+ FFI::NCurses.initscr
198
+ begin
199
+ size = FFI::NCurses.getmaxyx(FFI::NCurses.stdscr).reverse
200
+ ensure
201
+ FFI::NCurses.endwin
202
+ end
203
+ size
204
+ end
205
+ rescue LoadError # Finally, if all else fails, use stty
206
+ # *WARNING*: This requires the external "stty" program!
207
+ CHARACTER_MODE = "stty" # For Debugging purposes only.
208
+
209
+ def raw_no_echo_mode
210
+ @state = `stty -g`
211
+ system "stty raw -echo -icanon isig"
212
+ end
213
+
214
+ def restore_mode
215
+ system "stty #{@state}"
216
+ end
217
+ end
218
+ end
219
+ end
220
+
221
+ # For termios and stty
222
+ if not method_defined?(:terminal_size)
223
+ # A Unix savvy method using stty to fetch the console columns, and rows.
224
+ # ... stty does not work in JRuby
225
+ def terminal_size
226
+ if /solaris/ =~ RUBY_PLATFORM and
227
+ `stty` =~ /\brows = (\d+).*\bcolumns = (\d+)/
228
+ [$2, $1].map { |c| x.to_i }
229
+ else
230
+ `stty size`.split.map { |x| x.to_i }.reverse
231
+ end
232
+ end
233
+ end
234
+ end
235
+
236
+ if not method_defined?(:get_character)
237
+ def get_character( input = STDIN )
238
+ input.getbyte
239
+ end
240
+ end
241
+ end
242
+ end