truex-skylight 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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