Import upstream version 1.5.0+git20150226.1.1700234
Debian Janitor
2 years ago
0 | --- | |
1 | language: ruby | |
2 | script: "bundle exec qed" | |
3 | rvm: | |
4 | - 2.1.0 | |
5 | - 2.0.0 | |
6 | - 1.9.3 | |
7 | - rbx | |
8 | - jruby | |
9 | matrix: | |
10 | allow_failures: | |
11 | - rvm: rbx | |
12 | cache: bundler |
0 | --- | |
1 | gem: | |
2 | active: true | |
3 | ||
4 | github: | |
5 | folder: web | |
6 | ||
7 | email: | |
8 | mailto: | |
9 | - rubyworks-mailinglist@googlegroups.com | |
10 | - ruby-talk@ruby-lang.org | |
11 | ||
12 | qed: | |
13 | files : demo/ | |
14 | ||
15 | qedoc: | |
16 | files : demo/ | |
17 | title : Ruby ANSI | |
18 | output : DEMO.md | |
19 | ||
20 | minitest: | |
21 | tests : ~ | |
22 | exclude : ~ | |
23 | loadpath : ~ | |
24 | requires : ~ | |
25 | live : false | |
26 | active : false | |
27 | ||
28 | dnote: | |
29 | files : lib/**/*.rb | |
30 | title : Source Notes | |
31 | output : log/notes.html | |
32 | ||
33 | yard: | |
34 | yardopts : true | |
35 | priority : 2 # do last | |
36 | ||
37 | vclog: | |
38 | output: | |
39 | - log/history.html | |
40 | - log/changes.html | |
41 | active: false | |
42 |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | ignore 'doc', 'site', 'log' | |
3 | ||
4 | ############################################################################# | |
5 | # | |
6 | # Default | |
7 | # | |
8 | ############################################################################# | |
9 | book :default => [:demo] | |
10 | ||
11 | ############################################################################# | |
12 | # | |
13 | # Run QED demos | |
14 | # | |
15 | ############################################################################# | |
16 | book :demo do | |
17 | desc "run demos" | |
18 | ||
19 | rule "demo/*.md" => :run_demo | |
20 | rule "lib/**/*.rb" => :run_all | |
21 | ||
22 | def run_demo(*demos) | |
23 | shell "bundle exec qed -Ilib " + demos.join(' ') | |
24 | end | |
25 | ||
26 | def run_all | |
27 | shell "bundle exec qed -Ilib demo/*.md" | |
28 | end | |
29 | ||
30 | #task("demo") { shell "qed -Ilib qed/" } | |
31 | end | |
32 | ||
33 | ############################################################################# | |
34 | # | |
35 | # Run unit tests | |
36 | # | |
37 | ############################################################################# | |
38 | book :test do | |
39 | desc "run unit tests" | |
40 | ||
41 | rule 'test/helper.rb' => :test_all | |
42 | rule 'test/case_*.rb' => :test | |
43 | rule /^lib\/(.*?)\.rb$/ => :test_match | |
44 | rule /^lib\/ansi\/(.*?)\.rb$/ => :test_match | |
45 | ||
46 | def test_all | |
47 | test *Dir['test/test_*.rb'] | |
48 | end | |
49 | ||
50 | def test_match(m) | |
51 | test "test/case_#{m[1]}" | |
52 | end | |
53 | ||
54 | def test(*paths) | |
55 | shell "bundle exec rubytest #{gem_opt} -Ilib:test " + paths.flatten.join(' ') | |
56 | end | |
57 | ||
58 | def gem_opt | |
59 | defined?(::Gem) ? "-rubygems" : "" | |
60 | end | |
61 | ||
62 | #Signal.trap('QUIT') { test_all } # Ctrl-\ | |
63 | end | |
64 | ||
65 | ############################################################################# | |
66 | # | |
67 | # Update .index file | |
68 | # | |
69 | ############################################################################# | |
70 | book :index do | |
71 | desc "update index file" | |
72 | ||
73 | rule 'INDEX.yml' do | |
74 | shell "index -u INDEX.yml" | |
75 | end | |
76 | end | |
77 | ||
78 | #Signal.trap('INT' ) { abort("\n") } # Ctrl-C |
0 | --- | |
1 | name: | |
2 | ansi | |
3 | ||
4 | version: | |
5 | 1.5.0 | |
6 | ||
7 | title: | |
8 | ANSI | |
9 | ||
10 | summary: | |
11 | ANSI at your fingertips! | |
12 | ||
13 | description: | |
14 | The ANSI project is a superlative collection of ANSI escape code related | |
15 | libraries eabling ANSI colorization and stylization of console output. | |
16 | Byte for byte ANSI is the best ANSI code library available for the Ruby | |
17 | programming language. | |
18 | ||
19 | requirements: | |
20 | - mast (build) | |
21 | - indexer (build) | |
22 | - ergo (build) | |
23 | - qed (test) | |
24 | - ae (test) | |
25 | - lemon (test) | |
26 | ||
27 | resources: | |
28 | home: http://rubyworks.github.com/ansi | |
29 | docs: http://rubydoc.info/gems/ansi/frames | |
30 | code: http://github.com/rubyworks/ansi | |
31 | bugs: http://github.com/rubyworks/ansi/issues | |
32 | mail: http://groups.google.com/group/rubyworks-mailinglist | |
33 | ||
34 | repositories: | |
35 | upstream: git://github.com/rubyworks/ansi.git | |
36 | ||
37 | authors: | |
38 | - Thomas Sawyer <transfire@gmail.com> | |
39 | - Florian Frank | |
40 | ||
41 | orgranizations: | |
42 | - Rubyworks | |
43 | ||
44 | copyrights: | |
45 | - 2009 Rubyworks (BSD-2-Clause) | |
46 | ||
47 | created: | |
48 | 2009-08-01 |
0 | #!mast .index .yardopts bin lib man demo test *.md *.txt | |
1 | .index | |
2 | .yardopts | |
3 | lib/ansi/bbcode.rb | |
4 | lib/ansi/chain.rb | |
5 | lib/ansi/chart.rb | |
6 | lib/ansi/code.rb | |
7 | lib/ansi/columns.rb | |
8 | lib/ansi/constants.rb | |
9 | lib/ansi/core.rb | |
10 | lib/ansi/diff.rb | |
11 | lib/ansi/hexdump.rb | |
12 | lib/ansi/logger.rb | |
13 | lib/ansi/mixin.rb | |
14 | lib/ansi/progressbar.rb | |
15 | lib/ansi/string.rb | |
16 | lib/ansi/table.rb | |
17 | lib/ansi/terminal/curses.rb | |
18 | lib/ansi/terminal/stty.rb | |
19 | lib/ansi/terminal/termios.rb | |
20 | lib/ansi/terminal/win32.rb | |
21 | lib/ansi/terminal.rb | |
22 | lib/ansi/version.rb | |
23 | lib/ansi.rb | |
24 | lib/ansi.yml | |
25 | demo/01_ansicode.md | |
26 | demo/02_core.md | |
27 | demo/03_logger.md | |
28 | demo/04_progressbar.md | |
29 | demo/05_mixin.md | |
30 | demo/06_string.md | |
31 | demo/07_columns.md | |
32 | demo/08_table.md | |
33 | demo/09_diff.md | |
34 | demo/10_bbcode.md | |
35 | demo/11_terminal.md | |
36 | demo/applique/ae.rb | |
37 | demo/applique/output.rb | |
38 | test/case_ansicode.rb | |
39 | test/case_bbcode.rb | |
40 | test/case_mixin.rb | |
41 | test/case_progressbar.rb | |
42 | test/test_helper.rb | |
43 | NOTICE.md | |
44 | README.md | |
45 | HISTORY.md | |
46 | DEMO.md | |
47 | LICENSE.txt |
1 | 1 | |
2 | 2 | [HOME](http://rubyworks.github.com/ansi) · |
3 | 3 | [API](http://rubydoc.info/gems/ansi/frames) · |
4 | [MAIL](http://googlegroups.com/group/rubyworks-mailinglist) · | |
5 | 4 | [ISSUES](http://github.com/rubyworks/ansi/issues) · |
6 | 5 | [SOURCE](http://github.com/rubyworks/ansi) |
7 | 6 | |
55 | 54 | |
56 | 55 | ## Installation |
57 | 56 | |
57 | ### Bundler | |
58 | ||
59 | Add the usual `gem` line to your project's `Gemfile`. | |
60 | ||
61 | gem 'ansi' | |
62 | ||
63 | And run then `bundle` command. | |
64 | ||
58 | 65 | ### RubyGems |
59 | 66 | |
60 | 67 | To install with RubyGems simply open a console and type: |
0 | #/usr/bin/env ruby | |
1 | ||
2 | task :default => [:demo] | |
3 | ||
4 | desc "run demos" | |
5 | task :demo do | |
6 | sh "bundle exec qed" | |
7 | end | |
8 | ||
9 | desc "run unit tests" | |
10 | task :test do | |
11 | sh "bundle exec rubytest" | |
12 | end | |
13 |
0 | # encoding: utf-8 | |
1 | ||
2 | require 'yaml' | |
3 | require 'pathname' | |
4 | ||
5 | module Indexer | |
6 | ||
7 | # Convert index data into a gemspec. | |
8 | # | |
9 | # Notes: | |
10 | # * Assumes all executables are in bin/. | |
11 | # * Does not yet handle default_executable setting. | |
12 | # * Does not yet handle platform setting. | |
13 | # * Does not yet handle required_ruby_version. | |
14 | # * Support for rdoc entries is weak. | |
15 | # | |
16 | class GemspecExporter | |
17 | ||
18 | # File globs to include in package --unless a manifest file exists. | |
19 | FILES = ".index .yardopts alt bin data demo ext features lib man spec test try* [A-Z]*.*" unless defined?(FILES) | |
20 | ||
21 | # File globs to omit from FILES. | |
22 | OMIT = "Config.rb" unless defined?(OMIT) | |
23 | ||
24 | # Standard file patterns. | |
25 | PATTERNS = { | |
26 | :root => '{.index,Gemfile}', | |
27 | :bin => 'bin/*', | |
28 | :lib => 'lib/{**/}*', #.rb', | |
29 | :ext => 'ext/{**/}extconf.rb', | |
30 | :doc => '*.{txt,rdoc,md,markdown,tt,textile}', | |
31 | :test => '{test,spec}/{**/}*.rb' | |
32 | } unless defined?(PATTERNS) | |
33 | ||
34 | # For which revision of indexer spec is this converter intended? | |
35 | REVISION = 2013 unless defined?(REVISION) | |
36 | ||
37 | # | |
38 | def self.gemspec | |
39 | new.to_gemspec | |
40 | end | |
41 | ||
42 | # | |
43 | attr :metadata | |
44 | ||
45 | # | |
46 | def initialize(metadata=nil) | |
47 | @root_check = false | |
48 | ||
49 | if metadata | |
50 | root_dir = metadata.delete(:root) | |
51 | if root_dir | |
52 | @root = root_dir | |
53 | @root_check = true | |
54 | end | |
55 | metadata = nil if metadata.empty? | |
56 | end | |
57 | ||
58 | @metadata = metadata || YAML.load_file(root + '.index') | |
59 | ||
60 | if @metadata['revision'].to_i != REVISION | |
61 | warn "This gemspec exporter was not designed for this revision of index metadata." | |
62 | end | |
63 | end | |
64 | ||
65 | # | |
66 | def has_root? | |
67 | root ? true : false | |
68 | end | |
69 | ||
70 | # | |
71 | def root | |
72 | return @root if @root || @root_check | |
73 | @root_check = true | |
74 | @root = find_root | |
75 | end | |
76 | ||
77 | # | |
78 | def manifest | |
79 | return nil unless root | |
80 | @manifest ||= Dir.glob(root + 'manifest{,.txt}', File::FNM_CASEFOLD).first | |
81 | end | |
82 | ||
83 | # | |
84 | def scm | |
85 | return nil unless root | |
86 | @scm ||= %w{git hg}.find{ |m| (root + ".#{m}").directory? }.to_sym | |
87 | end | |
88 | ||
89 | # | |
90 | def files | |
91 | return [] unless root | |
92 | @files ||= \ | |
93 | if manifest | |
94 | File.readlines(manifest). | |
95 | map{ |line| line.strip }. | |
96 | reject{ |line| line.empty? || line[0,1] == '#' } | |
97 | else | |
98 | list = [] | |
99 | Dir.chdir(root) do | |
100 | FILES.split(/\s+/).each do |pattern| | |
101 | list.concat(glob(pattern)) | |
102 | end | |
103 | OMIT.split(/\s+/).each do |pattern| | |
104 | list = list - glob(pattern) | |
105 | end | |
106 | end | |
107 | list | |
108 | end.select{ |path| File.file?(path) }.uniq | |
109 | end | |
110 | ||
111 | # | |
112 | def glob_files(pattern) | |
113 | return [] unless root | |
114 | Dir.chdir(root) do | |
115 | Dir.glob(pattern).select do |path| | |
116 | File.file?(path) && files.include?(path) | |
117 | end | |
118 | end | |
119 | end | |
120 | ||
121 | def patterns | |
122 | PATTERNS | |
123 | end | |
124 | ||
125 | def executables | |
126 | @executables ||= \ | |
127 | glob_files(patterns[:bin]).map do |path| | |
128 | File.basename(path) | |
129 | end | |
130 | end | |
131 | ||
132 | def extensions | |
133 | @extensions ||= \ | |
134 | glob_files(patterns[:ext]).map do |path| | |
135 | File.basename(path) | |
136 | end | |
137 | end | |
138 | ||
139 | def name | |
140 | metadata['name'] || metadata['title'].downcase.gsub(/\W+/,'_') | |
141 | end | |
142 | ||
143 | def homepage | |
144 | page = ( | |
145 | metadata['resources'].find{ |r| r['type'] =~ /^home/i } || | |
146 | metadata['resources'].find{ |r| r['name'] =~ /^home/i } || | |
147 | metadata['resources'].find{ |r| r['name'] =~ /^web/i } | |
148 | ) | |
149 | page ? page['uri'] : false | |
150 | end | |
151 | ||
152 | def licenses | |
153 | metadata['copyrights'].map{ |c| c['license'] }.compact | |
154 | end | |
155 | ||
156 | def require_paths | |
157 | paths = metadata['paths'] || {} | |
158 | paths['load'] || ['lib'] | |
159 | end | |
160 | ||
161 | # | |
162 | # Convert to gemnspec. | |
163 | # | |
164 | def to_gemspec | |
165 | if has_root? | |
166 | Gem::Specification.new do |gemspec| | |
167 | to_gemspec_data(gemspec) | |
168 | to_gemspec_paths(gemspec) | |
169 | end | |
170 | else | |
171 | Gem::Specification.new do |gemspec| | |
172 | to_gemspec_data(gemspec) | |
173 | to_gemspec_paths(gemspec) | |
174 | end | |
175 | end | |
176 | end | |
177 | ||
178 | # | |
179 | # Convert pure data settings. | |
180 | # | |
181 | def to_gemspec_data(gemspec) | |
182 | gemspec.name = name | |
183 | gemspec.version = metadata['version'] | |
184 | gemspec.summary = metadata['summary'] | |
185 | gemspec.description = metadata['description'] | |
186 | ||
187 | metadata['authors'].each do |author| | |
188 | gemspec.authors << author['name'] | |
189 | ||
190 | if author.has_key?('email') | |
191 | if gemspec.email | |
192 | gemspec.email << author['email'] | |
193 | else | |
194 | gemspec.email = [author['email']] | |
195 | end | |
196 | end | |
197 | end | |
198 | ||
199 | gemspec.licenses = licenses | |
200 | ||
201 | requirements = metadata['requirements'] || [] | |
202 | requirements.each do |req| | |
203 | next if req['optional'] | |
204 | next if req['external'] | |
205 | ||
206 | name = req['name'] | |
207 | groups = req['groups'] || [] | |
208 | ||
209 | version = gemify_version(req['version']) | |
210 | ||
211 | if groups.empty? or groups.include?('runtime') | |
212 | # populate runtime dependencies | |
213 | if gemspec.respond_to?(:add_runtime_dependency) | |
214 | gemspec.add_runtime_dependency(name,*version) | |
215 | else | |
216 | gemspec.add_dependency(name,*version) | |
217 | end | |
218 | else | |
219 | # populate development dependencies | |
220 | if gemspec.respond_to?(:add_development_dependency) | |
221 | gemspec.add_development_dependency(name,*version) | |
222 | else | |
223 | gemspec.add_dependency(name,*version) | |
224 | end | |
225 | end | |
226 | end | |
227 | ||
228 | # convert external dependencies into gemspec requirements | |
229 | requirements.each do |req| | |
230 | next unless req['external'] | |
231 | gemspec.requirements << ("%s-%s" % req.values_at('name', 'version')) | |
232 | end | |
233 | ||
234 | gemspec.homepage = homepage | |
235 | gemspec.require_paths = require_paths | |
236 | gemspec.post_install_message = metadata['install_message'] | |
237 | end | |
238 | ||
239 | # | |
240 | # Set gemspec settings that require a root directory path. | |
241 | # | |
242 | def to_gemspec_paths(gemspec) | |
243 | gemspec.files = files | |
244 | gemspec.extensions = extensions | |
245 | gemspec.executables = executables | |
246 | ||
247 | if Gem::VERSION < '1.7.' | |
248 | gemspec.default_executable = gemspec.executables.first | |
249 | end | |
250 | ||
251 | gemspec.test_files = glob_files(patterns[:test]) | |
252 | ||
253 | unless gemspec.files.include?('.document') | |
254 | gemspec.extra_rdoc_files = glob_files(patterns[:doc]) | |
255 | end | |
256 | end | |
257 | ||
258 | # | |
259 | # Return a copy of this file. This is used to generate a local | |
260 | # .gemspec file that can automatically read the index file. | |
261 | # | |
262 | def self.source_code | |
263 | File.read(__FILE__) | |
264 | end | |
265 | ||
266 | private | |
267 | ||
268 | def find_root | |
269 | root_files = patterns[:root] | |
270 | if Dir.glob(root_files).first | |
271 | Pathname.new(Dir.pwd) | |
272 | elsif Dir.glob("../#{root_files}").first | |
273 | Pathname.new(Dir.pwd).parent | |
274 | else | |
275 | #raise "Can't find root of project containing `#{root_files}'." | |
276 | warn "Can't find root of project containing `#{root_files}'." | |
277 | nil | |
278 | end | |
279 | end | |
280 | ||
281 | def glob(pattern) | |
282 | if File.directory?(pattern) | |
283 | Dir.glob(File.join(pattern, '**', '*')) | |
284 | else | |
285 | Dir.glob(pattern) | |
286 | end | |
287 | end | |
288 | ||
289 | def gemify_version(version) | |
290 | case version | |
291 | when /^(.*?)\+$/ | |
292 | ">= #{$1}" | |
293 | when /^(.*?)\-$/ | |
294 | "< #{$1}" | |
295 | when /^(.*?)\~$/ | |
296 | "~> #{$1}" | |
297 | else | |
298 | version | |
299 | end | |
300 | end | |
301 | ||
302 | end | |
303 | ||
304 | end | |
305 | ||
306 | Indexer::GemspecExporter.gemspec⏎ |
51 | 51 | pbar.format("%-14s %3d%% %s %s",:title, :percentage, :bar, :stat_for_file_transfer) |
52 | 52 | run(pbar) |
53 | 53 | |
54 | The `#style` setter allows each part of the line be modified with ANSI codes. And the | |
55 | `#bar_mark` writer can be used to change the character used to make the bar. | |
54 | The `#style` setter allows each part of the line be modified with ANSI codes. | |
55 | And the `#bar_mark` writer can be used to change the character used to make the bar. | |
56 | 56 | |
57 | 57 | pbar.standard_mode |
58 | 58 | pbar.style(:title => [:red], :bar=>[:blue]) |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | QED.configure 'cov' do | |
3 | require 'simplecov' | |
4 | SimpleCov.command_name 'qed' | |
5 | SimpleCov.start do | |
6 | add_filter '/demo/' | |
7 | coverage_dir 'log/coverage' | |
8 | #add_group "Label", "lib/qed/directory" | |
9 | end | |
10 | end | |
11 |
0 | --- | |
1 | revision: 2013 | |
2 | type: ruby | |
3 | sources: | |
4 | - INDEX.yml | |
5 | authors: | |
6 | - name: Thomas Sawyer | |
7 | email: transfire@gmail.com | |
8 | - name: Florian Frank | |
9 | organizations: [] | |
10 | requirements: | |
11 | - groups: | |
12 | - build | |
13 | development: true | |
14 | name: mast | |
15 | - groups: | |
16 | - build | |
17 | development: true | |
18 | name: indexer | |
19 | - groups: | |
20 | - build | |
21 | development: true | |
22 | name: ergo | |
23 | - groups: | |
24 | - test | |
25 | development: true | |
26 | name: qed | |
27 | - groups: | |
28 | - test | |
29 | development: true | |
30 | name: ae | |
31 | - groups: | |
32 | - test | |
33 | development: true | |
34 | name: lemon | |
35 | conflicts: [] | |
36 | alternatives: [] | |
37 | resources: | |
38 | - type: home | |
39 | uri: http://rubyworks.github.com/ansi | |
40 | label: Homepage | |
41 | - type: docs | |
42 | uri: http://rubydoc.info/gems/ansi/frames | |
43 | label: Documentation | |
44 | - type: code | |
45 | uri: http://github.com/rubyworks/ansi | |
46 | label: Source Code | |
47 | - type: bugs | |
48 | uri: http://github.com/rubyworks/ansi/issues | |
49 | label: Issue Tracker | |
50 | - type: mail | |
51 | uri: http://groups.google.com/group/rubyworks-mailinglist | |
52 | label: Mailing List | |
53 | repositories: | |
54 | - name: upstream | |
55 | scm: git | |
56 | uri: git://github.com/rubyworks/ansi.git | |
57 | categories: [] | |
58 | copyrights: | |
59 | - holder: Rubyworks | |
60 | year: '2009' | |
61 | license: BSD-2-Clause | |
62 | customs: [] | |
63 | paths: | |
64 | lib: | |
65 | - lib | |
66 | name: ansi | |
67 | title: ANSI | |
68 | version: 1.5.0 | |
69 | summary: ANSI at your fingertips! | |
70 | description: The ANSI project is a superlative collection of ANSI escape code related | |
71 | libraries eabling ANSI colorization and stylization of console output. Byte for | |
72 | byte ANSI is the best ANSI code library available for the Ruby programming language. | |
73 | orgranizations: | |
74 | - Rubyworks | |
75 | created: '2009-08-01' | |
76 | date: '2015-01-16' |
0 | ../.index⏎ |
0 | --- !ruby/object:Gem::Specification | |
1 | name: ansi | |
2 | version: !ruby/object:Gem::Version | |
3 | version: 1.5.0 | |
4 | platform: ruby | |
5 | authors: | |
6 | - Thomas Sawyer | |
7 | - Florian Frank | |
8 | autorequire: | |
9 | bindir: bin | |
10 | cert_chain: [] | |
11 | date: 2015-01-17 00:00:00.000000000 Z | |
12 | dependencies: | |
13 | - !ruby/object:Gem::Dependency | |
14 | name: mast | |
15 | requirement: !ruby/object:Gem::Requirement | |
16 | requirements: | |
17 | - - '>=' | |
18 | - !ruby/object:Gem::Version | |
19 | version: '0' | |
20 | type: :development | |
21 | prerelease: false | |
22 | version_requirements: !ruby/object:Gem::Requirement | |
23 | requirements: | |
24 | - - '>=' | |
25 | - !ruby/object:Gem::Version | |
26 | version: '0' | |
27 | - !ruby/object:Gem::Dependency | |
28 | name: indexer | |
29 | requirement: !ruby/object:Gem::Requirement | |
30 | requirements: | |
31 | - - '>=' | |
32 | - !ruby/object:Gem::Version | |
33 | version: '0' | |
34 | type: :development | |
35 | prerelease: false | |
36 | version_requirements: !ruby/object:Gem::Requirement | |
37 | requirements: | |
38 | - - '>=' | |
39 | - !ruby/object:Gem::Version | |
40 | version: '0' | |
41 | - !ruby/object:Gem::Dependency | |
42 | name: ergo | |
43 | requirement: !ruby/object:Gem::Requirement | |
44 | requirements: | |
45 | - - '>=' | |
46 | - !ruby/object:Gem::Version | |
47 | version: '0' | |
48 | type: :development | |
49 | prerelease: false | |
50 | version_requirements: !ruby/object:Gem::Requirement | |
51 | requirements: | |
52 | - - '>=' | |
53 | - !ruby/object:Gem::Version | |
54 | version: '0' | |
55 | - !ruby/object:Gem::Dependency | |
56 | name: qed | |
57 | requirement: !ruby/object:Gem::Requirement | |
58 | requirements: | |
59 | - - '>=' | |
60 | - !ruby/object:Gem::Version | |
61 | version: '0' | |
62 | type: :development | |
63 | prerelease: false | |
64 | version_requirements: !ruby/object:Gem::Requirement | |
65 | requirements: | |
66 | - - '>=' | |
67 | - !ruby/object:Gem::Version | |
68 | version: '0' | |
69 | - !ruby/object:Gem::Dependency | |
70 | name: ae | |
71 | requirement: !ruby/object:Gem::Requirement | |
72 | requirements: | |
73 | - - '>=' | |
74 | - !ruby/object:Gem::Version | |
75 | version: '0' | |
76 | type: :development | |
77 | prerelease: false | |
78 | version_requirements: !ruby/object:Gem::Requirement | |
79 | requirements: | |
80 | - - '>=' | |
81 | - !ruby/object:Gem::Version | |
82 | version: '0' | |
83 | - !ruby/object:Gem::Dependency | |
84 | name: lemon | |
85 | requirement: !ruby/object:Gem::Requirement | |
86 | requirements: | |
87 | - - '>=' | |
88 | - !ruby/object:Gem::Version | |
89 | version: '0' | |
90 | type: :development | |
91 | prerelease: false | |
92 | version_requirements: !ruby/object:Gem::Requirement | |
93 | requirements: | |
94 | - - '>=' | |
95 | - !ruby/object:Gem::Version | |
96 | version: '0' | |
97 | description: The ANSI project is a superlative collection of ANSI escape code related | |
98 | libraries eabling ANSI colorization and stylization of console output. Byte for | |
99 | byte ANSI is the best ANSI code library available for the Ruby programming language. | |
100 | email: | |
101 | - transfire@gmail.com | |
102 | executables: [] | |
103 | extensions: [] | |
104 | extra_rdoc_files: | |
105 | - LICENSE.txt | |
106 | - NOTICE.md | |
107 | - README.md | |
108 | - HISTORY.md | |
109 | - DEMO.md | |
110 | files: | |
111 | - .index | |
112 | - .yardopts | |
113 | - lib/ansi/bbcode.rb | |
114 | - lib/ansi/chain.rb | |
115 | - lib/ansi/chart.rb | |
116 | - lib/ansi/code.rb | |
117 | - lib/ansi/columns.rb | |
118 | - lib/ansi/constants.rb | |
119 | - lib/ansi/core.rb | |
120 | - lib/ansi/diff.rb | |
121 | - lib/ansi/hexdump.rb | |
122 | - lib/ansi/logger.rb | |
123 | - lib/ansi/mixin.rb | |
124 | - lib/ansi/progressbar.rb | |
125 | - lib/ansi/string.rb | |
126 | - lib/ansi/table.rb | |
127 | - lib/ansi/terminal/curses.rb | |
128 | - lib/ansi/terminal/stty.rb | |
129 | - lib/ansi/terminal/termios.rb | |
130 | - lib/ansi/terminal/win32.rb | |
131 | - lib/ansi/terminal.rb | |
132 | - lib/ansi/version.rb | |
133 | - lib/ansi.rb | |
134 | - lib/ansi.yml | |
135 | - demo/01_ansicode.md | |
136 | - demo/02_core.md | |
137 | - demo/03_logger.md | |
138 | - demo/04_progressbar.md | |
139 | - demo/05_mixin.md | |
140 | - demo/06_string.md | |
141 | - demo/07_columns.md | |
142 | - demo/08_table.md | |
143 | - demo/09_diff.md | |
144 | - demo/10_bbcode.md | |
145 | - demo/11_terminal.md | |
146 | - demo/applique/ae.rb | |
147 | - demo/applique/output.rb | |
148 | - test/case_ansicode.rb | |
149 | - test/case_bbcode.rb | |
150 | - test/case_mixin.rb | |
151 | - test/case_progressbar.rb | |
152 | - test/test_helper.rb | |
153 | - NOTICE.md | |
154 | - README.md | |
155 | - HISTORY.md | |
156 | - DEMO.md | |
157 | - LICENSE.txt | |
158 | homepage: http://rubyworks.github.com/ansi | |
159 | licenses: | |
160 | - BSD-2-Clause | |
161 | metadata: {} | |
162 | post_install_message: | |
163 | rdoc_options: [] | |
164 | require_paths: | |
165 | - lib | |
166 | required_ruby_version: !ruby/object:Gem::Requirement | |
167 | requirements: | |
168 | - - '>=' | |
169 | - !ruby/object:Gem::Version | |
170 | version: '0' | |
171 | required_rubygems_version: !ruby/object:Gem::Requirement | |
172 | requirements: | |
173 | - - '>=' | |
174 | - !ruby/object:Gem::Version | |
175 | version: '0' | |
176 | requirements: [] | |
177 | rubyforge_project: | |
178 | rubygems_version: 2.0.3 | |
179 | signing_key: | |
180 | specification_version: 4 | |
181 | summary: ANSI at your fingertips! | |
182 | test_files: | |
183 | - test/case_bbcode.rb | |
184 | - test/case_progressbar.rb | |
185 | - test/case_ansicode.rb | |
186 | - test/case_mixin.rb | |
187 | - test/test_helper.rb | |
188 | has_rdoc: |
0 | = DEVELOPMENT NOTES | |
1 | ||
2 | == Tweaks Branch | |
3 | ||
4 | The `tweaks` branch needs to be merged into master. | |
5 |
0 | require 'benchmark' | |
1 | require 'ansi/code' | |
2 | ||
3 | n = 50000 | |
4 | Benchmark.bmbm(10) do |x| | |
5 | x.report("string:"){ n.times{|i| ANSI::Code.red(i.to_s) } } | |
6 | x.report("block :"){ n.times{|i| ANSI::Code.red{i.to_s} } } | |
7 | end | |
8 |
0 | require 'ansi/code' | |
1 | ||
2 | file = ARGV.first | |
3 | text = File.read(file) | |
4 | ||
5 | close = ANSI::Code.clear | |
6 | ||
7 | def uncolored(str) | |
8 | ANSI::Code.uncolored(str) | |
9 | end | |
10 | ||
11 | colors = { | |
12 | :dot => ANSI::Code.red, | |
13 | :cash => ANSI::Code.green, | |
14 | :at => ANSI::Code.cyan, | |
15 | :fn => ANSI::Code.bold + ANSI::Code.blue, | |
16 | :cap => ANSI::Code.blue, | |
17 | :sharp => ANSI::Code.white, | |
18 | :quote => ANSI::Code.red, | |
19 | } | |
20 | ||
21 | work = text.dup | |
22 | ||
23 | # xxx( | |
24 | text.gsub!(/(\W)(\w+?)(?=\()/){ $1 + colors[:fn] + $2 + close } | |
25 | ||
26 | # .xxx | |
27 | text.gsub!(/\.(\w+?)(?=\W)/){ colors[:dot] + '.' + $1 + close } | |
28 | ||
29 | # $xxx | |
30 | text.gsub!(/(\$\w+?)(?=\W)/){ colors[:cash] + $1 + close } | |
31 | ||
32 | # @xxx | |
33 | text.gsub!(/(\$\w+?)(?=\W)/){ colors[:at] + $1 + close } | |
34 | ||
35 | # #xxx | |
36 | text.gsub!(/\#(.*?)$/){ colors[:sharp] + '#' + uncolored($1) + close } | |
37 | ||
38 | # XXX | |
39 | text.gsub!(/([A-Z_]+?)(?=\W)/){ colors[:cap] + $1 + close } | |
40 | ||
41 | # 'xxx' | |
42 | text.gsub!(/(['"].*?["'])/){ colors[:quote] + uncolored($1) + close } | |
43 | ||
44 | # #xxx | |
45 | text.gsub!(/^(\s+)(\#.*?)$/){ $1 + colors[:sharp] + '#' + uncolored($2) + close } | |
46 | ||
47 | ||
48 | $stdout << text | |
49 |
0 | = Clio::String | |
1 | ||
2 | This is a unit test specification for the Clio::String class. | |
3 | This class is intended to provide a very convenient way to | |
4 | output colorful and aligned text to a shell console. | |
5 | ||
6 | Require the Clio String library. | |
7 | ||
8 | require 'clio/string' | |
9 | ||
10 | Define a few regular strings for comparison. | |
11 | ||
12 | @s1 = "Hi how are you." | |
13 | @s2 = "Fine thanks." | |
14 | ||
15 | Define the equivalent Clio strings. | |
16 | ||
17 | @c1 = Clio.string("Hi how are you.") | |
18 | @c2 = Clio.string("Fine thanks.") | |
19 | ||
20 | Clio::String#ansi is used to wrap the current string in an | |
21 | ANSI code *bracket*, ie. prepending with the given ANSI code | |
22 | and appending with the ANSI escape code. | |
23 | ||
24 | y = @c1.ansi(:red) | |
25 | x = "\e[31mHi how are you.\e[0m" | |
26 | y.to_s.should == x | |
27 | ||
28 | Some methods are delegated directly to the underying string, | |
29 | as they do not effect any ANSI codes have been applied. | |
30 | ||
31 | y = @c1.ansi(:red).upcase | |
32 | x = "\e[31mHI HOW ARE YOU.\e[0m" | |
33 | y.to_s.should == x | |
34 | ||
35 | Shortcut methods are provided for most ANSI Codes, such as | |
36 | Clio::String#red. | |
37 | ||
38 | y = @c1.red | |
39 | x = "\e[31mHi how are you.\e[0m" | |
40 | y.to_s.should == x | |
41 | ||
42 | Clio::String#[] will return the character at a gven index. | |
43 | This works like Ruby 1.9, so no size parameter is needed. | |
44 | ||
45 | y = @c1[0] | |
46 | x = @s1[0,1] | |
47 | y.to_s.should == x | |
48 | ||
49 | But the size parameter can be given too. | |
50 | ||
51 | y = @c1[0,3] | |
52 | x = @s1[0,3] | |
53 | y.to_s.should == x | |
54 | ||
55 | A Range works too. | |
56 | ||
57 | y = @c1[0..3] | |
58 | x = @s1[0..3] | |
59 | y.to_s.should == x | |
60 | ||
61 | Clio::String#+ works just like a regular String. | |
62 | ||
63 | y = @c1 + @c2 | |
64 | x = @s1 + @s2 | |
65 | y.to_s.should == x | |
66 | ||
67 | Complex cases with ANSI codes work as expected. | |
68 | ||
69 | s1 = Clio.string("a").red | |
70 | s2 = Clio.string("b").blue | |
71 | y = s1 + s2 | |
72 | x = "\e[31ma\e[0m\e[34mb\e[0m" | |
73 | y.to_s.should == x | |
74 | ||
75 | Method #sub can replace a substring. | |
76 | ||
77 | y = @c1.sub('Hi', 'Hello') | |
78 | x = "Hello how are you." | |
79 | y.to_s.assert == x | |
80 | ||
81 | Method #gsub! can replace many substrings. | |
82 | ||
83 | s1 = Clio.string("axax").red | |
84 | s2 = Clio.string("axax").blue | |
85 | y = s1 + s2 | |
86 | y.to_s.assert == "\e[31maxax\e[0m\e[34maxax\e[0m" | |
87 | y.gsub!('x', 'y') | |
88 | y.to_s.assert == "\e[31mayay\e[0m\e[34mayay\e[0m" | |
89 | ||
90 | This specification is not complete, but it is a good start. | |
91 |
0 | # ANSI Module provides a Bezel interface as follows: | |
1 | # | |
2 | # ANSI = lib('ansi', '1.2.6') | |
3 | # | |
4 | # module MyAPP | |
5 | # include ANSI | |
6 | # end | |
7 | # | |
8 | # Examples | |
9 | # | |
10 | # def hello_world | |
11 | # puts ansi("Hello World", :red) | |
12 | # end | |
13 | # | |
14 | # # automatically included with ANSI 1.3. | |
15 | # def ansi(string, *codes) | |
16 | # ANSI::Code.ansi(string, *codes) | |
17 | # end | |
18 | # | |
19 | # Or | |
20 | # | |
21 | # def hello_world | |
22 | # puts "Hello World".ansi(:red) | |
23 | # end | |
24 | # | |
25 | # NOTE: Core extensions need stable interfaces! | |
26 | # | |
27 | module ANSI; end | |
28 | ||
29 | import 'ansi/code' | |
30 | import 'ansi/bbcode' | |
31 | import 'ansi/columns' | |
32 | import 'ansi/diff' | |
33 | import 'ansi/logger' | |
34 | import 'ansi/mixin' | |
35 | import 'ansi/progressbar' | |
36 | import 'ansi/string' | |
37 | import 'ansi/table' | |
38 | import 'ansi/terminal' | |
39 |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | desc "run demos" | |
3 | ||
4 | rule "demo/*.md" => :run_demo | |
5 | rule "lib/**/*.rb" => :run_all | |
6 | ||
7 | def run_demo(*demos) | |
8 | shell "bundle exec qed -Ilib " + demos.join(' ') | |
9 | end | |
10 | ||
11 | def run_all | |
12 | shell "bundle exec qed -Ilib demo/*.md" | |
13 | end | |
14 | ||
15 | #task("demo") { shell "qed -Ilib qed/" } | |
16 |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | desc "update index file" | |
3 | ||
4 | rule 'Index.yml' do | |
5 | shell "index -u Index.yml" | |
6 | end | |
7 |
0 | #!/usr/bin/env ruby | |
1 | file = "lib/#{project.metadata.name}/version.rb" | |
2 | ||
3 | line = [] | |
4 | line << "module ANSI" | |
5 | line << " VERSION = '#{project.version}'" | |
6 | line << " DATE = '#{Time.new.strftime("%Y-%m-%d")}'" | |
7 | ||
8 | #project.profile.to_h.each do |key, value| | |
9 | # next if key == "manifest" | |
10 | # line << " #{key.upcase} = #{value.inspect}" | |
11 | #end | |
12 | ||
13 | line << "end" | |
14 | ||
15 | text = line.join("\n") | |
16 | ||
17 | if !exist?(file) || read(file) != text | |
18 | write(file, text) | |
19 | report "Updated #{file}" | |
20 | else | |
21 | report "Already current #{file}" | |
22 | end | |
23 |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | desc "run unit tests" | |
3 | ||
4 | rule 'test/helper.rb' => :test_all | |
5 | rule 'test/case_*.rb' => :test | |
6 | rule /^lib\/(.*?)\.rb$/ => :test_match | |
7 | rule /^lib\/ansi\/(.*?)\.rb$/ => :test_match | |
8 | ||
9 | def test_all | |
10 | test *Dir['test/test_*.rb'] | |
11 | end | |
12 | ||
13 | def test_match(m) | |
14 | test "test/case_#{m[1]}" | |
15 | end | |
16 | ||
17 | def test(*paths) | |
18 | shell "bundle exec rubytest #{gem_opt} -Ilib:test " + paths.flatten.join(' ') | |
19 | end | |
20 | ||
21 | def gem_opt | |
22 | defined?(::Gem) ? "-rubygems" : "" | |
23 | end | |
24 | ||
25 | #Signal.trap('QUIT') { test tests } # Ctrl-\ | |
26 | #Signal.trap('INT' ) { abort("\n") } # Ctrl-C | |
27 |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | watch( '^test.*/test_.*\.rb' ) { |m| test m[0] } | |
3 | watch( '^lib/(.*)\.rb' ) { |m| test "test/case_#{m[1]}.rb" } | |
4 | watch( '^lib/ansi/(.*)\.rb' ) { |m| test "test/case_#{m[1]}.rb" } | |
5 | watch( '^test/test_helper\.rb' ) { test tests } | |
6 | ||
7 | Signal.trap('QUIT') { test tests } # Ctrl-\ | |
8 | Signal.trap('INT' ) { abort("\n") } # Ctrl-C | |
9 | ||
10 | def test(*paths) | |
11 | run "ruby-test #{gem_opt} -Ilib:test #{paths.flatten.join(' ')}" | |
12 | end | |
13 | ||
14 | def tests | |
15 | Dir['test/**/case_*.rb'] | |
16 | end | |
17 | ||
18 | def run(cmd) | |
19 | puts cmd | |
20 | system cmd | |
21 | end | |
22 | ||
23 | def gem_opt | |
24 | defined?(Gem) ? "-rubygems" : "" | |
25 | end | |
26 |
0 | # = ANSICode | |
1 | # | |
2 | # Module which makes it very easy to use ANSI codes. | |
3 | # These are esspecially nice for beautifying shell output. | |
4 | # | |
5 | # include ANSICode | |
6 | # | |
7 | # p red, "Hello", blue, "World" | |
8 | # => "\e[31mHello\e[34mWorld" | |
9 | # | |
10 | # p red { "Hello" } + blue { "World" } | |
11 | # => "\e[31mHello\e[0m\e[34mWorld\e[0m" | |
12 | # | |
13 | # == Supported ANSI Comands | |
14 | # | |
15 | # The following is a list of supported codes. | |
16 | # | |
17 | # save | |
18 | # restore | |
19 | # clear_screen | |
20 | # cls # synonym for :clear_screen | |
21 | # clear_line | |
22 | # clr # synonym for :clear_line | |
23 | # move | |
24 | # up | |
25 | # down | |
26 | # left | |
27 | # right | |
28 | # display | |
29 | # | |
30 | # clear | |
31 | # reset # synonym for :clear | |
32 | # bold | |
33 | # dark | |
34 | # italic # not widely implemented | |
35 | # underline | |
36 | # underscore # synonym for :underline | |
37 | # blink | |
38 | # rapid_blink # not widely implemented | |
39 | # negative # no reverse because of String#reverse | |
40 | # concealed | |
41 | # strikethrough # not widely implemented | |
42 | # | |
43 | # black | |
44 | # red | |
45 | # green | |
46 | # yellow | |
47 | # blue | |
48 | # magenta | |
49 | # cyan | |
50 | # white | |
51 | # | |
52 | # on_black | |
53 | # on_red | |
54 | # on_green | |
55 | # on_yellow | |
56 | # on_blue | |
57 | # on_magenta | |
58 | # on_cyan | |
59 | # on_white | |
60 | # | |
61 | # == Authors | |
62 | # | |
63 | # * Florian Frank | |
64 | # * Thomas Sawyer | |
65 | # | |
66 | # == Speical Thanks | |
67 | # | |
68 | # Special thanks to Florian Frank. ANSICode is a partial adaptation | |
69 | # of ANSIColor, Copyright (c) 2002 Florian Frank, LGPL. | |
70 | # | |
71 | # == Todo | |
72 | # | |
73 | # * Need to add rest of ANSI codes. Include modes? | |
74 | # * Re-evaluate how color/yielding methods are defined. | |
75 | # * Maybe up, down, right, left should have yielding methods too? | |
76 | # | |
77 | # == Copying | |
78 | # | |
79 | # Copyright (c) 2004 Florian Frank, Thomas Sawyer | |
80 | # | |
81 | # Ruby License | |
82 | # | |
83 | # This module is free software. You may use, modify, and/or redistribute this | |
84 | # software under the same terms as Ruby. | |
85 | # | |
86 | # This program is distributed in the hope that it will be useful, but WITHOUT | |
87 | # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | |
88 | # FOR A PARTICULAR PURPOSE. | |
89 | ||
90 | ||
91 | # = ANSICode | |
92 | # | |
93 | # Module which makes it very easy to use ANSI codes. | |
94 | # These are esspecially nice for beautifying shell output. | |
95 | # | |
96 | # include ANSICode | |
97 | # | |
98 | # p red, "Hello", blue, "World" | |
99 | # => "\e[31mHello\e[34mWorld" | |
100 | # | |
101 | # p red { "Hello" } + blue { "World" } | |
102 | # => "\e[31mHello\e[0m\e[34mWorld\e[0m" | |
103 | # | |
104 | # == Supported ANSI Comands | |
105 | # | |
106 | # The following is a list of supported codes. | |
107 | # | |
108 | # save | |
109 | # restore | |
110 | # clear_screen | |
111 | # cls # synonym for :clear_screen | |
112 | # clear_line | |
113 | # clr # synonym for :clear_line | |
114 | # move | |
115 | # up | |
116 | # down | |
117 | # left | |
118 | # right | |
119 | # display | |
120 | # | |
121 | # clear | |
122 | # reset # synonym for :clear | |
123 | # bold | |
124 | # dark | |
125 | # italic # not widely implemented | |
126 | # underline | |
127 | # underscore # synonym for :underline | |
128 | # blink | |
129 | # rapid_blink # not widely implemented | |
130 | # negative # no reverse because of String#reverse | |
131 | # concealed | |
132 | # strikethrough # not widely implemented | |
133 | # | |
134 | # black | |
135 | # red | |
136 | # green | |
137 | # yellow | |
138 | # blue | |
139 | # magenta | |
140 | # cyan | |
141 | # white | |
142 | # | |
143 | # on_black | |
144 | # on_red | |
145 | # on_green | |
146 | # on_yellow | |
147 | # on_blue | |
148 | # on_magenta | |
149 | # on_cyan | |
150 | # on_white | |
151 | # | |
152 | module ANSICode | |
153 | ||
154 | extend self | |
155 | ||
156 | # Save current cursor positon. | |
157 | ||
158 | def save | |
159 | "\e[s" | |
160 | end | |
161 | ||
162 | # Restore saved cursor positon. | |
163 | ||
164 | def restore | |
165 | "\e[u" | |
166 | end | |
167 | ||
168 | # Clear the screen and move cursor to home. | |
169 | ||
170 | def clear_screen | |
171 | "\e[2J" | |
172 | end | |
173 | alias_method :cls, :clear_screen | |
174 | ||
175 | # Clear to the end of the current line. | |
176 | ||
177 | def clear_line | |
178 | "\e[K" | |
179 | end | |
180 | alias_method :clr, :clear_line | |
181 | ||
182 | #-- | |
183 | #def position | |
184 | # "\e[#;#R" | |
185 | #end | |
186 | #++ | |
187 | ||
188 | # Move curose to line and column. | |
189 | ||
190 | def move( line, column=0 ) | |
191 | "\e[#{line.to_i};#{column.to_i}H" | |
192 | end | |
193 | ||
194 | # Move cursor up a specificed number of spaces. | |
195 | ||
196 | def up( spaces=1 ) | |
197 | "\e[#{spaces.to_i}A" | |
198 | end | |
199 | ||
200 | # Move cursor down a specificed number of spaces. | |
201 | ||
202 | def down( spaces=1 ) | |
203 | "\e[#{spaces.to_i}B" | |
204 | end | |
205 | ||
206 | # Move cursor left a specificed number of spaces. | |
207 | ||
208 | def left( spaces=1 ) | |
209 | "\e[#{spaces.to_i}D" | |
210 | end | |
211 | ||
212 | # Move cursor right a specificed number of spaces. | |
213 | ||
214 | def right( spaces=1 ) | |
215 | "\e[#{spaces.to_i}C" | |
216 | end | |
217 | ||
218 | # Like +move+ but returns to original positon | |
219 | # after yielding block or adding string argument. | |
220 | ||
221 | def display( line, column=0, string=nil ) #:yield: | |
222 | result = "\e[s" | |
223 | result << "\e[#{line.to_i};#{column.to_i}H" | |
224 | if block_given? | |
225 | result << yield | |
226 | result << "\e[u" | |
227 | elsif string | |
228 | result << string | |
229 | result << "\e[u" | |
230 | elsif respond_to?(:to_str) | |
231 | result << self | |
232 | result << "\e[u" | |
233 | end | |
234 | return result | |
235 | end | |
236 | ||
237 | # Define color codes. | |
238 | ||
239 | def self.define_ansicolor_method(name,code) | |
240 | class_eval <<-HERE | |
241 | def #{name.to_s}(string = nil) | |
242 | result = "\e[#{code}m" | |
243 | if block_given? | |
244 | result << yield | |
245 | result << "\e[0m" | |
246 | elsif string | |
247 | result << string | |
248 | result << "\e[0m" | |
249 | elsif respond_to?(:to_str) | |
250 | result << self | |
251 | result << "\e[0m" | |
252 | end | |
253 | return result | |
254 | end | |
255 | HERE | |
256 | end | |
257 | ||
258 | @@colors = [ | |
259 | [ :clear , 0 ], | |
260 | [ :reset , 0 ], # synonym for :clear | |
261 | [ :bold , 1 ], | |
262 | [ :dark , 2 ], | |
263 | [ :italic , 3 ], # not widely implemented | |
264 | [ :underline , 4 ], | |
265 | [ :underscore , 4 ], # synonym for :underline | |
266 | [ :blink , 5 ], | |
267 | [ :rapid_blink , 6 ], # not widely implemented | |
268 | [ :negative , 7 ], # no reverse because of String#reverse | |
269 | [ :concealed , 8 ], | |
270 | [ :strikethrough, 9 ], # not widely implemented | |
271 | [ :black , 30 ], | |
272 | [ :red , 31 ], | |
273 | [ :green , 32 ], | |
274 | [ :yellow , 33 ], | |
275 | [ :blue , 34 ], | |
276 | [ :magenta , 35 ], | |
277 | [ :cyan , 36 ], | |
278 | [ :white , 37 ], | |
279 | [ :on_black , 40 ], | |
280 | [ :on_red , 41 ], | |
281 | [ :on_green , 42 ], | |
282 | [ :on_yellow , 43 ], | |
283 | [ :on_blue , 44 ], | |
284 | [ :on_magenta , 45 ], | |
285 | [ :on_cyan , 46 ], | |
286 | [ :on_white , 47 ], | |
287 | ] | |
288 | ||
289 | @@colors.each do |c, v| | |
290 | define_ansicolor_method(c, v) | |
291 | end | |
292 | ||
293 | ColoredRegexp = /\e\[([34][0-7]|[0-9])m/ | |
294 | ||
295 | def uncolored(string = nil) | |
296 | if block_given? | |
297 | yield.gsub(ColoredRegexp, '') | |
298 | elsif string | |
299 | string.gsub(ColoredRegexp, '') | |
300 | elsif respond_to?(:to_str) | |
301 | gsub(ColoredRegexp, '') | |
302 | else | |
303 | '' | |
304 | end | |
305 | end | |
306 | ||
307 | module_function | |
308 | ||
309 | def colors | |
310 | @@colors.map { |c| c[0] } | |
311 | end | |
312 | ||
313 | end | |
314 |
0 | doc |
0 | ||
1 | #include "windows.h" | |
2 | #include "ruby.h" | |
3 | ||
4 | #ifdef WIN32 | |
5 | #define CONSOLE_EXPORT __declspec(dllexport) | |
6 | #else | |
7 | #error Not compiling on Windows | |
8 | #endif | |
9 | ||
10 | VALUE rb_mWin32; | |
11 | VALUE rb_mConsole; | |
12 | VALUE rb_mAPI; | |
13 | VALUE rb_mConstants; | |
14 | ||
15 | /* old RUBY_METHOD_FUNC() definition doesn't match to prototypes in those days. */ | |
16 | #ifndef ANYARGS | |
17 | #undef RUBY_METHOD_FUNC | |
18 | #define RUBY_METHOD_FUNC(func) ((VALUE (*)())func) | |
19 | #endif | |
20 | ||
21 | ||
22 | #define RB_DEF_S_METHOD(klass,method,func,argtype) \ | |
23 | rb_define_singleton_method(klass,method,RUBY_METHOD_FUNC(func), argtype) | |
24 | ||
25 | #define RB_DEF_API_METHOD(name,argtype) \ | |
26 | RB_DEF_S_METHOD(rb_mAPI,#name,RUBY_METHOD_FUNC(rb_##name), argtype) | |
27 | ||
28 | #define RB_DEF_METHOD(klass,method,func,argtype) \ | |
29 | rb_define_method(klass,method,RUBY_METHOD_FUNC(func), argtype) | |
30 | ||
31 | VALUE | |
32 | rb_getWin32Error() | |
33 | { | |
34 | DWORD e = GetLastError(); | |
35 | LPVOID lpMsgBuf; | |
36 | if (!FormatMessage( | |
37 | FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
38 | FORMAT_MESSAGE_FROM_SYSTEM | | |
39 | FORMAT_MESSAGE_IGNORE_INSERTS, | |
40 | NULL, | |
41 | GetLastError(), | |
42 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language | |
43 | (LPTSTR) &lpMsgBuf, | |
44 | 0, | |
45 | NULL )) | |
46 | { | |
47 | // Handle the error. | |
48 | return Qnil; | |
49 | } | |
50 | ||
51 | VALUE t = rb_str_new2( (LPCTSTR) lpMsgBuf ); | |
52 | ||
53 | // Free the buffer. | |
54 | LocalFree( lpMsgBuf ); | |
55 | ||
56 | // Raise exception | |
57 | rb_raise(rb_eRuntimeError, RSTRING(t)->ptr); | |
58 | return Qnil; | |
59 | ||
60 | } | |
61 | ||
62 | ||
63 | extern "C" | |
64 | { | |
65 | ||
66 | static VALUE rb_GetStdHandle(VALUE self, VALUE handle) | |
67 | { | |
68 | unsigned long x; | |
69 | if ( FIXNUM_P( handle ) ) | |
70 | { | |
71 | x = NUM2ULONG( handle ); | |
72 | } | |
73 | else | |
74 | { | |
75 | Check_Type( handle, T_BIGNUM ); | |
76 | x = rb_big2ulong(handle); | |
77 | } | |
78 | unsigned long h = PtrToUlong( GetStdHandle( x ) ); | |
79 | return ULONG2NUM(h); | |
80 | } | |
81 | ||
82 | ||
83 | static VALUE rb_AllocConsole(VALUE self) | |
84 | { | |
85 | if (AllocConsole()) return INT2FIX(1); | |
86 | return rb_getWin32Error(); | |
87 | } | |
88 | ||
89 | ||
90 | static VALUE rb_FreeConsole(VALUE self) | |
91 | { | |
92 | if (FreeConsole()) return INT2FIX(1); | |
93 | return rb_getWin32Error(); | |
94 | } | |
95 | ||
96 | static VALUE rb_GenerateConsoleCtrlEvent(VALUE self, VALUE event, VALUE pgid) | |
97 | { | |
98 | unsigned int e = NUM2UINT(event); | |
99 | if ( e != CTRL_C_EVENT && e != CTRL_BREAK_EVENT ) | |
100 | rb_raise(rb_eArgError, "Wrong event: only CTRL_C_EVENT or " | |
101 | "CTRL_BREAK_EVENT accepted."); | |
102 | if ( GenerateConsoleCtrlEvent(e, NUM2UINT(pgid)) ) | |
103 | return INT2FIX(1); | |
104 | return rb_getWin32Error(); | |
105 | } | |
106 | ||
107 | static VALUE rb_GetConsoleMode(VALUE self, VALUE hConsoleOutput) | |
108 | { | |
109 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
110 | DWORD mode; | |
111 | if (GetConsoleMode(handle,&mode)) | |
112 | return UINT2NUM(mode); | |
113 | return rb_getWin32Error(); | |
114 | } | |
115 | ||
116 | static VALUE rb_GetConsoleTitle(VALUE self) | |
117 | { | |
118 | char title[1024]; | |
119 | if (GetConsoleTitle((char*)&title,1024)) | |
120 | return rb_str_new2( title ); | |
121 | return rb_getWin32Error(); | |
122 | } | |
123 | ||
124 | ||
125 | ||
126 | ||
127 | static VALUE rb_GetNumberOfConsoleMouseButtons( VALUE self ) | |
128 | { | |
129 | DWORD mb; | |
130 | if (GetNumberOfConsoleMouseButtons( &mb )) | |
131 | return INT2FIX(mb); | |
132 | return rb_getWin32Error(); | |
133 | } | |
134 | ||
135 | ||
136 | ||
137 | static VALUE rb_GetNumberOfConsoleInputEvents( VALUE self, VALUE hConsoleOutput ) | |
138 | { | |
139 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
140 | DWORD events; | |
141 | if (GetNumberOfConsoleInputEvents(handle, &events)) | |
142 | return INT2FIX(events); | |
143 | return rb_getWin32Error(); | |
144 | } | |
145 | ||
146 | ||
147 | static VALUE | |
148 | rb_CreateConsoleScreenBuffer( VALUE self, VALUE dwDesiredAccess, | |
149 | VALUE dwShareMode, VALUE dwFlags ) | |
150 | { | |
151 | if (CreateConsoleScreenBuffer( NUM2UINT(dwDesiredAccess), | |
152 | NUM2UINT( dwShareMode), | |
153 | NULL, | |
154 | NUM2UINT( dwFlags), | |
155 | NULL | |
156 | )) | |
157 | return INT2FIX(1); | |
158 | return rb_getWin32Error(); | |
159 | } | |
160 | ||
161 | ||
162 | static VALUE rb_GetConsoleCP( VALUE self ) | |
163 | { | |
164 | unsigned int h = GetConsoleCP(); | |
165 | return UINT2NUM(h); | |
166 | } | |
167 | ||
168 | static VALUE rb_GetConsoleOutputCP( VALUE self ) | |
169 | { | |
170 | unsigned int h = GetConsoleOutputCP(); | |
171 | return UINT2NUM(h); | |
172 | } | |
173 | ||
174 | static VALUE rb_SetConsoleMode( VALUE self, VALUE hConsoleOutput, | |
175 | VALUE Mode ) | |
176 | { | |
177 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
178 | if ( SetConsoleMode( handle, NUM2UINT( Mode ) ) ) | |
179 | return INT2FIX(1); | |
180 | return rb_getWin32Error(); | |
181 | } | |
182 | ||
183 | static VALUE rb_SetConsoleCP( VALUE self, VALUE wCodePageID ) | |
184 | { | |
185 | if ( SetConsoleCP( NUM2UINT( wCodePageID ) ) ) | |
186 | return INT2FIX(1); | |
187 | return rb_getWin32Error(); | |
188 | } | |
189 | ||
190 | static VALUE rb_SetConsoleOutputCP( VALUE self, VALUE wCodePageID ) | |
191 | { | |
192 | if ( SetConsoleOutputCP( NUM2UINT( wCodePageID ) ) ) | |
193 | return INT2FIX(1); | |
194 | return rb_getWin32Error(); | |
195 | } | |
196 | ||
197 | static VALUE rb_GetConsoleWindow( VALUE self ) | |
198 | { | |
199 | unsigned long h = PtrToUlong( GetConsoleOutputCP() ); | |
200 | return ULONG2NUM(h); | |
201 | } | |
202 | ||
203 | static VALUE rb_WriteConsole( VALUE self, VALUE hConsoleOutput, | |
204 | VALUE lpBuffer ) | |
205 | { | |
206 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
207 | DWORD nNumberOfCharsToWrite = RSTRING(lpBuffer)->len; | |
208 | ||
209 | DWORD lpNumberOfCharsWritten; | |
210 | ||
211 | WriteConsole( handle, RSTRING(lpBuffer)->ptr, | |
212 | nNumberOfCharsToWrite, | |
213 | &lpNumberOfCharsWritten, NULL ); | |
214 | return UINT2NUM( lpNumberOfCharsWritten ); | |
215 | } | |
216 | ||
217 | ||
218 | static VALUE rb_GetLargestConsoleWindowSize( VALUE self, VALUE hConsoleOutput ) | |
219 | { | |
220 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
221 | COORD size = GetLargestConsoleWindowSize( handle); | |
222 | ||
223 | VALUE ret = rb_ary_new(); | |
224 | rb_ary_push( ret, UINT2NUM( size.X ) ); | |
225 | rb_ary_push( ret, UINT2NUM( size.Y ) ); | |
226 | return ret; | |
227 | } | |
228 | ||
229 | static VALUE rb_GetConsoleCursorInfo( VALUE self, VALUE hConsoleOutput ) | |
230 | { | |
231 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
232 | ||
233 | CONSOLE_CURSOR_INFO out; | |
234 | if ( !GetConsoleCursorInfo( handle, &out ) ) | |
235 | return rb_getWin32Error(); | |
236 | ||
237 | VALUE ret = rb_ary_new(); | |
238 | rb_ary_push( ret, UINT2NUM( out.dwSize ) ); | |
239 | rb_ary_push( ret, UINT2NUM( out.bVisible ) ); | |
240 | return ret; | |
241 | } | |
242 | ||
243 | void rb_ParseEvent(VALUE ret, INPUT_RECORD& event ) | |
244 | { | |
245 | switch(event.EventType) { | |
246 | case KEY_EVENT: | |
247 | { | |
248 | KEY_EVENT_RECORD* kevent=(KEY_EVENT_RECORD *)&(event.Event); | |
249 | rb_ary_push(ret, UINT2NUM(KEY_EVENT)); | |
250 | rb_ary_push(ret, UINT2NUM(kevent->bKeyDown)); | |
251 | rb_ary_push(ret, UINT2NUM(kevent->wRepeatCount)); | |
252 | rb_ary_push(ret, UINT2NUM(kevent->wVirtualKeyCode)); | |
253 | rb_ary_push(ret, UINT2NUM(kevent->wVirtualScanCode)); | |
254 | #ifdef UNICODE | |
255 | rb_ary_push(ret, UINT2NUM(kevent->uChar.UnicodeChar)); | |
256 | #else | |
257 | rb_ary_push(ret, UINT2NUM(kevent->uChar.AsciiChar)); | |
258 | #endif | |
259 | rb_ary_push(ret, UINT2NUM(kevent->dwControlKeyState)); | |
260 | break; | |
261 | } | |
262 | case MOUSE_EVENT: | |
263 | { | |
264 | MOUSE_EVENT_RECORD * mevent=(MOUSE_EVENT_RECORD *)&(event.Event); | |
265 | rb_ary_push(ret, UINT2NUM(MOUSE_EVENT) ); | |
266 | rb_ary_push(ret, UINT2NUM(mevent->dwMousePosition.X) ); | |
267 | rb_ary_push(ret, UINT2NUM(mevent->dwMousePosition.Y) ); | |
268 | rb_ary_push(ret, UINT2NUM(mevent->dwButtonState) ); | |
269 | rb_ary_push(ret, UINT2NUM(mevent->dwControlKeyState) ); | |
270 | rb_ary_push(ret, UINT2NUM(mevent->dwEventFlags) ); | |
271 | break; | |
272 | } | |
273 | case WINDOW_BUFFER_SIZE_EVENT: | |
274 | { | |
275 | WINDOW_BUFFER_SIZE_RECORD* wevent= | |
276 | (WINDOW_BUFFER_SIZE_RECORD *)&(event.Event); | |
277 | rb_ary_push(ret, UINT2NUM(WINDOW_BUFFER_SIZE_EVENT) ); | |
278 | rb_ary_push(ret, UINT2NUM(wevent->dwSize.X) ); | |
279 | rb_ary_push(ret, UINT2NUM(wevent->dwSize.Y) ); | |
280 | } | |
281 | break; | |
282 | case MENU_EVENT: | |
283 | { | |
284 | MENU_EVENT_RECORD* mevent= (MENU_EVENT_RECORD *)&(event.Event); | |
285 | rb_ary_push(ret, UINT2NUM(MENU_EVENT) ); | |
286 | rb_ary_push(ret, UINT2NUM(mevent->dwCommandId) ); | |
287 | } | |
288 | break; | |
289 | case FOCUS_EVENT: | |
290 | { | |
291 | FOCUS_EVENT_RECORD* mevent= (FOCUS_EVENT_RECORD *)&(event.Event); | |
292 | rb_ary_push(ret, UINT2NUM(FOCUS_EVENT) ); | |
293 | rb_ary_push(ret, UINT2NUM(mevent->bSetFocus) ); | |
294 | } | |
295 | break; | |
296 | } | |
297 | } | |
298 | ||
299 | static VALUE rb_PeekConsoleInput( VALUE self, VALUE hConsoleOutput ) | |
300 | { | |
301 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
302 | ||
303 | DWORD nofread; | |
304 | INPUT_RECORD event; | |
305 | if (!PeekConsoleInput(handle,&event,1,&nofread)) | |
306 | return rb_getWin32Error(); | |
307 | ||
308 | VALUE ret = rb_ary_new(); | |
309 | rb_ParseEvent( ret, event ); | |
310 | return ret; | |
311 | } | |
312 | ||
313 | static VALUE rb_ReadConsole( VALUE self, VALUE hConsoleOutput, | |
314 | VALUE buffer, VALUE numread ) | |
315 | { | |
316 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
317 | DWORD nofread; | |
318 | Check_Type( buffer, T_STRING ); | |
319 | int to_read = NUM2INT(numread); | |
320 | if ( RSTRING(buffer)->len > to_read ) | |
321 | rb_raise(rb_eArgError, "String is too small to read that many characters."); | |
322 | if (ReadConsole(handle,(void *)RSTRING(buffer)->ptr, to_read, | |
323 | &nofread,NULL)) | |
324 | return UINT2NUM(nofread); | |
325 | return rb_getWin32Error(); | |
326 | } | |
327 | ||
328 | static VALUE rb_ReadConsoleInput( VALUE self, VALUE hConsoleOutput ) | |
329 | { | |
330 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
331 | DWORD nofread; | |
332 | INPUT_RECORD event; | |
333 | if (!ReadConsoleInput(handle,&event,1,&nofread)) | |
334 | return rb_getWin32Error(); | |
335 | ||
336 | VALUE ret = rb_ary_new(); | |
337 | rb_ParseEvent( ret, event ); | |
338 | return ret; | |
339 | } | |
340 | ||
341 | ||
342 | ||
343 | static VALUE rb_ReadConsoleOutputCharacter( VALUE self, VALUE hConsoleOutput, | |
344 | VALUE charbuf, VALUE len, | |
345 | VALUE x, VALUE y ) | |
346 | { | |
347 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
348 | COORD coords; | |
349 | DWORD nofread; | |
350 | coords.X= NUM2UINT( x ); | |
351 | coords.Y= NUM2UINT( y ); | |
352 | int l = NUM2INT(len); | |
353 | if ( RSTRING(charbuf)->len < l*sizeof(TCHAR) ) | |
354 | rb_raise(rb_eArgError, "String is too small to read that many characters."); | |
355 | if (ReadConsoleOutputCharacter(handle,RSTRING(charbuf)->ptr,l, | |
356 | coords,&nofread)) | |
357 | return UINT2NUM( nofread ); | |
358 | return rb_getWin32Error(); | |
359 | } | |
360 | ||
361 | ||
362 | static VALUE rb_ReadConsoleOutputAttribute( VALUE self, VALUE hConsoleOutput, | |
363 | VALUE len, VALUE x, VALUE y ) | |
364 | { | |
365 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
366 | COORD coords; | |
367 | DWORD nofread; | |
368 | unsigned short abuffer[80*999*sizeof(unsigned short)]; | |
369 | char cbuffer[80*999]; | |
370 | coords.X= NUM2UINT( x ); | |
371 | coords.Y= NUM2UINT( y ); | |
372 | if (ReadConsoleOutputAttribute(handle, abuffer, NUM2UINT(len), | |
373 | coords,&nofread)) | |
374 | { | |
375 | for(unsigned i=0;i<nofread;++i) { | |
376 | cbuffer[i]=(char)abuffer[i]; | |
377 | } | |
378 | return rb_str_new( cbuffer, nofread ); | |
379 | } | |
380 | return rb_getWin32Error(); | |
381 | } | |
382 | ||
383 | ||
384 | static VALUE rb_ReadConsoleOutput( VALUE self, VALUE hConsoleOutput, | |
385 | VALUE buffer, VALUE srcwid, VALUE srcht, | |
386 | VALUE startx, VALUE starty, | |
387 | VALUE l, VALUE t, VALUE r, VALUE b ) | |
388 | { | |
389 | COORD coords; | |
390 | COORD size; | |
391 | SMALL_RECT from; | |
392 | size.X= NUM2UINT( srcwid ); | |
393 | size.Y= NUM2UINT( srcht ); | |
394 | coords.X= NUM2INT( startx ); | |
395 | coords.Y= NUM2INT( starty ); | |
396 | from.Left = NUM2INT( l ); | |
397 | from.Top = NUM2INT( t ); | |
398 | from.Right = NUM2INT( r ); | |
399 | from.Bottom = NUM2INT( b ); | |
400 | Check_Type( buffer, T_STRING ); | |
401 | if ( RSTRING(buffer)->len < (sizeof(CHAR_INFO)*size.X*size.Y) ) | |
402 | rb_raise(rb_eArgError, "string buffer is too small for reading that many characters."); | |
403 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
404 | if (!ReadConsoleOutput(handle,(CHAR_INFO *)RSTRING(buffer)->ptr,size,coords,&from)) | |
405 | return rb_getWin32Error(); | |
406 | ||
407 | VALUE ret = rb_ary_new(); | |
408 | rb_ary_push( ret, INT2FIX(from.Left) ); | |
409 | rb_ary_push( ret, INT2FIX(from.Top) ); | |
410 | rb_ary_push( ret, INT2FIX(from.Right) ); | |
411 | rb_ary_push( ret, INT2FIX(from.Bottom) ); | |
412 | return ret; | |
413 | } | |
414 | ||
415 | ||
416 | ||
417 | static VALUE rb_GetConsoleScreenBufferInfo( VALUE self, VALUE hConsoleOutput ) | |
418 | { | |
419 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
420 | ||
421 | CONSOLE_SCREEN_BUFFER_INFO out; | |
422 | ||
423 | if ( !GetConsoleScreenBufferInfo( handle, &out ) ) | |
424 | return rb_getWin32Error(); | |
425 | ||
426 | VALUE ret = rb_ary_new(); | |
427 | rb_ary_push( ret, UINT2NUM( out.dwSize.X ) ); | |
428 | rb_ary_push( ret, UINT2NUM( out.dwSize.Y ) ); | |
429 | rb_ary_push( ret, UINT2NUM( out.dwCursorPosition.X ) ); | |
430 | rb_ary_push( ret, UINT2NUM( out.dwCursorPosition.Y ) ); | |
431 | ||
432 | rb_ary_push( ret, UINT2NUM( out.wAttributes ) ); | |
433 | ||
434 | rb_ary_push( ret, INT2FIX( out.srWindow.Left ) ); | |
435 | rb_ary_push( ret, INT2FIX( out.srWindow.Top ) ); | |
436 | rb_ary_push( ret, INT2FIX( out.srWindow.Right ) ); | |
437 | rb_ary_push( ret, INT2FIX( out.srWindow.Bottom ) ); | |
438 | ||
439 | rb_ary_push( ret, UINT2NUM( out.dwMaximumWindowSize.X ) ); | |
440 | rb_ary_push( ret, UINT2NUM( out.dwMaximumWindowSize.Y ) ); | |
441 | ||
442 | ||
443 | return ret; | |
444 | } | |
445 | ||
446 | ||
447 | #define strEQ(x,y) strcmp(x,y) == 0 | |
448 | ||
449 | DWORD c_constant(char *name) | |
450 | { | |
451 | switch (*name) { | |
452 | case 'A': | |
453 | break; | |
454 | case 'B': | |
455 | if (strEQ(name, "BACKGROUND_BLUE")) | |
456 | #ifdef BACKGROUND_BLUE | |
457 | return BACKGROUND_BLUE; | |
458 | #else | |
459 | goto not_there; | |
460 | #endif | |
461 | if (strEQ(name, "BACKGROUND_GREEN")) | |
462 | #ifdef BACKGROUND_GREEN | |
463 | return BACKGROUND_GREEN; | |
464 | #else | |
465 | goto not_there; | |
466 | #endif | |
467 | if (strEQ(name, "BACKGROUND_INTENSITY")) | |
468 | #ifdef BACKGROUND_INTENSITY | |
469 | return BACKGROUND_INTENSITY; | |
470 | #else | |
471 | goto not_there; | |
472 | #endif | |
473 | if (strEQ(name, "BACKGROUND_RED")) | |
474 | #ifdef BACKGROUND_RED | |
475 | return BACKGROUND_RED; | |
476 | #else | |
477 | goto not_there; | |
478 | #endif | |
479 | break; | |
480 | case 'C': | |
481 | if (strEQ(name, "CAPSLOCK_ON")) | |
482 | #ifdef CAPSLOCK_ON | |
483 | return CAPSLOCK_ON; | |
484 | #else | |
485 | goto not_there; | |
486 | #endif | |
487 | if (strEQ(name, "CONSOLE_TEXTMODE_BUFFER")) | |
488 | #ifdef CONSOLE_TEXTMODE_BUFFER | |
489 | return CONSOLE_TEXTMODE_BUFFER; | |
490 | #else | |
491 | goto not_there; | |
492 | #endif | |
493 | if (strEQ(name, "CTRL_BREAK_EVENT")) | |
494 | #ifdef CTRL_BREAK_EVENT | |
495 | return CTRL_BREAK_EVENT; | |
496 | #else | |
497 | goto not_there; | |
498 | #endif | |
499 | if (strEQ(name, "CTRL_C_EVENT")) | |
500 | #ifdef CTRL_C_EVENT | |
501 | return CTRL_C_EVENT; | |
502 | #else | |
503 | goto not_there; | |
504 | #endif | |
505 | break; | |
506 | ||
507 | case 'D': | |
508 | break; | |
509 | case 'E': | |
510 | if (strEQ(name, "ENABLE_ECHO_INPUT")) | |
511 | #ifdef ENABLE_ECHO_INPUT | |
512 | return ENABLE_ECHO_INPUT; | |
513 | #else | |
514 | goto not_there; | |
515 | #endif | |
516 | if (strEQ(name, "ENABLE_LINE_INPUT")) | |
517 | #ifdef ENABLE_LINE_INPUT | |
518 | return ENABLE_LINE_INPUT; | |
519 | #else | |
520 | goto not_there; | |
521 | #endif | |
522 | if (strEQ(name, "ENABLE_MOUSE_INPUT")) | |
523 | #ifdef ENABLE_MOUSE_INPUT | |
524 | return ENABLE_MOUSE_INPUT; | |
525 | #else | |
526 | goto not_there; | |
527 | #endif | |
528 | if (strEQ(name, "ENABLE_PROCESSED_INPUT")) | |
529 | #ifdef ENABLE_PROCESSED_INPUT | |
530 | return ENABLE_PROCESSED_INPUT; | |
531 | #else | |
532 | goto not_there; | |
533 | #endif | |
534 | if (strEQ(name, "ENABLE_PROCESSED_OUTPUT")) | |
535 | #ifdef ENABLE_PROCESSED_OUTPUT | |
536 | return ENABLE_PROCESSED_OUTPUT; | |
537 | #else | |
538 | goto not_there; | |
539 | #endif | |
540 | if (strEQ(name, "ENABLE_WINDOW_INPUT")) | |
541 | #ifdef ENABLE_WINDOW_INPUT | |
542 | return ENABLE_WINDOW_INPUT; | |
543 | #else | |
544 | goto not_there; | |
545 | #endif | |
546 | if (strEQ(name, "ENABLE_WRAP_AT_EOL_OUTPUT")) | |
547 | #ifdef ENABLE_WRAP_AT_EOL_OUTPUT | |
548 | return ENABLE_WRAP_AT_EOL_OUTPUT; | |
549 | #else | |
550 | goto not_there; | |
551 | #endif | |
552 | if (strEQ(name, "ENHANCED_KEY")) | |
553 | #ifdef ENHANCED_KEY | |
554 | return ENHANCED_KEY; | |
555 | #else | |
556 | goto not_there; | |
557 | #endif | |
558 | break; | |
559 | case 'F': | |
560 | if (strEQ(name, "FILE_SHARE_READ")) | |
561 | #ifdef FILE_SHARE_READ | |
562 | return FILE_SHARE_READ; | |
563 | #else | |
564 | goto not_there; | |
565 | #endif | |
566 | if (strEQ(name, "FILE_SHARE_WRITE")) | |
567 | #ifdef FILE_SHARE_WRITE | |
568 | return FILE_SHARE_WRITE; | |
569 | #else | |
570 | goto not_there; | |
571 | #endif | |
572 | if (strEQ(name, "FOREGROUND_BLUE")) | |
573 | #ifdef FOREGROUND_BLUE | |
574 | return FOREGROUND_BLUE; | |
575 | #else | |
576 | goto not_there; | |
577 | #endif | |
578 | if (strEQ(name, "FOREGROUND_GREEN")) | |
579 | #ifdef FOREGROUND_GREEN | |
580 | return FOREGROUND_GREEN; | |
581 | #else | |
582 | goto not_there; | |
583 | #endif | |
584 | if (strEQ(name, "FOREGROUND_INTENSITY")) | |
585 | #ifdef FOREGROUND_INTENSITY | |
586 | return FOREGROUND_INTENSITY; | |
587 | #else | |
588 | goto not_there; | |
589 | #endif | |
590 | if (strEQ(name, "FOREGROUND_RED")) | |
591 | #ifdef FOREGROUND_RED | |
592 | return FOREGROUND_RED; | |
593 | #else | |
594 | goto not_there; | |
595 | #endif | |
596 | break; | |
597 | case 'G': | |
598 | if (strEQ(name, "GENERIC_READ")) | |
599 | #ifdef GENERIC_READ | |
600 | return GENERIC_READ; | |
601 | #else | |
602 | goto not_there; | |
603 | #endif | |
604 | if (strEQ(name, "GENERIC_WRITE")) | |
605 | #ifdef GENERIC_WRITE | |
606 | return GENERIC_WRITE; | |
607 | #else | |
608 | goto not_there; | |
609 | #endif | |
610 | break; | |
611 | case 'H': | |
612 | break; | |
613 | case 'I': | |
614 | break; | |
615 | case 'J': | |
616 | break; | |
617 | case 'K': | |
618 | if (strEQ(name, "KEY_EVENT")) | |
619 | #ifdef KEY_EVENT | |
620 | return KEY_EVENT; | |
621 | #else | |
622 | goto not_there; | |
623 | #endif | |
624 | break; | |
625 | case 'L': | |
626 | if (strEQ(name, "LEFT_ALT_PRESSED")) | |
627 | #ifdef LEFT_ALT_PRESSED | |
628 | return LEFT_ALT_PRESSED; | |
629 | #else | |
630 | goto not_there; | |
631 | #endif | |
632 | if (strEQ(name, "LEFT_CTRL_PRESSED")) | |
633 | #ifdef LEFT_CTRL_PRESSED | |
634 | return LEFT_CTRL_PRESSED; | |
635 | #else | |
636 | goto not_there; | |
637 | #endif | |
638 | break; | |
639 | case 'M': | |
640 | break; | |
641 | case 'N': | |
642 | if (strEQ(name, "NUMLOCK_ON")) | |
643 | #ifdef NUMLOCK_ON | |
644 | return NUMLOCK_ON; | |
645 | #else | |
646 | goto not_there; | |
647 | #endif | |
648 | break; | |
649 | case 'O': | |
650 | break; | |
651 | case 'P': | |
652 | break; | |
653 | case 'Q': | |
654 | break; | |
655 | case 'R': | |
656 | if (strEQ(name, "RIGHT_ALT_PRESSED")) | |
657 | #ifdef RIGHT_ALT_PRESSED | |
658 | return RIGHT_ALT_PRESSED; | |
659 | #else | |
660 | goto not_there; | |
661 | #endif | |
662 | if (strEQ(name, "RIGHT_CTRL_PRESSED")) | |
663 | #ifdef RIGHT_CTRL_PRESSED | |
664 | return RIGHT_CTRL_PRESSED; | |
665 | #else | |
666 | goto not_there; | |
667 | #endif | |
668 | break; | |
669 | case 'S': | |
670 | if (strEQ(name, "SCROLLLOCK_ON")) | |
671 | #ifdef SCROLLLOCK_ON | |
672 | return SCROLLLOCK_ON; | |
673 | #else | |
674 | goto not_there; | |
675 | #endif | |
676 | if (strEQ(name, "SHIFT_PRESSED")) | |
677 | #ifdef SHIFT_PRESSED | |
678 | return SHIFT_PRESSED; | |
679 | #else | |
680 | goto not_there; | |
681 | #endif | |
682 | if (strEQ(name, "STD_ERROR_HANDLE")) | |
683 | #ifdef STD_ERROR_HANDLE | |
684 | return STD_ERROR_HANDLE; | |
685 | #else | |
686 | goto not_there; | |
687 | #endif | |
688 | if (strEQ(name, "STD_INPUT_HANDLE")) | |
689 | #ifdef STD_INPUT_HANDLE | |
690 | return STD_INPUT_HANDLE; | |
691 | #else | |
692 | goto not_there; | |
693 | #endif | |
694 | if (strEQ(name, "STD_OUTPUT_HANDLE")) | |
695 | #ifdef STD_OUTPUT_HANDLE | |
696 | return STD_OUTPUT_HANDLE; | |
697 | #else | |
698 | goto not_there; | |
699 | #endif | |
700 | break; | |
701 | case 'T': | |
702 | break; | |
703 | case 'U': | |
704 | break; | |
705 | case 'V': | |
706 | break; | |
707 | case 'W': | |
708 | break; | |
709 | case 'X': | |
710 | break; | |
711 | case 'Y': | |
712 | break; | |
713 | case 'Z': | |
714 | break; | |
715 | } | |
716 | rb_raise(rb_eArgError, "Not such constant."); | |
717 | return 0; | |
718 | ||
719 | not_there: | |
720 | rb_raise(rb_eArgError, "Not defined."); | |
721 | return 0; | |
722 | } | |
723 | ||
724 | VALUE rb_constant( VALUE self, VALUE name ) | |
725 | { | |
726 | Check_Type( name, T_STRING ); | |
727 | return ULONG2NUM( c_constant( RSTRING(name)->ptr ) ); | |
728 | } | |
729 | ||
730 | ||
731 | void define_constants() | |
732 | { | |
733 | #define DEF_SELF_CONST(NAME) \ | |
734 | rb_define_const(rb_mConstants, #NAME, ULONG2NUM( (ULONG)NAME ) ); | |
735 | ||
736 | DEF_SELF_CONST( STD_INPUT_HANDLE ); | |
737 | DEF_SELF_CONST( STD_OUTPUT_HANDLE ); | |
738 | DEF_SELF_CONST( STD_ERROR_HANDLE ); | |
739 | DEF_SELF_CONST( INVALID_HANDLE_VALUE ); | |
740 | DEF_SELF_CONST( GENERIC_READ ); | |
741 | DEF_SELF_CONST( GENERIC_WRITE ); | |
742 | DEF_SELF_CONST( FILE_SHARE_READ ); | |
743 | DEF_SELF_CONST( FILE_SHARE_WRITE ); | |
744 | DEF_SELF_CONST( CONSOLE_TEXTMODE_BUFFER ); | |
745 | ||
746 | DEF_SELF_CONST( FOREGROUND_BLUE ); | |
747 | DEF_SELF_CONST( FOREGROUND_GREEN ); | |
748 | DEF_SELF_CONST( FOREGROUND_RED ); | |
749 | DEF_SELF_CONST( FOREGROUND_INTENSITY ); | |
750 | DEF_SELF_CONST( BACKGROUND_BLUE ); | |
751 | DEF_SELF_CONST( BACKGROUND_GREEN ); | |
752 | DEF_SELF_CONST( BACKGROUND_RED ); | |
753 | DEF_SELF_CONST( BACKGROUND_INTENSITY ); | |
754 | ||
755 | DEF_SELF_CONST( ENABLE_PROCESSED_INPUT ); | |
756 | DEF_SELF_CONST( ENABLE_LINE_INPUT ); | |
757 | DEF_SELF_CONST( ENABLE_ECHO_INPUT ); | |
758 | DEF_SELF_CONST( ENABLE_WINDOW_INPUT ); | |
759 | DEF_SELF_CONST( ENABLE_MOUSE_INPUT ); | |
760 | DEF_SELF_CONST( ENABLE_PROCESSED_OUTPUT ); | |
761 | DEF_SELF_CONST( ENABLE_WRAP_AT_EOL_OUTPUT ); | |
762 | ||
763 | DEF_SELF_CONST( KEY_EVENT ); | |
764 | DEF_SELF_CONST( MOUSE_EVENT ); | |
765 | DEF_SELF_CONST( WINDOW_BUFFER_SIZE_EVENT ); | |
766 | DEF_SELF_CONST( MENU_EVENT ); | |
767 | DEF_SELF_CONST( FOCUS_EVENT ); | |
768 | ||
769 | DEF_SELF_CONST( CAPSLOCK_ON ); | |
770 | DEF_SELF_CONST( ENHANCED_KEY ); | |
771 | DEF_SELF_CONST( NUMLOCK_ON ); | |
772 | DEF_SELF_CONST( SHIFT_PRESSED ); | |
773 | DEF_SELF_CONST( LEFT_CTRL_PRESSED ); | |
774 | DEF_SELF_CONST( RIGHT_CTRL_PRESSED ); | |
775 | DEF_SELF_CONST( LEFT_ALT_PRESSED ); | |
776 | DEF_SELF_CONST( RIGHT_ALT_PRESSED ); | |
777 | DEF_SELF_CONST( SCROLLLOCK_ON ); | |
778 | ||
779 | DEF_SELF_CONST( MOUSE_WHEELED ); | |
780 | DEF_SELF_CONST( DOUBLE_CLICK ); | |
781 | DEF_SELF_CONST( MOUSE_MOVED ); | |
782 | ||
783 | DEF_SELF_CONST( FROM_LEFT_1ST_BUTTON_PRESSED ); | |
784 | DEF_SELF_CONST( FROM_LEFT_2ND_BUTTON_PRESSED ); | |
785 | DEF_SELF_CONST( FROM_LEFT_3RD_BUTTON_PRESSED ); | |
786 | DEF_SELF_CONST( FROM_LEFT_4TH_BUTTON_PRESSED ); | |
787 | DEF_SELF_CONST( RIGHTMOST_BUTTON_PRESSED ); | |
788 | ||
789 | DEF_SELF_CONST( CTRL_C_EVENT ); | |
790 | DEF_SELF_CONST( CTRL_BREAK_EVENT ); | |
791 | DEF_SELF_CONST( CTRL_CLOSE_EVENT ); | |
792 | DEF_SELF_CONST( CTRL_LOGOFF_EVENT ); | |
793 | DEF_SELF_CONST( CTRL_SHUTDOWN_EVENT ); | |
794 | } | |
795 | ||
796 | ||
797 | VALUE | |
798 | rb_FillConsoleOutputAttribute( VALUE self, VALUE hConsoleOutput, | |
799 | VALUE wAttribute, VALUE nLength, | |
800 | VALUE col, VALUE row ) | |
801 | { | |
802 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
803 | ||
804 | COORD dwWriteCoord; | |
805 | dwWriteCoord.X = NUM2UINT(col); | |
806 | dwWriteCoord.Y = NUM2UINT(row); | |
807 | DWORD numChars; | |
808 | if (FillConsoleOutputAttribute( handle, NUM2UINT(wAttribute), | |
809 | NUM2ULONG(nLength), dwWriteCoord, | |
810 | &numChars )) | |
811 | return ULONG2NUM(numChars); | |
812 | return rb_getWin32Error(); | |
813 | } | |
814 | ||
815 | VALUE | |
816 | rb_SetConsoleScreenBufferSize( VALUE self, VALUE hConsoleOutput, | |
817 | VALUE x, VALUE y ) | |
818 | { | |
819 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
820 | COORD size; | |
821 | size.X=NUM2UINT(x); | |
822 | size.Y=NUM2UINT(y); | |
823 | if (SetConsoleScreenBufferSize(handle, size)) | |
824 | return NUM2UINT(1); | |
825 | return rb_getWin32Error(); | |
826 | } | |
827 | ||
828 | VALUE | |
829 | rb_SetConsoleTitle( VALUE self, VALUE title ) | |
830 | { | |
831 | Check_Type( title, T_STRING ); | |
832 | if (SetConsoleTitle(RSTRING( title )->ptr)) | |
833 | return NUM2UINT(1); | |
834 | return rb_getWin32Error(); | |
835 | } | |
836 | ||
837 | VALUE | |
838 | rb_SetStdHandle( VALUE self, VALUE fd, VALUE hConsoleOutput ) | |
839 | { | |
840 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
841 | if (SetStdHandle(NUM2UINT(fd), handle)) | |
842 | return NUM2UINT(1); | |
843 | return rb_getWin32Error(); | |
844 | } | |
845 | ||
846 | VALUE | |
847 | rb_SetConsoleWindowInfo( VALUE self, VALUE hConsoleOutput, VALUE bAbsolute, | |
848 | VALUE left, VALUE top, VALUE right, VALUE bottom ) | |
849 | { | |
850 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
851 | ||
852 | SMALL_RECT rect; | |
853 | rect.Left = NUM2INT( left ); | |
854 | rect.Top = NUM2INT( top ); | |
855 | rect.Right = NUM2INT( right ); | |
856 | rect.Bottom = NUM2INT( bottom ); | |
857 | if (SetConsoleWindowInfo( handle, NUM2INT( bAbsolute ), &rect )) | |
858 | return UINT2NUM(1); | |
859 | return rb_getWin32Error(); | |
860 | } | |
861 | ||
862 | ||
863 | ||
864 | VALUE | |
865 | rb_SetConsoleCursorPosition( VALUE self, VALUE hConsoleOutput, | |
866 | VALUE col, VALUE row ) | |
867 | { | |
868 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
869 | ||
870 | COORD dwWriteCoord; | |
871 | dwWriteCoord.X = NUM2UINT(col); | |
872 | dwWriteCoord.Y = NUM2UINT(row); | |
873 | // Cannot call rb_getWin32Error as this function fails when | |
874 | // setting cursor to last column/row. | |
875 | if ( !SetConsoleCursorPosition( handle, dwWriteCoord ) ) | |
876 | return Qnil; | |
877 | return INT2FIX(1); | |
878 | } | |
879 | ||
880 | VALUE | |
881 | rb_SetConsoleCursorInfo( VALUE self, VALUE hConsoleOutput, | |
882 | VALUE size, VALUE visib ) | |
883 | { | |
884 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
885 | CONSOLE_CURSOR_INFO c; | |
886 | c.dwSize = NUM2UINT(size); | |
887 | c.bVisible = NUM2UINT(visib); | |
888 | if ( !SetConsoleCursorInfo( handle, &c ) ) | |
889 | return rb_getWin32Error(); | |
890 | return INT2FIX(1); | |
891 | } | |
892 | ||
893 | ||
894 | ||
895 | VALUE | |
896 | rb_SetConsoleActiveScreenBuffer( VALUE self, VALUE hConsoleOutput ) | |
897 | { | |
898 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
899 | ||
900 | if ( !SetConsoleActiveScreenBuffer( handle ) ) | |
901 | return rb_getWin32Error(); | |
902 | return INT2FIX(1); | |
903 | } | |
904 | ||
905 | VALUE | |
906 | rb_SetConsoleTextAttribute( VALUE self, VALUE hConsoleOutput, | |
907 | VALUE wAttributes ) | |
908 | { | |
909 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
910 | ||
911 | if ( !SetConsoleTextAttribute( handle, NUM2UINT(wAttributes) ) ) | |
912 | return Qnil; // no getWin32Error to allow piping/redirecting | |
913 | return INT2FIX(1); | |
914 | } | |
915 | ||
916 | ||
917 | ||
918 | VALUE | |
919 | rb_ScrollConsoleScreenBuffer( VALUE self, VALUE hConsoleOutput, VALUE left1, | |
920 | VALUE top1, VALUE right1, VALUE bottom1, | |
921 | VALUE col, VALUE row, VALUE cChar, VALUE attr, | |
922 | VALUE left2, VALUE top2, VALUE right2, | |
923 | VALUE bottom2) | |
924 | { | |
925 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
926 | ||
927 | SMALL_RECT scroll, clip; | |
928 | scroll.Left = NUM2INT( left1 ); | |
929 | scroll.Right = NUM2INT( right1 ); | |
930 | scroll.Top = NUM2INT( top1 ); | |
931 | scroll.Bottom = NUM2INT( bottom1 ); | |
932 | clip.Left = NUM2INT( left2 ); | |
933 | clip.Right = NUM2INT( right2 ); | |
934 | clip.Top = NUM2INT( top2 ); | |
935 | clip.Bottom = NUM2INT( bottom2 ); | |
936 | CHAR_INFO fill; | |
937 | #ifdef UNICODE | |
938 | fill.Char.UnicodeChar = NUM2CHR( cChar ); | |
939 | #else | |
940 | fill.Char.AsciiChar = NUM2CHR( cChar ); | |
941 | #endif | |
942 | fill.Attributes = NUM2INT(attr); | |
943 | COORD origin; | |
944 | origin.X = NUM2UINT( col ); | |
945 | origin.Y = NUM2UINT( row ); | |
946 | ||
947 | if ( ScrollConsoleScreenBuffer( handle, &scroll, &clip, origin, | |
948 | &fill ) ) | |
949 | return INT2FIX(1); | |
950 | return rb_getWin32Error(); | |
951 | } | |
952 | ||
953 | ||
954 | VALUE | |
955 | rb_FillConsoleOutputCharacter( VALUE self, VALUE hConsoleOutput, | |
956 | VALUE cCharacter, VALUE nLength, | |
957 | VALUE col, VALUE row ) | |
958 | { | |
959 | HANDLE handle = ULongToPtr( NUM2ULONG( hConsoleOutput ) ); | |
960 | ||
961 | COORD dwWriteCoord; | |
962 | dwWriteCoord.X = NUM2UINT(col); | |
963 | dwWriteCoord.Y = NUM2UINT(row); | |
964 | DWORD numChars; | |
965 | if (FillConsoleOutputCharacter( handle, NUM2CHR(cCharacter), | |
966 | NUM2ULONG(nLength), dwWriteCoord, | |
967 | &numChars )) | |
968 | return ULONG2NUM(numChars); | |
969 | return rb_getWin32Error(); | |
970 | } | |
971 | ||
972 | ||
973 | VALUE | |
974 | rb_WriteConsoleInput(int argc, VALUE *argv, VALUE self) | |
975 | { | |
976 | if (argc < 3) | |
977 | rb_raise(rb_eArgError, "Wrong number of arguments."); | |
978 | ||
979 | HANDLE handle = ULongToPtr( NUM2ULONG( argv[0] ) ); | |
980 | WORD type = NUM2INT( argv[1] ); | |
981 | DWORD written; | |
982 | INPUT_RECORD event; | |
983 | event.EventType = type; | |
984 | switch(event.EventType) { | |
985 | case KEY_EVENT: | |
986 | { | |
987 | KEY_EVENT_RECORD* kevent=(KEY_EVENT_RECORD *)&(event.Event); | |
988 | kevent->bKeyDown=(BOOL)NUM2UINT( argv[2] ); | |
989 | kevent->wRepeatCount=NUM2UINT( argv[3] ); | |
990 | kevent->wVirtualKeyCode=NUM2UINT( argv[4] ); | |
991 | kevent->wVirtualScanCode=NUM2UINT( argv[5] ); | |
992 | #ifdef UNICODE | |
993 | if (argc < 7) | |
994 | rb_raise(rb_eArgError, "Wrong number of arguments."); | |
995 | kevent->uChar.UnicodeChar=NUM2UINT( argv[6] ); | |
996 | #else | |
997 | if (argc < 8) | |
998 | rb_raise(rb_eArgError, "Wrong number of arguments."); | |
999 | kevent->uChar.AsciiChar=NUM2UINT( argv[7] ); | |
1000 | #endif | |
1001 | break; | |
1002 | } | |
1003 | case MOUSE_EVENT: | |
1004 | { | |
1005 | if (argc < 7) | |
1006 | rb_raise(rb_eArgError, "Wrong number of arguments."); | |
1007 | ||
1008 | MOUSE_EVENT_RECORD* mevent=(MOUSE_EVENT_RECORD *)&(event.Event); | |
1009 | mevent->dwMousePosition.X=NUM2UINT( argv[2] ); | |
1010 | mevent->dwMousePosition.Y=NUM2UINT( argv[3] ); | |
1011 | mevent->dwButtonState=NUM2UINT( argv[4] ); | |
1012 | mevent->dwControlKeyState=NUM2UINT( argv[5] ); | |
1013 | mevent->dwEventFlags=NUM2UINT( argv[6] ); | |
1014 | break; | |
1015 | } | |
1016 | case WINDOW_BUFFER_SIZE_EVENT: | |
1017 | { | |
1018 | if (argc < 4) | |
1019 | rb_raise(rb_eArgError, "Wrong number of arguments."); | |
1020 | WINDOW_BUFFER_SIZE_RECORD* mevent= | |
1021 | (WINDOW_BUFFER_SIZE_RECORD *)&(event.Event); | |
1022 | mevent->dwSize.X = NUM2UINT( argv[2] ); | |
1023 | mevent->dwSize.Y = NUM2UINT( argv[3] ); | |
1024 | } | |
1025 | break; | |
1026 | case MENU_EVENT: | |
1027 | { | |
1028 | if (argc < 3) | |
1029 | rb_raise(rb_eArgError, "Wrong number of arguments."); | |
1030 | MENU_EVENT_RECORD* mevent= (MENU_EVENT_RECORD *)&(event.Event); | |
1031 | mevent->dwCommandId = argv[2]; | |
1032 | } | |
1033 | break; | |
1034 | case FOCUS_EVENT: | |
1035 | { | |
1036 | if (argc < 3) | |
1037 | rb_raise(rb_eArgError, "Wrong number of arguments."); | |
1038 | FOCUS_EVENT_RECORD* mevent= (FOCUS_EVENT_RECORD *)&(event.Event); | |
1039 | mevent->bSetFocus = NUM2UINT( argv[2] ); | |
1040 | } | |
1041 | default: | |
1042 | rb_raise( rb_eArgError, "Unknown type of event."); | |
1043 | break; | |
1044 | } | |
1045 | if (WriteConsoleInput(handle,&event,1,&written)) | |
1046 | return INT2FIX(1); | |
1047 | return rb_getWin32Error(); | |
1048 | } | |
1049 | ||
1050 | VALUE | |
1051 | rb_WriteConsoleOutput(VALUE self, VALUE h, VALUE buffer, | |
1052 | VALUE srcwid, VALUE srcht, VALUE startx, | |
1053 | VALUE starty, VALUE l, VALUE t, VALUE r, VALUE b) | |
1054 | { | |
1055 | COORD coords; | |
1056 | COORD size; | |
1057 | SMALL_RECT to; | |
1058 | ||
1059 | HANDLE handle = ULongToPtr( NUM2ULONG( h ) ); | |
1060 | Check_Type( buffer, T_STRING ); | |
1061 | size.X=NUM2UINT( srcwid ); | |
1062 | size.Y=NUM2UINT( srcht ); | |
1063 | coords.X=NUM2INT( startx ); | |
1064 | coords.Y=NUM2INT( starty ); | |
1065 | to.Left = NUM2INT( l ); | |
1066 | to.Top = NUM2INT( t ); | |
1067 | to.Right = NUM2INT( r ); | |
1068 | to.Bottom = NUM2INT( b ); | |
1069 | if (WriteConsoleOutput(handle,(CHAR_INFO *)RSTRING(buffer)->ptr, | |
1070 | size,coords,&to)) { | |
1071 | VALUE ret = rb_ary_new(); | |
1072 | rb_ary_push( ret, INT2FIX( to.Left ) ); | |
1073 | rb_ary_push( ret, INT2FIX( to.Top ) ); | |
1074 | rb_ary_push( ret, INT2FIX( to.Right ) ); | |
1075 | rb_ary_push( ret, INT2FIX( to.Bottom ) ); | |
1076 | return ret; | |
1077 | } | |
1078 | return rb_getWin32Error(); | |
1079 | } | |
1080 | ||
1081 | ||
1082 | VALUE | |
1083 | rb_WriteConsoleOutputAttribute(VALUE self, VALUE h, VALUE s, | |
1084 | VALUE x, VALUE y) | |
1085 | { | |
1086 | ||
1087 | HANDLE handle = ULongToPtr( NUM2ULONG( h ) ); | |
1088 | Check_Type( s, T_STRING ); | |
1089 | ||
1090 | unsigned short buffer[80*999*sizeof(unsigned short)]; | |
1091 | DWORD written; | |
1092 | DWORD towrite = RSTRING(s)->len; | |
1093 | for(unsigned i=0; i<towrite; i++) { | |
1094 | buffer[i] = (unsigned short)(RSTRING(s)->ptr[i]); | |
1095 | } | |
1096 | COORD coords; | |
1097 | coords.X=NUM2INT( x ); | |
1098 | coords.Y=NUM2INT( y ); | |
1099 | if (WriteConsoleOutputAttribute(handle,(const unsigned short *)&buffer, | |
1100 | towrite,coords,&written)) { | |
1101 | return UINT2NUM( written ); | |
1102 | } | |
1103 | return rb_getWin32Error(); | |
1104 | } | |
1105 | ||
1106 | ||
1107 | VALUE | |
1108 | rb_WriteConsoleOutputCharacter(VALUE self, VALUE h, VALUE s, | |
1109 | VALUE x, VALUE y) | |
1110 | { | |
1111 | ||
1112 | HANDLE handle = ULongToPtr( NUM2ULONG( h ) ); | |
1113 | Check_Type( s, T_STRING ); | |
1114 | ||
1115 | DWORD written; | |
1116 | COORD coords; | |
1117 | coords.X=NUM2INT( x ); | |
1118 | coords.Y=NUM2INT( y ); | |
1119 | if (WriteConsoleOutputCharacter(handle,(LPCTSTR)RSTRING(s)->ptr, | |
1120 | RSTRING(s)->len,coords,&written)) { | |
1121 | return UINT2NUM( written ); | |
1122 | } | |
1123 | return rb_getWin32Error(); | |
1124 | } | |
1125 | ||
1126 | ||
1127 | CONSOLE_EXPORT void | |
1128 | Init_Console(void) | |
1129 | { | |
1130 | rb_mWin32 = rb_define_module("Win32"); | |
1131 | rb_define_const(rb_mKernel, "Win32", rb_mWin32); | |
1132 | ||
1133 | rb_mConsole = rb_define_class_under(rb_mWin32, "Console", rb_cObject); | |
1134 | ||
1135 | // Handle Constants | |
1136 | rb_mConstants = rb_define_module_under(rb_mConsole,"Constants"); | |
1137 | define_constants(); | |
1138 | ||
1139 | // Handle API | |
1140 | rb_mAPI = rb_define_class_under(rb_mConsole, "API", rb_cObject); | |
1141 | ||
1142 | RB_DEF_API_METHOD(constant, 1); //OK | |
1143 | ||
1144 | RB_DEF_API_METHOD(AllocConsole, 0); | |
1145 | ||
1146 | RB_DEF_API_METHOD(CreateConsoleScreenBuffer, 3); //OK | |
1147 | ||
1148 | RB_DEF_API_METHOD(FillConsoleOutputAttribute, 5); //OK | |
1149 | RB_DEF_API_METHOD(FillConsoleOutputCharacter, 5); //OK | |
1150 | // RB_DEF_API_METHOD(FillConsoleInputBuffer, 1); // Does not exist anymore | |
1151 | ||
1152 | RB_DEF_API_METHOD(FreeConsole, 0); | |
1153 | ||
1154 | RB_DEF_API_METHOD(GenerateConsoleCtrlEvent, 2); | |
1155 | ||
1156 | RB_DEF_API_METHOD(GetConsoleCP, 0); //OK | |
1157 | RB_DEF_API_METHOD(GetConsoleCursorInfo, 1); //OK | |
1158 | RB_DEF_API_METHOD(GetConsoleMode, 1); | |
1159 | RB_DEF_API_METHOD(GetConsoleOutputCP, 0); | |
1160 | RB_DEF_API_METHOD(GetConsoleScreenBufferInfo, 1); //OK | |
1161 | RB_DEF_API_METHOD(GetConsoleTitle, 0); | |
1162 | RB_DEF_API_METHOD(GetConsoleWindow, 0); | |
1163 | RB_DEF_API_METHOD(GetLargestConsoleWindowSize, 1); | |
1164 | RB_DEF_API_METHOD(GetNumberOfConsoleInputEvents, 1); | |
1165 | RB_DEF_API_METHOD(GetNumberOfConsoleMouseButtons, 0); | |
1166 | ||
1167 | RB_DEF_API_METHOD(GetStdHandle, 1); //OK | |
1168 | ||
1169 | RB_DEF_API_METHOD(PeekConsoleInput, 1); //OK | |
1170 | RB_DEF_API_METHOD(ReadConsole, 3); //OK | |
1171 | RB_DEF_API_METHOD(ReadConsoleInput, 1); //OK | |
1172 | ||
1173 | RB_DEF_API_METHOD(ReadConsoleOutput, 10); // OK | |
1174 | RB_DEF_API_METHOD(ReadConsoleOutputAttribute, 4); // OK | |
1175 | RB_DEF_API_METHOD(ReadConsoleOutputCharacter, 5); // OK | |
1176 | ||
1177 | ||
1178 | RB_DEF_API_METHOD(ScrollConsoleScreenBuffer, 13); //OK | |
1179 | ||
1180 | RB_DEF_API_METHOD(SetConsoleActiveScreenBuffer, 1); | |
1181 | RB_DEF_API_METHOD(SetConsoleCP, 1); | |
1182 | RB_DEF_API_METHOD(SetConsoleCursorPosition, 3); | |
1183 | RB_DEF_API_METHOD(SetConsoleCursorInfo, 3); | |
1184 | RB_DEF_API_METHOD(SetConsoleMode, 2); //OK | |
1185 | RB_DEF_API_METHOD(SetConsoleOutputCP, 1); | |
1186 | RB_DEF_API_METHOD(SetConsoleScreenBufferSize, 3); | |
1187 | RB_DEF_API_METHOD(SetConsoleTextAttribute, 2); | |
1188 | RB_DEF_API_METHOD(SetConsoleTitle, 1); //OK | |
1189 | RB_DEF_API_METHOD(SetConsoleWindowInfo, 6); | |
1190 | ||
1191 | RB_DEF_API_METHOD(SetStdHandle, 2); | |
1192 | ||
1193 | RB_DEF_API_METHOD(WriteConsole, 2); | |
1194 | ||
1195 | RB_DEF_API_METHOD(WriteConsoleInput, -1); | |
1196 | RB_DEF_API_METHOD(WriteConsoleOutput, 10); | |
1197 | RB_DEF_API_METHOD(WriteConsoleOutputAttribute, 4); | |
1198 | RB_DEF_API_METHOD(WriteConsoleOutputCharacter, 4); | |
1199 | ||
1200 | } | |
1201 | ||
1202 | } |
0 | # | |
1 | # = NAME | |
2 | # | |
3 | # Win32::Console - Win32 Console and Character Mode Functions | |
4 | # | |
5 | # | |
6 | # = DESCRIPTION | |
7 | # | |
8 | # This module implements the Win32 console and character mode | |
9 | # functions. They give you full control on the console input and output, | |
10 | # including: support of off-screen console buffers (eg. multiple screen | |
11 | # pages) | |
12 | # | |
13 | # - reading and writing of characters, attributes and whole portions of | |
14 | # the screen | |
15 | # | |
16 | # - complete processing of keyboard and mouse events | |
17 | # | |
18 | # - some very funny additional features :) | |
19 | # | |
20 | # | |
21 | # Those functions should also make possible a port of the Unix's curses | |
22 | # library; if there is anyone interested (and/or willing to contribute) | |
23 | # to this project, e-mail me. Thank you. | |
24 | # | |
25 | # | |
26 | # = REFERENCE | |
27 | # | |
28 | # | |
29 | # == Methods | |
30 | # | |
31 | # - Alloc | |
32 | # | |
33 | # Allocates a new console for the process. Returns C<nil> on errors, a | |
34 | # nonzero value on success. A process cannot be associated with more | |
35 | # than one console, so this method will fail if there is already an | |
36 | # allocated console. Use Free to detach the process from the console, | |
37 | # and then call Alloc to create a new console. See also: C<Free> | |
38 | # | |
39 | # Example: | |
40 | # | |
41 | # Win32::Console::Alloc() | |
42 | # | |
43 | # - Attr [attr] | |
44 | # | |
45 | # Gets or sets the current console attribute. This attribute is used by | |
46 | # the Write method. | |
47 | # | |
48 | # Example: | |
49 | # | |
50 | # attr = console.Attr() | |
51 | # console.Attr(FG_YELLOW | BG_BLUE) | |
52 | # | |
53 | # - Close | |
54 | # | |
55 | # Closes a shortcut object. Note that it is not "strictly" required to | |
56 | # close the objects you created, since the Win32::Shortcut objects are | |
57 | # automatically closed when the program ends (or when you elsehow | |
58 | # destroy such an object). | |
59 | # | |
60 | # Example: | |
61 | # | |
62 | # link.Close() | |
63 | # | |
64 | # - Cls [attr] | |
65 | # | |
66 | # Clear the console, with the specified I<attr> if given, or using | |
67 | # ATTR_NORMAL otherwise. | |
68 | # | |
69 | # Example: | |
70 | # | |
71 | # console.Cls() | |
72 | # console.Cls(FG_WHITE | BG_GREEN) | |
73 | # | |
74 | # - Cursor [x, y, size, visible] | |
75 | # | |
76 | # Gets or sets cursor position and appearance. Returns C<nil> on | |
77 | # errors, or a 4-element list containing: I<x>, I<y>, I<size>, | |
78 | # I<visible>. I<x> and I<y> are the current cursor position; ... | |
79 | # | |
80 | # Example: | |
81 | # | |
82 | # x, y, size, visible = console.Cursor() | |
83 | # | |
84 | # # Get position only | |
85 | # x, y = console.Cursor() | |
86 | # | |
87 | # console.Cursor(40, 13, 50, 1) | |
88 | # | |
89 | # # Set position only | |
90 | # console.Cursor(40, 13) | |
91 | # | |
92 | # # Set size and visibility without affecting position | |
93 | # console.Cursor(-1, -1, 50, 1) | |
94 | # | |
95 | # - Display | |
96 | # | |
97 | # Displays the specified console on the screen. Returns C<nil> on errors, | |
98 | # a nonzero value on success. | |
99 | # | |
100 | # Example: | |
101 | # | |
102 | # console.Display() | |
103 | # | |
104 | # - FillAttr [attribute, number, col, row] | |
105 | # | |
106 | # Fills the specified number of consecutive attributes, beginning at | |
107 | # I<col>, I<row>, with the value specified in I<attribute>. Returns the | |
108 | # number of attributes filled, or C<nil> on errors. See also: | |
109 | # C<FillChar>. | |
110 | # | |
111 | # Example: | |
112 | # | |
113 | # console.FillAttr(FG_BLACK | BG_BLACK, 80*25, 0, 0) | |
114 | # | |
115 | # - FillChar char, number, col, row | |
116 | # | |
117 | # Fills the specified number of consecutive characters, beginning at | |
118 | # I<col>, I<row>, with the character specified in I<char>. Returns the | |
119 | # number of characters filled, or C<nil> on errors. See also: | |
120 | # C<FillAttr>. | |
121 | # | |
122 | # Example: | |
123 | # | |
124 | # console.FillChar("X", 80*25, 0, 0) | |
125 | # | |
126 | # - Flush | |
127 | # | |
128 | # Flushes the console input buffer. All the events in the buffer are | |
129 | # discarded. Returns C<nil> on errors, a nonzero value on success. | |
130 | # | |
131 | # Example: | |
132 | # | |
133 | # console.Flush() | |
134 | # | |
135 | # - Free | |
136 | # | |
137 | # Detaches the process from the console. Returns C<nil> on errors, a | |
138 | # nonzero value on success. See also: C<Alloc>. | |
139 | # | |
140 | # Example: | |
141 | # | |
142 | # Win32::Console::Free() | |
143 | # | |
144 | # - GenerateCtrlEvent [type, processgroup] | |
145 | # | |
146 | # Sends a break signal of the specified I<type> to the specified | |
147 | # I<processgroup>. I<type> can be one of the following constants: | |
148 | # | |
149 | # CTRL_BREAK_EVENT | |
150 | # CTRL_C_EVENT | |
151 | # | |
152 | # they signal, respectively, the pressing of Control + Break and of | |
153 | # Control + C; if not specified, it defaults to CTRL_C_EVENT. | |
154 | # I<processgroup> is the pid of a process sharing the same console. If | |
155 | # omitted, it defaults to 0 (the current process), which is also the | |
156 | # only meaningful value that you can pass to this function. Returns | |
157 | # C<nil> on errors, a nonzero value on success. | |
158 | # | |
159 | # Example: | |
160 | # | |
161 | # # break this script now | |
162 | # Win32::Console::GenerateCtrlEvent() | |
163 | # | |
164 | # - GetEvents | |
165 | # | |
166 | # Returns the number of unread input events in the console's input | |
167 | # buffer, or C<nil> on errors. See also: C<Input>, C<InputChar>, | |
168 | # C<PeekInput>, C<WriteInput>. | |
169 | # | |
170 | # Example: | |
171 | # | |
172 | # events = console.GetEvents() | |
173 | # | |
174 | # - Info | |
175 | # | |
176 | # Returns an array of informations about the console (or C<nil> on | |
177 | # errors), which contains: | |
178 | # | |
179 | # * columns (X size) of the console buffer. | |
180 | # | |
181 | # * rows (Y size) of the console buffer. | |
182 | # | |
183 | # * current column (X position) of the cursor. | |
184 | # | |
185 | # * current row (Y position) of the cursor. | |
186 | # | |
187 | # * current attribute used for C<Write>. | |
188 | # | |
189 | # * left column (X of the starting point) of the current console window. | |
190 | # | |
191 | # * top row (Y of the starting point) of the current console window. | |
192 | # | |
193 | # * right column (X of the final point) of the current console window. | |
194 | # | |
195 | # * bottom row (Y of the final point) of the current console window. | |
196 | # | |
197 | # * maximum number of columns for the console window, given the current | |
198 | # buffer size, font and the screen size. | |
199 | # | |
200 | # * maximum number of rows for the console window, given the current | |
201 | # buffer size, font and the screen size. | |
202 | # | |
203 | # | |
204 | # See also: <b>Attr</b>, <b>Cursor</b>, <b>Size</b>, <b>Window</b>, <b>MaxWindow</b>. | |
205 | # | |
206 | # Example: | |
207 | # | |
208 | # info = console.Info() | |
209 | # puts "Cursor at #{info[3]}, #{info[4]}." | |
210 | # | |
211 | # - Input | |
212 | # | |
213 | # Reads an event from the input buffer. Returns an array of values, which | |
214 | # depending on the event's nature are: | |
215 | # | |
216 | # - keyboard event | |
217 | # | |
218 | # The array will contain: | |
219 | # | |
220 | # * event type: 1 for keyboard | |
221 | # | |
222 | # * key down: TRUE if the key is being pressed, FALSE if the key is being released | |
223 | # | |
224 | # * repeat count: the number of times the key is being held down | |
225 | # | |
226 | # * virtual keycode: the virtual key code of the key | |
227 | # | |
228 | # * virtual scancode: the virtual scan code of the key | |
229 | # | |
230 | # * char: the ASCII code of the character (if the key is a character key, 0 otherwise) | |
231 | # | |
232 | # * control key state: the state of the control keys (SHIFTs, CTRLs, ALTs, etc.) | |
233 | # | |
234 | # | |
235 | # - mouse event | |
236 | # | |
237 | # The array will contain: | |
238 | # | |
239 | # * event type: 2 for mouse | |
240 | # | |
241 | # * mouse pos. X: X coordinate (column) of the mouse location | |
242 | # | |
243 | # * mouse pos. Y: Y coordinate (row) of the mouse location | |
244 | # | |
245 | # * button state: the mouse button(s) which are pressed | |
246 | # | |
247 | # * control key state: the state of the control keys (SHIFTs, CTRLs, ALTs, etc.) | |
248 | # | |
249 | # * event flags: the type of the mouse event | |
250 | # | |
251 | # | |
252 | # This method will return <b>nil</b> on errors. Note that the events | |
253 | # returned are depending on the input <b>Mode</b> of the console; for example, | |
254 | # mouse events are not intercepted unless ENABLE_MOUSE_INPUT is | |
255 | # specified. See also: <b>GetEvents</b>, <b>InputChar</b>, <b>Mode</b>, | |
256 | # <b>PeekInput</b>, <b>WriteInput</b>. | |
257 | # | |
258 | # Example: | |
259 | # | |
260 | # event = console.Input() | |
261 | # | |
262 | # - InputChar number | |
263 | # | |
264 | # Reads and returns I<number> characters from the console input buffer, | |
265 | # or <b>nil</b> on errors. See also: <b>Input</b>, <b>Mode</b>. | |
266 | # | |
267 | # Example: | |
268 | # | |
269 | # key = console.InputChar(1) | |
270 | # | |
271 | # - InputCP [codepage] | |
272 | # | |
273 | # Gets or sets the input code page used by the console. Note that this | |
274 | # doesn't apply to a console object, but to the standard input | |
275 | # console. This attribute is used by the Write method. See also: | |
276 | # <b>OutputCP</b>. | |
277 | # | |
278 | # Example: | |
279 | # | |
280 | # codepage = Win32::Console::InputCP() | |
281 | # Win32::Console::InputCP(437) | |
282 | # | |
283 | # - MaxWindow | |
284 | # | |
285 | # Returns the size of the largest possible console window, based on the | |
286 | # current font and the size of the display. The result is <b>nil</b> on | |
287 | # errors, otherwise a 2-element list containing col, row. | |
288 | # | |
289 | # Example: | |
290 | # | |
291 | # maxCol, maxRow = console.MaxWindow() | |
292 | # | |
293 | # - Mode [flags] | |
294 | # | |
295 | # Gets or sets the input or output mode of a console. I<flags> can be a | |
296 | # combination of the following constants: | |
297 | # | |
298 | # ENABLE_LINE_INPUT | |
299 | # ENABLE_ECHO_INPUT | |
300 | # ENABLE_PROCESSED_INPUT | |
301 | # ENABLE_WINDOW_INPUT | |
302 | # ENABLE_MOUSE_INPUT | |
303 | # ENABLE_PROCESSED_OUTPUT | |
304 | # ENABLE_WRAP_AT_EOL_OUTPUT | |
305 | # | |
306 | # For more informations on the meaning of those flags, please refer to | |
307 | # the L<"Microsoft's Documentation">. | |
308 | # | |
309 | # Example: | |
310 | # | |
311 | # mode = console.Mode() | |
312 | # console.Mode(ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT) | |
313 | # | |
314 | # - MouseButtons | |
315 | # | |
316 | # Returns the number of the buttons on your mouse, or <b>nil</b> on errors. | |
317 | # | |
318 | # Example: | |
319 | # | |
320 | # puts "Your mouse has #{Win32::Console::MouseButtons()} buttons." | |
321 | # | |
322 | # - Win32::Console.new standard_handle | |
323 | # | |
324 | # - Win32::Console.new [accessmode, sharemode] | |
325 | # | |
326 | # Creates a new console object. The first form creates a handle to a | |
327 | # standard channel, I<standard_handle> can be one of the following: | |
328 | # | |
329 | # STD_OUTPUT_HANDLE | |
330 | # STD_ERROR_HANDLE | |
331 | # STD_INPUT_HANDLE | |
332 | # | |
333 | # The second form, instead, creates a console screen buffer in memory, | |
334 | # which you can access for reading and writing as a normal console, and | |
335 | # then redirect on the standard output (the screen) with <b>Display</b>. In | |
336 | # this case, you can specify one or both of the following values for | |
337 | # I<accessmode>: | |
338 | # | |
339 | # GENERIC_READ | |
340 | # GENERIC_WRITE | |
341 | # | |
342 | # which are the permissions you will have on the created buffer, and one | |
343 | # or both of the following values for I<sharemode>: | |
344 | # | |
345 | # FILE_SHARE_READ | |
346 | # FILE_SHARE_WRITE | |
347 | # | |
348 | # which affect the way the console can be shared. If you don't specify | |
349 | # any of those parameters, all 4 flags will be used. | |
350 | # | |
351 | # Example: | |
352 | # | |
353 | # stdout = Win32::Console.new(STD_OUTPUT_HANDLE) | |
354 | # stderr = Win32::Console.new(STD_ERROR_HANDLE) | |
355 | # stdin = Win32::Console.new(STD_INPUT_HANDLE) | |
356 | # | |
357 | # buffer = Win32::Console.new() | |
358 | # buffer = Win32::Console.new(GENERIC_READ | GENERIC_WRITE) | |
359 | # | |
360 | # - OutputCP [codepage] | |
361 | # | |
362 | # Gets or sets the output code page used by the console. Note that this | |
363 | # doesn't apply to a console object, but to the standard output console. | |
364 | # See also: <b>InputCP</b>. | |
365 | # | |
366 | # Example: | |
367 | # | |
368 | # codepage = Win32::Console::OutputCP() | |
369 | # Win32::Console::OutputCP(437) | |
370 | # | |
371 | # - PeekInput | |
372 | # | |
373 | # Does exactly the same as <b>Input</b>, except that the event read is not | |
374 | # removed from the input buffer. See also: <b>GetEvents</b>, <b>Input</b>, | |
375 | # <b>InputChar</b>, <b>Mode</b>, <b>WriteInput</b>. | |
376 | # | |
377 | # Example: | |
378 | # | |
379 | # event = console.PeekInput() | |
380 | # | |
381 | # - ReadAttr [number, col, row] | |
382 | # | |
383 | # Reads the specified I<number> of consecutive attributes, beginning at | |
384 | # I<col>, I<row>, from the console. Returns the attributes read (a | |
385 | # variable containing one character for each attribute), or <b>nil</b> on | |
386 | # errors. You can then pass the returned variable to <b>WriteAttr</b> to | |
387 | # restore the saved attributes on screen. See also: <b>ReadChar</b>, | |
388 | # <b>ReadRect</b>. | |
389 | # | |
390 | # Example: | |
391 | # | |
392 | # colors = console.ReadAttr(80*25, 0, 0) | |
393 | # | |
394 | # - ReadChar [number, col, row] | |
395 | # | |
396 | # Reads the specified I<number> of consecutive characters, beginning at | |
397 | # I<col>, I<row>, from the console. Returns a string containing the | |
398 | # characters read, or <b>nil</b> on errors. You can then pass the | |
399 | # returned variable to <b>WriteChar</b> to restore the saved characters on | |
400 | # screen. See also: <b>ReadAttr</b>, <b>ReadRect</b>. | |
401 | # | |
402 | # Example: | |
403 | # | |
404 | # chars = console.ReadChar(80*25, 0, 0) | |
405 | # | |
406 | # - ReadRect left, top, right, bottom | |
407 | # | |
408 | # Reads the content (characters and attributes) of the rectangle | |
409 | # specified by I<left>, I<top>, I<right>, I<bottom> from the console. | |
410 | # Returns a string containing the rectangle read, or <b>nil</b> on errors. | |
411 | # You can then pass the returned variable to <b>WriteRect</b> to restore the | |
412 | # saved rectangle on screen (or on another console). See also: | |
413 | # <b>ReadAttr</b>, <b>ReadChar</b>. | |
414 | # | |
415 | # Example: | |
416 | # | |
417 | # rect = console.ReadRect(0, 0, 80, 25) | |
418 | # | |
419 | # - Scroll left, top, right, bottom, col, row, char, attr, | |
420 | # [cleft, ctop, cright, cbottom] | |
421 | # | |
422 | # Moves a block of data in a console buffer the block is identified by | |
423 | # I<left>, I<top>, I<right>, I<bottom>, while I<row>, I<col> identify | |
424 | # the new location of the block. The cells left empty as a result of | |
425 | # the move are filled with the character I<char> and attribute I<attr>. | |
426 | # Optionally you can specify a clipping region with I<cleft>, I<ctop>, | |
427 | # I<cright>, I<cbottom>, so that the content of the console outside this | |
428 | # rectangle are unchanged. Returns <b>nil</b> on errors, a nonzero value | |
429 | # on success. | |
430 | # | |
431 | # Example: | |
432 | # | |
433 | # # scrolls the screen 10 lines down, filling with black spaces | |
434 | # console.Scroll(0, 0, 80, 25, 0, 10, " ", FG_BLACK | BG_BLACK) | |
435 | # | |
436 | # - Select standard_handle | |
437 | # | |
438 | # Redirects a standard handle to the specified console. | |
439 | # I<standard_handle> can have one of the following values: | |
440 | # | |
441 | # STD_INPUT_HANDLE | |
442 | # STD_OUTPUT_HANDLE | |
443 | # STD_ERROR_HANDLE | |
444 | # | |
445 | # Returns <b>nil</b> on errors, a nonzero value on success. | |
446 | # | |
447 | # Example: | |
448 | # | |
449 | # console.Select(STD_OUTPUT_HANDLE) | |
450 | # | |
451 | # - Size [col, row] | |
452 | # | |
453 | # Gets or sets the console buffer size. | |
454 | # | |
455 | # Example: | |
456 | # | |
457 | # x, y = console.Size() | |
458 | # console.Size(80, 25) | |
459 | # | |
460 | # - Title [title] | |
461 | # | |
462 | # Gets or sets the title bar the string of the current console window. | |
463 | # | |
464 | # Example: | |
465 | # | |
466 | # title = console.Title() | |
467 | # console.Title("This is a title") | |
468 | # | |
469 | # - Window [flag, left, top, right, bottom] | |
470 | # | |
471 | # Gets or sets the current console window size. If called without | |
472 | # arguments, returns a 4-element list containing the current window | |
473 | # coordinates in the form of I<left>, I<top>, I<right>, I<bottom>. To | |
474 | # set the window size, you have to specify an additional I<flag> | |
475 | # parameter: if it is 0 (zero), coordinates are considered relative to | |
476 | # the current coordinates; if it is non-zero, coordinates are absolute. | |
477 | # | |
478 | # Example: | |
479 | # | |
480 | # left, top, right, bottom = console.Window() | |
481 | # console.Window(1, 0, 0, 80, 50) | |
482 | # | |
483 | # - Write string | |
484 | # | |
485 | # Writes I<string> on the console, using the current attribute, that you | |
486 | # can set with <b>Attr</b>, and advancing the cursor as needed. This isn't | |
487 | # so different from Perl's "print" statement. Returns the number of | |
488 | # characters written or <b>nil</b> on errors. See also: <b>WriteAttr</b>, | |
489 | # <b>WriteChar</b>, <b>WriteRect</b>. | |
490 | # | |
491 | # Example: | |
492 | # | |
493 | # console.Write("Hello, world!") | |
494 | # | |
495 | # - WriteAttr attrs, col, row | |
496 | # | |
497 | # Writes the attributes in the string I<attrs>, beginning at I<col>, | |
498 | # I<row>, without affecting the characters that are on screen. The | |
499 | # string attrs can be the result of a <b>ReadAttr</b> function, or you can | |
500 | # build your own attribute string; in this case, keep in mind that every | |
501 | # attribute is treated as a character, not a number (see example). | |
502 | # Returns the number of attributes written or <b>nil</b> on errors. See | |
503 | # also: <b>Write</b>, <b>WriteChar</b>, <b>WriteRect</b>. | |
504 | # | |
505 | # Example: | |
506 | # | |
507 | # console.WriteAttr($attrs, 0, 0) | |
508 | # | |
509 | # # note the use of chr()... | |
510 | # attrs = (FG_BLACK | BG_WHITE).chr() * 80 | |
511 | # console.WriteAttr(attrs, 0, 0) | |
512 | # | |
513 | # - WriteChar chars, col, row | |
514 | # | |
515 | # Writes the characters in the string <i>attr</i>, beginning at <i>col</i>, <i>row</i>, | |
516 | # without affecting the attributes that are on screen. The string <i>chars</i> | |
517 | # can be the result of a <b>ReadChar</b> function, or a normal string. Returns | |
518 | # the number of characters written or <b>nil</b> on errors. See also: | |
519 | # <b>Write</b>, <b>WriteAttr</b>, <b>WriteRect</b>. | |
520 | # | |
521 | # Example: | |
522 | # | |
523 | # console.WriteChar("Hello, worlds!", 0, 0) | |
524 | # | |
525 | # - WriteInput (event) | |
526 | # | |
527 | # Pushes data in the console input buffer. I<(event)> is a list of values, | |
528 | # for more information see <b>Input</b>. The string chars can be the result of | |
529 | # a <b>ReadChar</b> function, or a normal string. Returns the number of | |
530 | # characters written or <b>nil</b> on errors. See also: <b>Write</b>, | |
531 | # <b>WriteAttr</b>, <b>WriteRect</b>. | |
532 | # | |
533 | # Example: | |
534 | # | |
535 | # console.WriteInput(event) | |
536 | # | |
537 | # - WriteRect rect, left, top, right, bottom | |
538 | # | |
539 | # Writes a rectangle of characters and attributes (contained in <i>rect</i>) | |
540 | # on the console at the coordinates specified by <i>left</i>, <i>top</i>, | |
541 | # <i>right</i>, <i>bottom</i>. <i>rect</i> can be the result of a <b>ReadRect</b> | |
542 | # function. Returns <b>nil</b> on errors, otherwise a 4-element list | |
543 | # containing the coordinates of the affected rectangle, in the format | |
544 | # <i>left</i>, <i>top</i>, <i>right</i>, <i>bottom</i>. See also: <b>Write</b>, | |
545 | # <b>WriteAttr</b>, <b>WriteChar</b>. | |
546 | # | |
547 | # Example: | |
548 | # | |
549 | # console.WriteRect(rect, 0, 0, 80, 25) | |
550 | # | |
551 | # | |
552 | # == Constants | |
553 | # | |
554 | # The following constants are defined in the namespace of | |
555 | # Win32::Console::Constants and are brought into the current | |
556 | # namespace when the module is required: | |
557 | # | |
558 | # BACKGROUND_BLUE | |
559 | # BACKGROUND_GREEN | |
560 | # BACKGROUND_INTENSITY | |
561 | # BACKGROUND_RED | |
562 | # CAPSLOCK_ON | |
563 | # CONSOLE_TEXTMODE_BUFFER | |
564 | # ENABLE_ECHO_INPUT | |
565 | # ENABLE_LINE_INPUT | |
566 | # ENABLE_MOUSE_INPUT | |
567 | # ENABLE_PROCESSED_INPUT | |
568 | # ENABLE_PROCESSED_OUTPUT | |
569 | # ENABLE_WINDOW_INPUT | |
570 | # ENABLE_WRAP_AT_EOL_OUTPUT | |
571 | # ENHANCED_KEY | |
572 | # FILE_SHARE_READ | |
573 | # FILE_SHARE_WRITE | |
574 | # FOREGROUND_BLUE | |
575 | # FOREGROUND_GREEN | |
576 | # FOREGROUND_INTENSITY | |
577 | # FOREGROUND_RED | |
578 | # LEFT_ALT_PRESSED | |
579 | # LEFT_CTRL_PRESSED | |
580 | # NUMLOCK_ON | |
581 | # GENERIC_READ | |
582 | # GENERIC_WRITE | |
583 | # RIGHT_ALT_PRESSED | |
584 | # RIGHT_CTRL_PRESSED | |
585 | # SCROLLLOCK_ON | |
586 | # SHIFT_PRESSED | |
587 | # STD_INPUT_HANDLE | |
588 | # STD_OUTPUT_HANDLE | |
589 | # STD_ERROR_HANDLE | |
590 | # | |
591 | # Additionally, these other constants are also added to your current | |
592 | # namespace when requiring the module: | |
593 | # | |
594 | # FG_BLACK | |
595 | # FG_BLUE | |
596 | # FG_LIGHTBLUE | |
597 | # FG_RED | |
598 | # FG_LIGHTRED | |
599 | # FG_GREEN | |
600 | # FG_LIGHTGREEN | |
601 | # FG_MAGENTA | |
602 | # FG_LIGHTMAGENTA | |
603 | # FG_CYAN | |
604 | # FG_LIGHTCYAN | |
605 | # FG_BROWN | |
606 | # FG_YELLOW | |
607 | # FG_GRAY | |
608 | # FG_WHITE | |
609 | # | |
610 | # BG_BLACK | |
611 | # BG_BLUE | |
612 | # BG_LIGHTBLUE | |
613 | # BG_RED | |
614 | # BG_LIGHTRED | |
615 | # BG_GREEN | |
616 | # BG_LIGHTGREEN | |
617 | # BG_MAGENTA | |
618 | # BG_LIGHTMAGENTA | |
619 | # BG_CYAN | |
620 | # BG_LIGHTCYAN | |
621 | # BG_BROWN | |
622 | # BG_YELLOW | |
623 | # BG_GRAY | |
624 | # BG_WHITE | |
625 | # | |
626 | # ATTR_NORMAL | |
627 | # ATTR_INVERSE | |
628 | # | |
629 | # ATTR_NORMAL is set to gray foreground on black background (DOS's | |
630 | # standard colors). | |
631 | # | |
632 | # | |
633 | # == Microsoft's Documentation | |
634 | # | |
635 | # Documentation for the Win32 Console and Character mode Functions can | |
636 | # be found on Microsoft's site at this URL: | |
637 | # | |
638 | # http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/sys/src/conchar.htm | |
639 | # | |
640 | # A reference of the available functions is at: | |
641 | # | |
642 | # http://www.microsoft.com/msdn/sdk/platforms/doc/sdk/win32/sys/src/conchar_34.htm | |
643 | # | |
644 | # | |
645 | # = VERSION HISTORY | |
646 | # | |
647 | # * 0.031 (24 Sep 1999) | |
648 | # | |
649 | # * Fixed typo in GenerateCtrlEvent(). | |
650 | # | |
651 | # * Converted and added pod documentation (from Jan Dubois <jand@activestate.com>). | |
652 | # | |
653 | # * 0.03 (07 Apr 1997) | |
654 | # | |
655 | # * Added "GenerateCtrlEvent" method. | |
656 | # | |
657 | # * The PLL file now comes in 2 versions, one for Perl version 5.001 | |
658 | # (build 110) and one for Perl version 5.003 (build 300 and higher, | |
659 | # EXCEPT 304). | |
660 | # | |
661 | # * added an installation program that will automatically copy the right | |
662 | # version in the right place. | |
663 | # | |
664 | # * 0.01 (09 Feb 1997) | |
665 | # | |
666 | # * First public release. | |
667 | # | |
668 | # = AUTHORS | |
669 | # | |
670 | # Aldo Calpini <a.calpini@romagiubileo.it> Perl module | |
671 | # | |
672 | # Gonzalo Garramuño <GGarramuno@aol.com> Ruby Port | |
673 | # | |
674 | # = CREDITS | |
675 | # | |
676 | # Thanks to: Jesse Dougherty, Dave Roth, ActiveWare, and the | |
677 | # Perl-Win32-Users community. | |
678 | # | |
679 | # | |
680 | # = DISCLAIMER | |
681 | # | |
682 | # This program is FREE; you can redistribute, modify, disassemble, or | |
683 | # even reverse engineer this software at your will. Keep in mind, | |
684 | # however, that NOTHING IS GUARANTEED to work and everything you do is | |
685 | # AT YOUR OWN RISK - I will not take responsibility for any damage, loss | |
686 | # of money and/or health that may arise from the use of this program! | |
687 | # | |
688 | # This is distributed under the terms of Larry Wall's Artistic License. | |
689 | # |
0 | # | |
1 | # = NAME | |
2 | # | |
3 | # Win32::Console::ANSI - Ruby extension to emulate ANSI console on Win32 system. | |
4 | # | |
5 | # = SYNOPSIS | |
6 | # | |
7 | # require "Win32::Console::ANSI" | |
8 | # | |
9 | # puts "\e[1;34mThis text is bold blue.\e[0m" | |
10 | # puts "This text is normal."" | |
11 | # puts "\e[33;45;1mBold yellow on magenta.\e[0m" | |
12 | # puts "This text is normal." | |
13 | # | |
14 | # With the Term::ANSIColor module one increases the readability: | |
15 | # | |
16 | # require "Win32::Console::ANSI" | |
17 | # require "Term::ANSIColor" | |
18 | # | |
19 | # puts color 'bold blue' | |
20 | # puts "This text is bold blue." | |
21 | # puts color 'reset' | |
22 | # puts "This text is normal." | |
23 | # puts colored ("Bold yellow on magenta.", 'bold yellow on_magenta') | |
24 | # puts "This text is normal." | |
25 | # | |
26 | # And even more with Term::ANSIScreen: | |
27 | # | |
28 | # require "Win32::Console::ANSI; | |
29 | # require "Term::ANSIScreen qw/:color :cursor :screen/; | |
30 | # | |
31 | # locate 1, 1; puts "@ This is (1,1)", savepos; | |
32 | # puts locate(24,60), "@ This is (24,60)"; loadpos; | |
33 | # puts down(2), clline, "@ This is (3,16)"; | |
34 | # setscroll 1, 20; | |
35 | # color 'black on white'; clline; | |
36 | # puts "This line is black on white."; | |
37 | # puts color 'reset'; puts "This text is normal."; | |
38 | # puts colored ("This text is bold blue.", 'bold blue'); | |
39 | # puts "This text is normal."; | |
40 | # puts colored ['bold blue'], "This text is bold blue."; | |
41 | # puts "This text is normal."; | |
42 | # | |
43 | # = DESCRIPTION | |
44 | # | |
45 | # Windows NT/2000/XP does not support ANSI escape sequences in Win32 Console | |
46 | # applications. This module emulates an ANSI console for the script which | |
47 | # uses it. | |
48 | # | |
49 | # | |
50 | # == Escape sequences for Cursor Movement | |
51 | # | |
52 | # * \e[#A | |
53 | # | |
54 | # CUU: CUrsor Up: Moves the cursor up by the specified number of lines without | |
55 | # changing columns. If the cursor is already on the top line, this sequence | |
56 | # is ignored. \e[A is equivalent to \e[1A. | |
57 | # | |
58 | # * \e[#B | |
59 | # | |
60 | # CUD: CUrsor Down: Moves the cursor down by the specified number of lines | |
61 | # without changing columns. If the cursor is already on the bottom line, | |
62 | # this sequence is ignored. \e[B is equivalent to \e[1B. | |
63 | # | |
64 | # * \e[#C | |
65 | # | |
66 | # CUF: CUrsor Forward: Moves the cursor forward by the specified number of | |
67 | # columns without changing lines. If the cursor is already in the | |
68 | # rightmost column, this sequence is ignored. \e[C is equivalent to \e[1C. | |
69 | # | |
70 | # * \e[#D | |
71 | # | |
72 | # CUB: CUrsor Backward: Moves the cursor back by the specified number of | |
73 | # columns without changing lines. If the cursor is already in the leftmost | |
74 | # column, this sequence is ignored. \e[D is equivalent to \e[1D. | |
75 | # | |
76 | # * \e[#E | |
77 | # | |
78 | # CNL: Cursor Next Line: Moves the cursor down the indicated # of rows, to | |
79 | # column 1. \e[E is equivalent to \e[1E. | |
80 | # | |
81 | # * \e[#F | |
82 | # | |
83 | # CPL: Cursor Preceding Line: Moves the cursor up the indicated # of rows, | |
84 | # to column 1. \e[F is equivalent to \e[1F. | |
85 | # | |
86 | # * \e[#G | |
87 | # | |
88 | # CHA: Cursor Horizontal Absolute: Moves the cursor to indicated column in | |
89 | # current row. \e[G is equivalent to \e[1G. | |
90 | # | |
91 | # * \e[#;#H | |
92 | # | |
93 | # CUP: CUrsor Position: Moves the cursor to the specified position. The first # | |
94 | # specifies the line number, the second # specifies the column. | |
95 | # If you do not specify a position, the cursor moves to the | |
96 | # home position: the upper-left corner of the screen (line 1, column 1). | |
97 | # | |
98 | # * \e[#;#f | |
99 | # | |
100 | # HVP: Horizontal and Vertical Position. | |
101 | # Works the same way as the preceding escape sequence. | |
102 | # | |
103 | # * \e[s | |
104 | # | |
105 | # SCP: Save Cursor Position: Saves the current cursor position. You can move | |
106 | # the cursor to the saved cursor position by using the Restore Cursor | |
107 | # Position sequence. | |
108 | # | |
109 | # * \e[u | |
110 | # | |
111 | # RCP: Restore Cursor Position: Returns the cursor to the position stored | |
112 | # by the Save Cursor Position sequence. | |
113 | # | |
114 | # == Escape sequences for Display Edition | |
115 | # | |
116 | # * \e[#J | |
117 | # | |
118 | # ED: Erase Display: | |
119 | # | |
120 | # * \e[0J | |
121 | # | |
122 | # Clears the screen from cursor to end of display. The cursor position is unchanged. | |
123 | # | |
124 | # * \e[1J | |
125 | # | |
126 | # Clears the screen from start to cursor. The cursor position is unchanged. | |
127 | # | |
128 | # * \e[2J | |
129 | # | |
130 | # Clears the screen and moves the cursor to the home position (line 1, column 1). | |
131 | # | |
132 | # \e[J is equivalent to \e[0J. (Some terminal/emulators respond to \e[J as if | |
133 | # it were \e[2J. Here, the default is 0; it's the norm) | |
134 | # | |
135 | # * \e[#K | |
136 | # | |
137 | # EL: Erase Line: | |
138 | # | |
139 | # * \e[0K | |
140 | # | |
141 | # Clears all characters from the cursor position to the end of the line | |
142 | # (including the character at the cursor position). | |
143 | # The cursor position is unchanged. | |
144 | # | |
145 | # * \e[1K | |
146 | # | |
147 | # Clears all characters from start of line to the cursor position. | |
148 | # (including the character at the cursor position). | |
149 | # The cursor position is unchanged. | |
150 | # | |
151 | # * \e[2K | |
152 | # | |
153 | # Clears all characters of the whole line. | |
154 | # The cursor position is unchanged. | |
155 | # | |
156 | # \e[K is equivalent to \e[0K. | |
157 | # | |
158 | # * \e[#L | |
159 | # | |
160 | # IL: Insert Lines: The cursor line and all lines below it move down # lines, | |
161 | # leaving blank space. The cursor position is unchanged. The bottommost # | |
162 | # lines are lost. \e[L is equivalent to \e[1L. | |
163 | # | |
164 | # * \e[#M | |
165 | # | |
166 | # DL: Delete Line: The block of # lines at and below the cursor are deleted; | |
167 | # all lines below them move up # lines to fill in the gap, leaving # blank | |
168 | # lines at the bottom of the screen. The cursor position is unchanged. | |
169 | # \e[M is equivalent to \e[1M. | |
170 | # | |
171 | # * \e#\@ | |
172 | # | |
173 | # ICH: Insert CHaracter: The cursor character and all characters to the right | |
174 | # of it move right # columns, leaving behind blank space. | |
175 | # The cursor position is unchanged. The rightmost # characters on the line are lost. | |
176 | # | |
177 | # * \e[#P | |
178 | # | |
179 | # DCH: Delete CHaracter: The block of # characters at and to the right of the | |
180 | # cursor are deleted; all characters to the right of it move left # columns, | |
181 | # leaving behind blank space. The cursor position is unchanged. | |
182 | # \e[P is equivalent to \e[1P. | |
183 | # | |
184 | # | |
185 | # == Escape sequences for Set Graphics Rendition | |
186 | # | |
187 | # * \e[#;...;#m | |
188 | # | |
189 | # SGM: Set Graphics Mode: Calls the graphics functions specified by the | |
190 | # following values. These specified functions remain active until the next | |
191 | # occurrence of this escape sequence. Graphics mode changes the colors and | |
192 | # attributes of text (such as bold and underline) displayed on the | |
193 | # screen. | |
194 | # | |
195 | # * Text attributes | |
196 | # | |
197 | # 0 All attributes off | |
198 | # 1 Bold on | |
199 | # 4 Underscore on | |
200 | # 7 Reverse video on | |
201 | # 8 Concealed on | |
202 | # | |
203 | # 21 Bold off | |
204 | # 24 Underscore off | |
205 | # 27 Reverse video off | |
206 | # 28 Concealed off | |
207 | # | |
208 | # * Foreground colors | |
209 | # | |
210 | # 30 Black | |
211 | # 31 Red | |
212 | # 32 Green | |
213 | # 33 Yellow | |
214 | # 34 Blue | |
215 | # 35 Magenta | |
216 | # 36 Cyan | |
217 | # 37 White | |
218 | # | |
219 | # * Background colors | |
220 | # | |
221 | # 40 Black | |
222 | # 41 Red | |
223 | # 42 Green | |
224 | # 43 Yellow | |
225 | # 44 Blue | |
226 | # 45 Magenta | |
227 | # 46 Cyan | |
228 | # 47 White | |
229 | # | |
230 | # \e[m is equivalent to \e0m. | |
231 | # | |
232 | # == Escape sequences for Select Character Set | |
233 | # | |
234 | # * \e(U | |
235 | # | |
236 | # Select null mapping - straight to character from the codepage of the console. | |
237 | # | |
238 | # * \e(K | |
239 | # | |
240 | # Select Windows to DOS mapping, if the corresponding map exist; no effect | |
241 | # otherwise. This is the default mapping (if the map exist, of course). It's | |
242 | # useful becarequire "one types the script with a Windows-based editor (using a | |
243 | # Windows codepage) and the script prints its messages on the console using | |
244 | # another codepage: without translation, the characters with a code greatest | |
245 | # than 127 are different and the printed messages may be not readable. | |
246 | # | |
247 | # The conversion is done by the module Encode if it is installed (it's a | |
248 | # standard module with Perl5.8, not Ruby yet). Otherwise, the conversion is limited to the | |
249 | # following couples: | |
250 | # | |
251 | # WinLatin1 (cp1252) to DOSLatin1 (cp850) | |
252 | # WinLatin1 (cp1252) to DOSLatinUS (cp437) | |
253 | # WinLatin2 (cp1250) to DOSLatin2 (cp852) | |
254 | # WinCyrillic(cp1251) to DOSCyrillic (cp855) | |
255 | # | |
256 | # * \e(#X | |
257 | # | |
258 | # This escape sequence is I<not> standard! It's an experimental one, just for | |
259 | # fun :-) | |
260 | # | |
261 | # If <i>and only if</i> the console uses an Unicode police, it is possible to | |
262 | # change its codepage with this escape sequence. No effect with an ordinary | |
263 | # "Raster Font". (For Windows NT/2000/XP the currently available Unicode | |
264 | # console font is the Lucida Console TrueType font.) | |
265 | # # is the number of the codepage needed, 855 for cp855 for instance. | |
266 | # | |
267 | # | |
268 | # = LIMITATIONS | |
269 | # | |
270 | # * Due to DOS-console limitations, the blink mode (text attributes 5 and 25) is not implemented. | |
271 | # | |
272 | # = SEE ALSO | |
273 | # | |
274 | # <b>Win32::Console</b>, <b>Term::ANSIColor</b>, <b>Term::ANSIScreen</b>. | |
275 | # | |
276 | # = AUTHOR | |
277 | # | |
278 | # J-L Morel jl_morel@bribes.org | |
279 | # | |
280 | # Home page: http://www.bribes.org/perl/wANSIConsole.html | |
281 | # | |
282 | # Gonzalo Garramuño GGarramuno@aol.com Ruby port | |
283 | # | |
284 | # = CREDITS | |
285 | # | |
286 | # Render unto Cæsar the things which are Cæsar's... | |
287 | # | |
288 | # This module requires the module Win32::Console. Thanks to Aldo Calpini. | |
289 | # | |
290 | # The method used to overload the print function is due to Matt Sergeant | |
291 | # (see his module Win32::ASP). | |
292 | # | |
293 | # = COPYRIGHT | |
294 | # | |
295 | # Copyright (c) 2004 Gonzalo Garramuño. All rights reserved. | |
296 | # Copyright (c) 2003 J-L Morel. All rights reserved. | |
297 | # | |
298 | # This program is free software; you can redistribute it and/or modify it under | |
299 | # the terms of the Artistic License. | |
300 | # | |
301 | # |
0 | v1.0 - Added .dup to _printString function to avoid mangling outside | |
1 | string references. Removed the other (later) .dup call. | |
2 | Turned of some exceptions that were conflicting with using | |
3 | the module with pipes or redirections. | |
4 | v0.8 - Fixed bugs in reading routines, added ruby docs, and | |
5 | sample test suite. | |
6 | v0.5 - First public release. |
0 | ||
1 | To compile and install: | |
2 | ||
3 | ||
4 | Open a windows console. | |
5 | > vcvars32.bat # to set up microsoft's compiling environment | |
6 | # this is located in the bin/ directory of the MSVC compiler | |
7 | > ruby extconf.rb # to create a Makefile | |
8 | > nmake # to compile | |
9 | > nmake install # to install | |
10 | ||
11 | ||
12 | To test: | |
13 | ||
14 | > cd test | |
15 | > dir # to see available samples | |
16 | > ruby [anysample] | |
17 |
0 | ||
1 | SHELL = /bin/sh | |
2 | ||
3 | #### Start of system configuration section. #### | |
4 | ||
5 | srcdir = C:/ruby/visualc/Console | |
6 | topdir = $(rubylibdir)/$(arch) | |
7 | hdrdir = $(rubylibdir)/$(arch) | |
8 | VPATH = $(srcdir) | |
9 | ||
10 | DESTDIR = c: | |
11 | prefix = $(DESTDIR)/ruby | |
12 | exec_prefix = $(prefix) | |
13 | bindir = $(exec_prefix)/bin | |
14 | sitelibdir = $(sitedir)/$(ruby_version) | |
15 | datadir = $(prefix)/share | |
16 | sitedir = $(prefix)/lib/ruby/site_ruby | |
17 | sharedstatedir = $(DESTDIR)/etc | |
18 | archdir = $(rubylibdir)/$(arch) | |
19 | localstatedir = $(DESTDIR)/var | |
20 | infodir = $(prefix)/info | |
21 | oldincludedir = $(DESTDIR)/usr/include | |
22 | libexecdir = $(exec_prefix)/libexec | |
23 | compile_dir = $(DESTDIR)/WINDOWS/Escritorio/Programacion/ruby/win32 | |
24 | sbindir = $(exec_prefix)/sbin | |
25 | includedir = $(prefix)/include | |
26 | sysconfdir = $(prefix)/etc | |
27 | sitearchdir = $(sitelibdir)/$(sitearch) | |
28 | mandir = $(prefix)/man | |
29 | libdir = $(exec_prefix)/lib | |
30 | rubylibdir = $(libdir)/ruby/$(ruby_version) | |
31 | ||
32 | CC = cl -nologo | |
33 | LIBRUBY = $(RUBY_SO_NAME).lib | |
34 | LIBRUBY_A = $(RUBY_SO_NAME)-static.lib | |
35 | LIBRUBYARG_SHARED = $(LIBRUBY) | |
36 | LIBRUBYARG_STATIC = $(LIBRUBY_A) | |
37 | ||
38 | CFLAGS = -MD -Zi -O2b2xg- -G6 | |
39 | CPPFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir) -I. -I./.. -I./../missing | |
40 | CXXFLAGS = $(CFLAGS) | |
41 | DLDFLAGS = -link -incremental:no -debug -opt:ref -opt:icf -dll $(LIBPATH) -def:$(DEFFILE) | |
42 | LDSHARED = cl -nologo -LD | |
43 | AR = lib -nologo | |
44 | EXEEXT = .exe | |
45 | ||
46 | RUBY_INSTALL_NAME = ruby | |
47 | RUBY_SO_NAME = msvcrt-ruby18 | |
48 | arch = i386-mswin32 | |
49 | sitearch = i386-msvcrt | |
50 | ruby_version = 1.8 | |
51 | RUBY = ruby | |
52 | RM = $(RUBY) -run -e rm -- -f | |
53 | MAKEDIRS = $(RUBY) -run -e mkdir -- -p | |
54 | INSTALL_PROG = $(RUBY) -run -e install -- -vpm 0755 | |
55 | INSTALL_DATA = $(RUBY) -run -e install -- -vpm 0644 | |
56 | ||
57 | #### End of system configuration section. #### | |
58 | ||
59 | ||
60 | LIBPATH = -libpath:"$(libdir)" | |
61 | DEFFILE = $(TARGET)-$(arch).def | |
62 | ||
63 | CLEANFILES = | |
64 | DISTCLEANFILES = $(DEFFILE) | |
65 | ||
66 | target_prefix = | |
67 | LOCAL_LIBS = | |
68 | LIBS = $(LIBRUBYARG_SHARED) oldnames.lib user32.lib advapi32.lib wsock32.lib | |
69 | OBJS = Console.obj | |
70 | TARGET = Console | |
71 | DLLIB = $(TARGET).so | |
72 | STATIC_LIB = $(TARGET).lib | |
73 | ||
74 | RUBYCOMMONDIR = $(sitedir)$(target_prefix) | |
75 | RUBYLIBDIR = $(sitelibdir)$(target_prefix) | |
76 | RUBYARCHDIR = $(sitearchdir)$(target_prefix) | |
77 | ||
78 | CLEANLIBS = "$(TARGET).{lib,exp,il?,tds,map}" $(DLLIB) | |
79 | CLEANOBJS = "*.{obj,lib,s[ol],pdb,bak}" | |
80 | ||
81 | all: $(DLLIB) | |
82 | static: $(STATIC_LIB) | |
83 | ||
84 | clean: | |
85 | @$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) | |
86 | ||
87 | distclean: clean | |
88 | @$(RM) Makefile extconf.h conftest.* mkmf.log | |
89 | @$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) | |
90 | ||
91 | realclean: distclean | |
92 | install: $(RUBYARCHDIR) | |
93 | install: $(RUBYARCHDIR)/$(DLLIB) | |
94 | $(RUBYARCHDIR)/$(DLLIB): $(DLLIB) $(RUBYARCHDIR) | |
95 | @$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) | |
96 | install: $(RUBYLIBDIR)/Win32 | |
97 | install: $(RUBYLIBDIR)/Win32/Console.rb | |
98 | $(RUBYLIBDIR)/Win32/Console.rb: $(srcdir)/lib/Win32/Console.rb $(RUBYLIBDIR)/Win32 | |
99 | @$(INSTALL_DATA) $(srcdir)/lib/Win32/Console.rb $(RUBYLIBDIR)/Win32 | |
100 | install: $(RUBYLIBDIR)/Win32/Console | |
101 | install: $(RUBYLIBDIR)/Win32/Console/ANSI.rb | |
102 | $(RUBYLIBDIR)/Win32/Console/ANSI.rb: $(srcdir)/lib/Win32/Console/ANSI.rb $(RUBYLIBDIR)/Win32/Console | |
103 | @$(INSTALL_DATA) $(srcdir)/lib/Win32/Console/ANSI.rb $(RUBYLIBDIR)/Win32/Console | |
104 | install: $(RUBYLIBDIR)/Term | |
105 | install: $(RUBYLIBDIR)/Term/ansicolor.rb | |
106 | $(RUBYLIBDIR)/Term/ansicolor.rb: $(srcdir)/lib/Term/ansicolor.rb $(RUBYLIBDIR)/Term | |
107 | @$(INSTALL_DATA) $(srcdir)/lib/Term/ansicolor.rb $(RUBYLIBDIR)/Term | |
108 | $(RUBYARCHDIR): | |
109 | @$(MAKEDIRS) $(RUBYARCHDIR) | |
110 | $(RUBYLIBDIR)/Win32: | |
111 | @$(MAKEDIRS) $(RUBYLIBDIR)/Win32 | |
112 | $(RUBYLIBDIR)/Win32/Console: | |
113 | @$(MAKEDIRS) $(RUBYLIBDIR)/Win32/Console | |
114 | $(RUBYLIBDIR)/Term: | |
115 | @$(MAKEDIRS) $(RUBYLIBDIR)/Term | |
116 | ||
117 | site-install: install | |
118 | ||
119 | .SUFFIXES: .c .cc .m .cxx .cpp .C .obj | |
120 | ||
121 | {$(srcdir)}.cc{}.obj: | |
122 | $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) | |
123 | ||
124 | .cc.obj: | |
125 | $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) | |
126 | ||
127 | {$(srcdir)}.cpp{}.obj: | |
128 | $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) | |
129 | ||
130 | .cpp.obj: | |
131 | $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) | |
132 | ||
133 | {$(srcdir)}.cxx{}.obj: | |
134 | $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) | |
135 | ||
136 | .cxx.obj: | |
137 | $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) | |
138 | ||
139 | {$(srcdir)}.C{}.obj: | |
140 | $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) | |
141 | ||
142 | .C.obj: | |
143 | $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -Tp$(<:\=/) | |
144 | ||
145 | {$(srcdir)}.c{}.obj: | |
146 | $(CC) $(CFLAGS) $(CPPFLAGS) -c -Tc$(<:\=/) | |
147 | ||
148 | .c.obj: | |
149 | $(CC) $(CFLAGS) $(CPPFLAGS) -c -Tc$(<:\=/) | |
150 | ||
151 | $(DLLIB): $(OBJS) $(DEFFILE) | |
152 | @-$(RM) $@ | |
153 | @-$(RM) $(TARGET).lib | |
154 | $(LDSHARED) -Fe$(@) $(OBJS) $(LIBS) $(LOCAL_LIBS) $(DLDFLAGS) | |
155 | ||
156 | $(STATIC_LIB): $(OBJS) | |
157 | $(AR) -machine:x86 -out:$@ $(OBJS) | |
158 | ||
159 | $(DEFFILE): | |
160 | $(RUBY) -e "puts 'EXPORTS', 'Init_$(TARGET)'" > $@ | |
161 |
0 | ||
1 | This file implements a port of Perl's Win32::Console | |
2 | and Win32::Console::ANSI modules. | |
3 | ||
4 | Win32::Console allows controling the windows command line terminal | |
5 | thru an OO-interface. This allows you to query the terminal (find | |
6 | its size, characters, attributes, etc). The interface and functionality | |
7 | should be identical to Perl's. | |
8 | ||
9 | Win32::Console consists of a Ruby .rb interface. | |
10 | For best performance, this library has been also ported to C. | |
11 | If you lack a C compiler, you can still use the class thru the ruby | |
12 | interface. If you can compile it, then the ruby interface is not | |
13 | used and the C functions are called instead. | |
14 | ||
15 | Win32::Console::ANSI is a class derived from IO that seamlessly | |
16 | translates ANSI Esc control character codes into Windows' command.exe | |
17 | or cmd.exe equivalents. | |
18 | ||
19 | These modules allow you to develop command-line tools that can take | |
20 | advantage of the unix terminal functions while still being portable. | |
21 | One of the most common uses for this is to allow to color your | |
22 | output. | |
23 | The modules are disted with Term/ansicolor.rb, too, as it is a nice | |
24 | thing to verify it is working properly. | |
25 |
0 | ################################################################# | |
1 | # | |
2 | # To compile and install, do this: | |
3 | # | |
4 | # Make sure your compiling environment is in your path. | |
5 | # In the case of MSVC, this involves running vcvars32.bat first | |
6 | # which is located in the bin directory of MS Visual C++. | |
7 | # | |
8 | # Then: | |
9 | # | |
10 | # > ruby extconf.rb | |
11 | # > nmake Makefile | |
12 | # > nmake install | |
13 | # | |
14 | # | |
15 | ################################################################## | |
16 | require 'mkmf' | |
17 | create_makefile('Console') |
0 | module Term | |
1 | ||
2 | module ANSIColor | |
3 | ||
4 | @@attributes = [ | |
5 | [ :clear , 0 ], | |
6 | [ :reset , 0 ], # synonym for :clear | |
7 | [ :bold , 1 ], | |
8 | [ :dark , 2 ], | |
9 | [ :italic , 3 ], # not widely implemented | |
10 | [ :underline , 4 ], | |
11 | [ :underscore , 4 ], # synonym for :underline | |
12 | [ :blink , 5 ], | |
13 | [ :rapid_blink , 6 ], # not widely implemented | |
14 | [ :negative , 7 ], # no reverse because of String#reverse | |
15 | [ :concealed , 8 ], | |
16 | [ :strikethrough, 9 ], # not widely implemented | |
17 | [ :black , 30 ], | |
18 | [ :red , 31 ], | |
19 | [ :green , 32 ], | |
20 | [ :yellow , 33 ], | |
21 | [ :blue , 34 ], | |
22 | [ :magenta , 35 ], | |
23 | [ :cyan , 36 ], | |
24 | [ :white , 37 ], | |
25 | [ :on_black , 40 ], | |
26 | [ :on_red , 41 ], | |
27 | [ :on_green , 42 ], | |
28 | [ :on_yellow , 43 ], | |
29 | [ :on_blue , 44 ], | |
30 | [ :on_magenta , 45 ], | |
31 | [ :on_cyan , 46 ], | |
32 | [ :on_white , 47 ], | |
33 | ] | |
34 | ||
35 | @@attributes.each do |c, v| | |
36 | eval %Q{ | |
37 | def #{c.to_s}(string = nil) | |
38 | result = "\e[#{v}m" | |
39 | if block_given? | |
40 | result << yield | |
41 | result << "\e[0m" | |
42 | elsif string | |
43 | result << string | |
44 | result << "\e[0m" | |
45 | elsif respond_to?(:to_str) | |
46 | result << self | |
47 | result << "\e[0m" | |
48 | end | |
49 | return result | |
50 | end | |
51 | } | |
52 | end | |
53 | ||
54 | ColoredRegexp = /\e\[([34][0-7]|[0-9])m/ | |
55 | def uncolored(string = nil) | |
56 | if block_given? | |
57 | yield.gsub(ColoredRegexp, '') | |
58 | elsif string | |
59 | string.gsub(ColoredRegexp, '') | |
60 | elsif respond_to?(:to_str) | |
61 | gsub(ColoredRegexp, '') | |
62 | else | |
63 | '' | |
64 | end | |
65 | end | |
66 | ||
67 | def attributes | |
68 | @@attributes.map { |c| c[0] } | |
69 | end | |
70 | module_function :attributes | |
71 | ||
72 | end | |
73 | ||
74 | end | |
75 | # vim: set cin sw=4 ts=4: |
0 | # | |
1 | # Win32::Console::ANSI | |
2 | # | |
3 | # Copyright 2004 - Gonzalo Garramuno | |
4 | # Licensed under GNU General Public License or Perl's Artistic License | |
5 | # | |
6 | # Based on Perl's Win32::Console::ANSI | |
7 | # Copyright (c) 2003 Jean-Louis Morel <jl_morel@bribes.org> | |
8 | # Licensed under GNU General Public License or Perl's Artistic License | |
9 | # | |
10 | require "win32/Console" | |
11 | ||
12 | module Win32 | |
13 | class Console | |
14 | module ANSI | |
15 | ||
16 | class IO < IO | |
17 | ||
18 | VERSION = '0.05' | |
19 | DEBUG = nil | |
20 | ||
21 | require "win32/registry" | |
22 | ||
23 | include Win32::Console::Constants | |
24 | ||
25 | # @todo: encode is another perl module | |
26 | EncodeOk = false | |
27 | ||
28 | # Retrieving the codepages | |
29 | cpANSI = nil | |
30 | Win32::Registry::HKEY_LOCAL_MACHINE.open('SYSTEM\CurrentControlSet\Control\Nls\CodePage' ) { |reg| | |
31 | cpANSI = reg['ACP'] | |
32 | } | |
33 | ||
34 | STDERR.puts "Unable to read Win codepage #{cpANSI}" if DEBUG && !cpANSI | |
35 | ||
36 | ||
37 | cpANSI = 'cp'+(cpANSI ? cpANSI : '1252') # Windows codepage | |
38 | OEM = Win32::Console::OutputCP() | |
39 | cpOEM = 'cp' + OEM.to_s # DOS codepage | |
40 | @@cp = cpANSI + cpOEM | |
41 | ||
42 | STDERR.puts "EncodeOk=#{EncodeOk} cpANSI=#{cpANSI} "+ | |
43 | "cpOEM=#{cpOEM}" if DEBUG | |
44 | ||
45 | @@color = { 30 => 0, # black foreground | |
46 | 31 => FOREGROUND_RED, # red foreground | |
47 | 32 => FOREGROUND_GREEN, # green foreground | |
48 | 33 => FOREGROUND_RED|FOREGROUND_GREEN, # yellow foreground | |
49 | 34 => FOREGROUND_BLUE, # blue foreground | |
50 | 35 => FOREGROUND_BLUE|FOREGROUND_RED, # magenta foreground | |
51 | 36 => FOREGROUND_BLUE|FOREGROUND_GREEN, # cyan foreground | |
52 | 37 => FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE, # white foreground | |
53 | 40 => 0, # black background | |
54 | 41 => BACKGROUND_RED, # red background | |
55 | 42 => BACKGROUND_GREEN, # green background | |
56 | 43 => BACKGROUND_RED|BACKGROUND_GREEN, # yellow background | |
57 | 44 => BACKGROUND_BLUE, # blue background | |
58 | 45 => BACKGROUND_BLUE|BACKGROUND_RED, # magenta background | |
59 | 46 => BACKGROUND_BLUE|BACKGROUND_GREEN, # cyan background | |
60 | 47 => BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE, # white background | |
61 | } | |
62 | ||
63 | def initialize | |
64 | super(1,'w') | |
65 | @Out = Win32::Console.new(STD_OUTPUT_HANDLE) | |
66 | @x = @y = 0 # to save cursor position | |
67 | @foreground = 7 | |
68 | @background = 0 | |
69 | @bold = | |
70 | @underline = | |
71 | @revideo = | |
72 | @concealed = nil | |
73 | @conv = 1 # char conversion by default | |
74 | end | |
75 | ||
76 | ||
77 | def write(*s) | |
78 | s.each { |x| | |
79 | _PrintString(x) | |
80 | } | |
81 | end | |
82 | ||
83 | ||
84 | private | |
85 | ||
86 | def _PrintString(t) | |
87 | s = t.dup | |
88 | while s != '' | |
89 | if s.sub!( /([^\e]*)?\e([\[\(])([0-9\;\=]*)([a-zA-Z@])(.*)/s,'\5') | |
90 | @Out.Write((_conv("#$1"))) | |
91 | if $2 == '[' | |
92 | case $4 | |
93 | when 'm' # ESC[#;#;....;#m Set display attributes | |
94 | attributs = $3.split(';') | |
95 | attributs.push(nil) unless attributs # ESC[m == ESC[;m ==...==ESC[0m | |
96 | for attr in attributs | |
97 | atv = attr.to_i | |
98 | if atv > 0 | |
99 | if atv == 1 | |
100 | @bold = 1 | |
101 | elsif atv == 21 | |
102 | @bold = nil | |
103 | elsif atv == 4 | |
104 | @underline = 1 | |
105 | elsif atv == 24 | |
106 | @underline = nil | |
107 | elsif atv == 7 | |
108 | @revideo = 1 | |
109 | elsif atv == 27 | |
110 | @revideo = nil | |
111 | elsif atv == 8 | |
112 | @concealed = 1 | |
113 | elsif atv == 28 | |
114 | @concealed = nil | |
115 | elsif atv >= 30 and atv <= 37 | |
116 | @foreground = atv - 30 | |
117 | elsif atv >=40 and atv <=47 | |
118 | @background = atv - 40 | |
119 | end | |
120 | else # ESC[0m reset | |
121 | @foreground = 7 | |
122 | @background = 0 | |
123 | @bold = | |
124 | @underline = | |
125 | @revideo = | |
126 | @concealed = nil | |
127 | end | |
128 | end | |
129 | ||
130 | if @revideo | |
131 | attribut = @@color[40+@foreground] | | |
132 | @@color[30+@background] | |
133 | else | |
134 | attribut = @@color[30+@foreground] | | |
135 | @@color[40+@background] | |
136 | end | |
137 | attribut |= FOREGROUND_INTENSITY if @bold | |
138 | attribut |= BACKGROUND_INTENSITY if @underline | |
139 | @Out.Attr(attribut) | |
140 | when 'J' | |
141 | if !$3 or $3 == '' # ESC[0J from cursor to end of display | |
142 | info = @Out.Info() | |
143 | s = ' ' * ((info[1]-info[3]-1)*info[0]+info[0]-info[2]-1) | |
144 | @Out.WriteChar(s, info[2], info[3]) | |
145 | @Out.Cursor(info[2], info[3]) | |
146 | elsif $3 == '1' # ESC[1J erase from start to cursor. | |
147 | info = @Out.Info() | |
148 | s = ' ' * (info[3]*info[0]+info[2]+1) | |
149 | @Out.WriteChar(s, 0, 0) | |
150 | @Out.Cursor(info[2], info[3]) | |
151 | elsif $3 == '2' # ESC[2J Clear screen and home cursor | |
152 | @Out.Cls() | |
153 | @Out.Cursor(0, 0) | |
154 | else | |
155 | STDERR.print "\e#$2#$3#$4" if DEBUG # if ESC-code not implemented | |
156 | end | |
157 | when 'K' | |
158 | info = @Out.Info() | |
159 | if !$3 or $3 == '' # ESC[0K Clear to end of line | |
160 | s = ' ' * (info[7]-info[2]+1) | |
161 | @Out.Write(s) | |
162 | @Out.Cursor(info[2], info[3]) | |
163 | elsif $3=='1' # ESC[1K Clear from start of line to cursor | |
164 | s = ' '*(info[2]+1) | |
165 | @Out.WriteChar(s, 0, info[3]) | |
166 | @Out.Cursor(info[2], info[3]) | |
167 | elsif $3=='2' # ESC[2K Clear whole line. | |
168 | s = ' '* info[0] | |
169 | @Out.WriteChar(s, 0, info[3]) | |
170 | @Out.Cursor(info[2], info[3]) | |
171 | end | |
172 | when 'L' # ESC[#L Insert # blank lines. | |
173 | n = $3 == ''? 1 : $3.to_i # ESC[L == ESC[1L | |
174 | info = @Out.Info() | |
175 | @Out.Scroll(0, info[3], info[0]-1, info[1]-1, | |
176 | 0, info[3] + n.to_i, | |
177 | ' '[0], @Out.Attr(), | |
178 | 0, 0, 10000, 10000) | |
179 | @Out.Cursor(info[2], info[3]) | |
180 | when 'M' # ESC[#M Delete # line. | |
181 | n = $3 == ''? 1 : $3.to_i # ESC[M == ESC[1M | |
182 | info = @Out.Info(); | |
183 | @Out.Scroll(0, info[3]+n, info[0]-1, info[1]-1, | |
184 | 0, info[3], | |
185 | ' '[0], @Out.Attr(), | |
186 | 0, 0, 10000, 10000) | |
187 | @Out.Cursor(info[2], info[3]) | |
188 | when 'P' # ESC[#P Delete # characters. | |
189 | n = $3 == ''? 1 : $3.to_i # ESC[P == ESC[1P | |
190 | info = @Out.Info() | |
191 | n = info[0]-info[2] if info[2]+n > info[0]-1 | |
192 | @Out.Scroll(info[2]+n, info[3] , info[0]-1, info[3], | |
193 | info[2], info[3], | |
194 | ' '[0], @Out.Attr(), | |
195 | 0, 0, 10000, 10000) | |
196 | s = ' ' * n | |
197 | @Out.Cursor(info[0]-n, info[3]) | |
198 | @Out.Write(s) | |
199 | @Out.Cursor(info[2], info[3]) | |
200 | when '@' # ESC[#@ Insert # blank Characters | |
201 | s = ' ' * $3.to_i | |
202 | info = @Out.Info() | |
203 | s << @Out.ReadChar(info[7]-info[2]+1, info[2], info[3]) | |
204 | s = s[0..-($3.to_i)] | |
205 | @Out.Write(s); | |
206 | @Out.Cursor(info[2], info[3]) | |
207 | when 'A' # ESC[#A Moves cursor up # lines | |
208 | (x, y) = @Out.Cursor() | |
209 | n = $3 == ''? 1 : $3.to_i; # ESC[A == ESC[1A | |
210 | @Out.Cursor(x, y-n) | |
211 | when 'B' # ESC[#B Moves cursor down # lines | |
212 | (x, y) = @Out.Cursor() | |
213 | n = $3 == ''? 1 : $3.to_i; # ESC[B == ESC[1B | |
214 | @Out.Cursor(x, y+n) | |
215 | when 'C' # ESC[#C Moves cursor forward # spaces | |
216 | (x, y) = @Out.Cursor() | |
217 | n = $3 == ''? 1 : $3.to_i; # ESC[C == ESC[1C | |
218 | @Out.Cursor(x+n, y) | |
219 | when 'D' # ESC[#D Moves cursor back # spaces | |
220 | (x, y) = @Out.Cursor() | |
221 | n = $3 == ''? 1 : $3.to_i; # ESC[D == ESC[1D | |
222 | @Out.Cursor(x-n, y) | |
223 | when 'E' # ESC[#E Moves cursor down # lines, column 1. | |
224 | x, y = @Out.Cursor() | |
225 | n = $3 == ''? 1 : $3.to_i; # ESC[E == ESC[1E | |
226 | @Out.Cursor(0, y+n) | |
227 | when 'F' # ESC[#F Moves cursor up # lines, column 1. | |
228 | x, y = @Out.Cursor() | |
229 | n = $3 == ''? 1 : $3.to_i; # ESC[F == ESC[1F | |
230 | @Out.Cursor(0, y-n) | |
231 | when 'G' # ESC[#G Moves cursor column # in current row. | |
232 | x, y = @Out.Cursor() | |
233 | n = $3 == ''? 1 : $3.to_i; # ESC[G == ESC[1G | |
234 | @Out.Cursor(n-1, y) | |
235 | when 'f' # ESC[#;#f Moves cursor to line #, column # | |
236 | y, x = $3.split(';') | |
237 | x = 1 unless x # ESC[;5H == ESC[1;5H ...etc | |
238 | y = 1 unless y | |
239 | @Out.Cursor(x.to_i-1, y.to_i-1) # origin (0,0) in DOS console | |
240 | when 'H' # ESC[#;#H Moves cursor to line #, column # | |
241 | y, x = $3.split(';') | |
242 | x = 1 unless x # ESC[;5H == ESC[1;5H ...etc | |
243 | y = 1 unless y | |
244 | @Out.Cursor(x.to_i-1, y.to_i-1) # origin (0,0) in DOS console | |
245 | when 's' # ESC[s Saves cursor position for recall later | |
246 | (@x, @y) = @Out.Cursor() | |
247 | when 'u' # ESC[u Return to saved cursor position | |
248 | @Out.Cursor(@x, @y) | |
249 | else | |
250 | STDERR.puts "\e#$2#$3#$4 not implemented" if DEBUG # ESC-code not implemented | |
251 | end | |
252 | else | |
253 | case $4 | |
254 | when 'U' # ESC(U no mapping | |
255 | @conv = nil | |
256 | when 'K' # ESC(K mapping if it exist | |
257 | @Out.OutputCP(OEM) # restore original codepage | |
258 | @conv = 1 | |
259 | when 'X' # ESC(#X codepage **EXPERIMENTAL** | |
260 | @conv = nil | |
261 | @Out.OutputCP($3) | |
262 | else | |
263 | STDERR.puts "\e#$2#$3#$4 not implemented" if DEBUG # ESC-code not implemented | |
264 | end | |
265 | end | |
266 | else | |
267 | @Out.Write(_conv(s)) | |
268 | s='' | |
269 | end | |
270 | end | |
271 | end | |
272 | ||
273 | def _conv(s) | |
274 | if @concealed | |
275 | s.gsub!( /\S/,' ') | |
276 | elsif @conv | |
277 | if EncodeOk | |
278 | from_to(s, cpANSI, cpOEM) | |
279 | elsif @@cp == 'cp1252cp850' # WinLatin1 --> DOSLatin1 | |
280 | s.tr!(" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ","?????????????????????????????ÿ½Ï¾Ýõù¸¦®ªð©îøñýüïæôú÷û§¯¬«ó¨·µ¶ÇÔÒÓÞÖ×ØÑ¥ãàâåëéêíèá ơФ¢äö£ìç") | |
281 | elsif @@cp == 'cp1252cp437' # WinLatin1 --> DOSLatinUS | |
282 | s.tr!(" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", "??????????????????????????????ÿ?????¦®ª???øñý??æ?ú??§¯¬«?¨????????????¥???????????á ?¡?¤¢?ö?£??") | |
283 | elsif @@cp == 'cp1250cp852' # WinLatin2 --> DOSLatin2 | |
284 | s.tr!(" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", | |
285 | "??????????æ?¦??????????ç?§«ÿóôϤ?õù?¸®ªð?½ø?òï???÷¥¯ñ¾èµ¶Æ¬¨Ó·Ö×ÒÑãÕàâüÞéëíÝáê Ç©Ø¡ÔÐäå¢öý £ûìîú" ) | |
286 | elsif @@cp == 'cp1251cp855' # WinCyrillic --> DOSCyrillic | |
287 | s.tr!(" ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", | |
288 | "??????????????????ÿÏ??ý ?®?ð???????ﯡ£ì§©êô¸¾ÇÑÓÕ×Ýâäæ諶¥üöúòîøà ¢ë¬¦¨éó·½ÆÐÒÔÖØáãå窵¤ûõùñí÷Þ") | |
289 | end | |
290 | end | |
291 | return s | |
292 | end | |
293 | ||
294 | end | |
295 | ||
296 | # end print overloading | |
297 | ||
298 | end | |
299 | end | |
300 | end | |
301 | ||
302 | ||
303 | $stdout = Win32::Console::ANSI::IO.new() | |
304 |
0 | # Win32::Console: an object implementing the Win32 API Console functions | |
1 | # Copyright (C) 2003 Gonzalo Garramuno (ggarramuno@aol.com) | |
2 | # | |
3 | # Original Win32API_Console was: | |
4 | # Copyright (C) 2001 Michael L. Semon (mlsemon@sega.net) | |
5 | ||
6 | begin | |
7 | # If Console.so is available, use that. Otherwise, we define | |
8 | # equivalent functions in ruby (a tad slower) | |
9 | # That dll should define everything in an identical interface | |
10 | # to all the ruby code that the rescue below defines. | |
11 | require "Console.so" | |
12 | STDERR.print "Using faster, DLL Console.so\n" if $DEBUG | |
13 | ||
14 | rescue Exception | |
15 | ||
16 | STDERR.print "Using slower, non-DLL Console.rb\n" if $DEBUG | |
17 | ||
18 | module Win32 | |
19 | class Console | |
20 | end | |
21 | end | |
22 | ||
23 | # The WINDOWS constants | |
24 | module Win32::Console::Constants | |
25 | STD_INPUT_HANDLE = 0xFFFFFFF6 | |
26 | STD_OUTPUT_HANDLE = 0xFFFFFFF5 | |
27 | STD_ERROR_HANDLE = 0xFFFFFFF4 | |
28 | INVALID_HANDLE_VALUE = 0xFFFFFFFF | |
29 | GENERIC_READ = 0x80000000 | |
30 | GENERIC_WRITE = 0x40000000 | |
31 | FILE_SHARE_READ = 0x00000001 | |
32 | FILE_SHARE_WRITE = 0x00000002 | |
33 | CONSOLE_TEXTMODE_BUFFER = 0x00000001 | |
34 | ||
35 | FOREGROUND_BLUE = 0x0001 | |
36 | FOREGROUND_GREEN = 0x0002 | |
37 | FOREGROUND_RED = 0x0004 | |
38 | FOREGROUND_INTENSITY = 0x0008 | |
39 | BACKGROUND_BLUE = 0x0010 | |
40 | BACKGROUND_GREEN = 0x0020 | |
41 | BACKGROUND_RED = 0x0040 | |
42 | BACKGROUND_INTENSITY = 0x0080 | |
43 | ||
44 | ENABLE_PROCESSED_INPUT = 0x0001 | |
45 | ENABLE_LINE_INPUT = 0x0002 | |
46 | ENABLE_ECHO_INPUT = 0x0004 | |
47 | ENABLE_WINDOW_INPUT = 0x0008 | |
48 | ENABLE_MOUSE_INPUT = 0x0010 | |
49 | ENABLE_PROCESSED_OUTPUT = 0x0001 | |
50 | ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002 | |
51 | ||
52 | KEY_EVENT = 0x0001 | |
53 | MOUSE_EVENT = 0x0002 | |
54 | WINDOW_BUFFER_SIZE_EVENT = 0x0004 | |
55 | MENU_EVENT = 0x0008 | |
56 | FOCUS_EVENT = 0x0010 | |
57 | ||
58 | CAPSLOCK_ON = 0x0080 | |
59 | ENHANCED_KEY = 0x0100 | |
60 | NUMLOCK_ON = 0x0020 | |
61 | SHIFT_PRESSED = 0x0010 | |
62 | LEFT_CTRL_PRESSED = 0x0008 | |
63 | RIGHT_CTRL_PRESSED = 0x0004 | |
64 | LEFT_ALT_PRESSED = 0x0002 | |
65 | RIGHT_ALT_PRESSED = 0x0001 | |
66 | SCROLLLOCK_ON = 0x0040 | |
67 | ||
68 | MOUSE_WHEELED = 0x0004 | |
69 | DOUBLE_CLICK = 0x0002 | |
70 | MOUSE_MOVED = 0x0001 | |
71 | ||
72 | FROM_LEFT_1ST_BUTTON_PRESSED = 0x0001 | |
73 | FROM_LEFT_2ND_BUTTON_PRESSED = 0x0004 | |
74 | FROM_LEFT_3RD_BUTTON_PRESSED = 0x0008 | |
75 | FROM_LEFT_4TH_BUTTON_PRESSED = 0x0010 | |
76 | RIGHTMOST_BUTTON_PRESSED = 0x0002 | |
77 | ||
78 | CTRL_C_EVENT = 0x0000 | |
79 | CTRL_BREAK_EVENT = 0x0001 | |
80 | CTRL_CLOSE_EVENT = 0x0002 | |
81 | CTRL_LOGOFF_EVENT = 0x0005 | |
82 | CTRL_SHUTDOWN_EVENT = 0x0006 | |
83 | end | |
84 | ||
85 | # The actual api to access windows functions | |
86 | class Win32::Console::API | |
87 | require 'Win32API' | |
88 | ||
89 | private | |
90 | # This is a class-wide cache that will hold Win32API objects. As each | |
91 | # Win32API object is about 920 bytes, I didn't want to initialize all of | |
92 | # them at one time. That would waste about 42 kB for this object because | |
93 | # it has 47 functions. However, to not have a cache at all would reduce | |
94 | # the speed of this object by 164%. | |
95 | @@m_AllocConsole = nil | |
96 | @@m_CreateConsoleScreenBuffer = nil | |
97 | @@m_FillConsoleOutputAttribute = nil | |
98 | @@m_FillConsoleOutputCharacter = nil | |
99 | @@m_FlushConsoleInputBuffer = nil | |
100 | @@m_FreeConsole = nil | |
101 | @@m_GenerateConsoleCtrlEvent = nil | |
102 | @@m_GetConsoleCP = nil | |
103 | @@m_GetConsoleCursorInfo = nil | |
104 | @@m_GetConsoleMode = nil | |
105 | @@m_GetConsoleOutputCP = nil | |
106 | @@m_GetConsoleScreenBufferInfo = nil | |
107 | @@m_GetConsoleTitle = nil | |
108 | @@m_GetConsoleWindow = nil | |
109 | @@m_GetLargestConsoleWindowSize = nil | |
110 | @@m_GetNumberOfConsoleInputEvents = nil | |
111 | @@m_GetNumberOfConsoleMouseButtons = nil | |
112 | @@m_GetStdHandle = nil | |
113 | @@m_PeekConsoleInput = nil | |
114 | @@m_ReadConsole = nil | |
115 | @@m_ReadConsoleInput = nil | |
116 | @@m_ReadConsoleOutput = nil | |
117 | @@m_ReadConsoleOutputAttribute = nil | |
118 | @@m_ReadConsoleOutputCharacter = nil | |
119 | @@m_ScrollConsoleScreenBuffer = nil | |
120 | @@m_SetConsoleActiveScreenBuffer = nil | |
121 | @@m_SetConsoleCP = nil | |
122 | @@m_SetConsoleCursorInfo = nil | |
123 | @@m_SetConsoleCursorPosition = nil | |
124 | @@m_SetConsoleMode = nil | |
125 | @@m_SetConsoleOutputCP = nil | |
126 | @@m_SetConsoleScreenBufferSize = nil | |
127 | @@m_SetConsoleTextAttribute = nil | |
128 | @@m_SetConsoleTitle = nil | |
129 | @@m_SetConsoleWindowInfo = nil | |
130 | @@m_SetStdHandle = nil | |
131 | @@m_WriteConsole = nil | |
132 | @@m_WriteConsoleInput = nil | |
133 | @@m_WriteConsoleOutput = nil | |
134 | @@m_WriteConsoleOutputAttribute = nil | |
135 | @@m_WriteConsoleOutputCharacter = nil | |
136 | ||
137 | public | |
138 | ||
139 | class << self | |
140 | ||
141 | ||
142 | def constant(t) | |
143 | begin | |
144 | eval "return Win32::Console::Constants::#{t}" | |
145 | rescue | |
146 | return nil | |
147 | end | |
148 | end | |
149 | ||
150 | ||
151 | def AllocConsole() | |
152 | if @@m_AllocConsole == nil | |
153 | @@m_AllocConsole = Win32API.new( "kernel32", "AllocConsole", | |
154 | [], 'l' ) | |
155 | end | |
156 | @@m_AllocConsole.call() | |
157 | end | |
158 | ||
159 | def CreateConsoleScreenBuffer( dwDesiredAccess, dwShareMode, dwFlags ) | |
160 | if @@m_CreateConsoleScreenBuffer == nil | |
161 | @@m_CreateConsoleScreenBuffer = Win32API.new( "kernel32", "CreateConsoleScreenBuffer", ['l', 'l', 'p', 'l', 'p'], 'l' ) | |
162 | end | |
163 | @@m_CreateConsoleScreenBuffer.call( dwDesiredAccess, dwShareMode, | |
164 | nil, dwFlags, nil ) | |
165 | end | |
166 | ||
167 | ||
168 | ||
169 | def FillConsoleOutputAttribute( hConsoleOutput, wAttribute, nLength, | |
170 | col, row ) | |
171 | if @@m_FillConsoleOutputAttribute == nil | |
172 | @@m_FillConsoleOutputAttribute = Win32API.new( "kernel32", "FillConsoleOutputAttribute", ['l', 'i', 'l', 'l', 'p'], 'l' ) | |
173 | end | |
174 | dwWriteCoord = (row << 16) + col | |
175 | lpNumberOfAttrsWritten = ' ' * 4 | |
176 | @@m_FillConsoleOutputAttribute.call( hConsoleOutput, wAttribute, | |
177 | nLength, dwWriteCoord, | |
178 | lpNumberOfAttrsWritten ) | |
179 | return lpNumberOfAttrsWritten.unpack('L') | |
180 | end | |
181 | ||
182 | ||
183 | ||
184 | def FillConsoleOutputCharacter( hConsoleOutput, cCharacter, nLength, | |
185 | col, row ) | |
186 | if @@m_FillConsoleOutputCharacter == nil | |
187 | @@m_FillConsoleOutputCharacter = Win32API.new( "kernel32", "FillConsoleOutputCharacter", ['l', 'i', 'l', 'l', 'p'], 'l' ) | |
188 | end | |
189 | dwWriteCoord = (row << 16) + col | |
190 | lpNumberOfAttrsWritten = ' ' * 4 | |
191 | @@m_FillConsoleOutputCharacter.call( hConsoleOutput, cCharacter, | |
192 | nLength, dwWriteCoord, | |
193 | lpNumberOfAttrsWritten ) | |
194 | return lpNumberOfAttrsWritten.unpack('L') | |
195 | end | |
196 | ||
197 | ||
198 | def FlushConsoleInputBuffer( hConsoleInput ) | |
199 | if @@m_FlushConsoleInputBuffer == nil | |
200 | @@m_FlushConsoleInputBuffer = Win32API.new( "kernel32", | |
201 | "FillConsoleInputBuffer", | |
202 | ['l'], 'l' ) | |
203 | end | |
204 | @@m_FlushConsoleInputBuffer.call( hConsoleInput ) | |
205 | end | |
206 | ||
207 | ||
208 | def FreeConsole() | |
209 | if @@m_FreeConsole == nil | |
210 | @@m_FreeConsole = Win32API.new( "kernel32", "FreeConsole", [], 'l' ) | |
211 | end | |
212 | @@m_FreeConsole.call() | |
213 | end | |
214 | ||
215 | ||
216 | def GenerateConsoleCtrlEvent( dwCtrlEvent, dwProcessGroupId ) | |
217 | if @@m_GenerateConsoleCtrlEvent == nil | |
218 | @@m_GenerateConsoleCtrlEvent = Win32API.new( "kernel32", "GenerateConsoleCtrlEvent", ['l', 'l'], 'l' ) | |
219 | end | |
220 | @@m_GenerateConsoleCtrlEvent.call( dwCtrlEvent, dwProcessGroupId ) | |
221 | end | |
222 | ||
223 | def GetConsoleCP() | |
224 | if @@m_GetConsoleCP == nil | |
225 | @@m_GetConsoleCP = Win32API.new( "kernel32", "GetConsoleCP", | |
226 | [], 'l' ) | |
227 | end | |
228 | @@m_GetConsoleCP.call() | |
229 | end | |
230 | ||
231 | def GetConsoleCursorInfo( hConsoleOutput ) | |
232 | if @@m_GetConsoleCursorInfo == nil | |
233 | @@m_GetConsoleCursorInfo = Win32API.new( "kernel32", | |
234 | "GetConsoleCursorInfo", | |
235 | ['l', 'p'], 'l' ) | |
236 | end | |
237 | lpConsoleCursorInfo = ' ' * 8 | |
238 | @@m_GetConsoleCursorInfo.call( hConsoleOutput, lpConsoleCursorInfo ) | |
239 | return lpConsoleCursorInfo.unpack('LL') | |
240 | end | |
241 | ||
242 | def GetConsoleMode( hConsoleHandle ) | |
243 | if @@m_GetConsoleMode == nil | |
244 | @@m_GetConsoleMode = Win32API.new( "kernel32", "GetConsoleMode", | |
245 | ['l', 'p'], 'l' ) | |
246 | end | |
247 | lpMode = ' ' * 4 | |
248 | @@m_GetConsoleMode.call( hConsoleHandle, lpMode ) | |
249 | return lpMode.unpack('L') | |
250 | end | |
251 | ||
252 | def GetConsoleOutputCP() | |
253 | if @@m_GetConsoleOutputCP == nil | |
254 | @@m_GetConsoleOutputCP = Win32API.new( "kernel32", | |
255 | "GetConsoleOutputCP", [], 'l' ) | |
256 | end | |
257 | @@m_GetConsoleOutputCP.call() | |
258 | end | |
259 | ||
260 | def GetConsoleScreenBufferInfo( hConsoleOutput ) | |
261 | if @@m_GetConsoleScreenBufferInfo == nil | |
262 | @@m_GetConsoleScreenBufferInfo = Win32API.new( "kernel32", "GetConsoleScreenBufferInfo", ['l', 'p'], 'l' ) | |
263 | end | |
264 | lpBuffer = ' ' * 22 | |
265 | @@m_GetConsoleScreenBufferInfo.call( hConsoleOutput, lpBuffer ) | |
266 | return lpBuffer.unpack('SSSSSssssSS') | |
267 | end | |
268 | ||
269 | def GetConsoleTitle() | |
270 | if @@m_GetConsoleTitle == nil | |
271 | @@m_GetConsoleTitle = Win32API.new( "kernel32", "GetConsoleTitle", | |
272 | ['p', 'l'], 'l' ) | |
273 | end | |
274 | nSize = 120 | |
275 | lpConsoleTitle = ' ' * nSize | |
276 | @@m_GetConsoleTitle.call( lpConsoleTitle, nSize ) | |
277 | return lpConsoleTitle.strip | |
278 | end | |
279 | ||
280 | def GetConsoleWindow() | |
281 | if @@m_GetConsoleWindow == nil | |
282 | @@m_GetConsoleWindow = Win32API.new( "kernel32", "GetConsoleWindow", | |
283 | [], 'l' ) | |
284 | end | |
285 | @@m_GetConsoleWindow.call() | |
286 | end | |
287 | ||
288 | def GetLargestConsoleWindowSize( hConsoleOutput ) | |
289 | if @@m_GetLargestConsoleWindowSize == nil | |
290 | @@m_GetLargestConsoleWindowSize = Win32API.new( "kernel32", "GetLargestConsoleWindowSize", ['l'], 'l' ) | |
291 | end | |
292 | coord = @@m_GetLargestConsoleWindowSize.call( hConsoleOutput ) | |
293 | x = coord >> 16 | |
294 | y = coord & 0x0000ffff | |
295 | return [x,y] | |
296 | end | |
297 | ||
298 | def GetNumberOfConsoleInputEvents( hConsoleInput ) | |
299 | if @@m_GetNumberOfConsoleInputEvents == nil | |
300 | @@m_GetNumberOfConsoleInputEvents = Win32API.new( "kernel32", "GetNumberOfConsoleInputEvents", ['l', 'p'], 'l' ) | |
301 | end | |
302 | lpcNumberOfEvents = 0 | |
303 | @@m_GetNumberOfConsoleInputEvents.call( hConsoleInput, | |
304 | lpcNumberOfEvents ) | |
305 | return lpcNumberOfEvents | |
306 | end | |
307 | ||
308 | def GetNumberOfConsoleMouseButtons( ) | |
309 | if @@m_GetNumberOfConsoleMouseButtons == nil | |
310 | @@m_GetNumberOfConsoleMouseButtons = Win32API.new( "kernel32", "GetNumberOfConsoleMouseButtons", ['p'], 'l' ) | |
311 | end | |
312 | lpNumberOfMouseButtons = 0 | |
313 | @@m_GetNumberOfConsoleMouseButtons.call( lpNumberOfMouseButtons ) | |
314 | return lpNumberOfMouseButtons | |
315 | end | |
316 | ||
317 | def GetStdHandle( nStdHandle ) | |
318 | if @@m_GetStdHandle == nil | |
319 | @@m_GetStdHandle = Win32API.new( "kernel32", "GetStdHandle", | |
320 | ['l'], 'l' ) | |
321 | end | |
322 | @@m_GetStdHandle.call( nStdHandle ) | |
323 | end | |
324 | ||
325 | # <<HandlerRoutine>> : This is not an actual API function, just a concept description in the SDK. | |
326 | ||
327 | def PeekConsoleInput( hConsoleInput ) | |
328 | if @@m_PeekConsoleInput == nil | |
329 | @@m_PeekConsoleInput = Win32API.new( "kernel32", "PeekConsoleInput", | |
330 | ['l', 'p', 'l', 'p'], 'l' ) | |
331 | end | |
332 | lpNumberOfEventsRead = ' ' * 4 | |
333 | lpBuffer = ' ' * 20 | |
334 | nLength = 20 | |
335 | @@m_PeekConsoleInput.call( hConsoleInput, lpBuffer, nLength, | |
336 | lpNumberOfEventsRead ) | |
337 | type = lpBuffer.unpack('s')[0] | |
338 | ||
339 | case type | |
340 | when KEY_EVENT | |
341 | return lpBuffer.unpack('sSSSSCS') | |
342 | when MOUSE_EVENT | |
343 | return lpBuffer.unpack('sSSSS') | |
344 | when WINDOW_BUFFER_SIZE_EVENT | |
345 | return lpBuffer.unpack('sS') | |
346 | when MENU_EVENT | |
347 | return lpBuffer.unpack('sS') | |
348 | when FOCUS_EVENT | |
349 | return lpBuffer.unpack('sS') | |
350 | else | |
351 | return [] | |
352 | end | |
353 | end | |
354 | ||
355 | def ReadConsole( hConsoleInput, lpBuffer, nNumberOfCharsToRead ) | |
356 | if @@m_ReadConsole == nil | |
357 | @@m_ReadConsole = Win32API.new( "kernel32", "ReadConsole", | |
358 | ['l', 'p', 'l', 'p', 'p'], 'l' ) | |
359 | end | |
360 | lpBuffer = ' ' * nNumberOfCharsToRead unless lpBuffer | |
361 | lpNumberOfCharsRead = ' ' * 4 | |
362 | lpReserved = ' ' * 4 | |
363 | @@m_ReadConsole.call( hConsoleInput, lpBuffer, nNumberOfCharsToRead, | |
364 | lpNumberOfCharsRead, lpReserved ) | |
365 | return lpNumberOfCharsRead.unpack('L') | |
366 | end | |
367 | ||
368 | def ReadConsoleInput( hConsoleInput ) | |
369 | if @@m_ReadConsoleInput == nil | |
370 | @@m_ReadConsoleInput = Win32API.new( "kernel32", "ReadConsoleInput", | |
371 | ['l', 'p', 'l', 'p'], 'l' ) | |
372 | end | |
373 | lpNumberOfEventsRead = ' ' * 4 | |
374 | lpBuffer = ' ' * 20 | |
375 | nLength = 20 | |
376 | @@m_ReadConsoleInput.call( hConsoleInput, lpBuffer, nLength, | |
377 | lpNumberOfEventsRead ) | |
378 | type = lpBuffer.unpack('s')[0] | |
379 | ||
380 | case type | |
381 | when KEY_EVENT | |
382 | return lpBuffer.unpack('sSSSSCS') | |
383 | when MOUSE_EVENT | |
384 | return lpBuffer.unpack('sSSSS') | |
385 | when WINDOW_BUFFER_SIZE_EVENT | |
386 | return lpBuffer.unpack('sS') | |
387 | when MENU_EVENT | |
388 | return lpBuffer.unpack('sS') | |
389 | when FOCUS_EVENT | |
390 | return lpBuffer.unpack('sS') | |
391 | else | |
392 | return [] | |
393 | end | |
394 | end | |
395 | ||
396 | def ReadConsoleOutput( hConsoleOutput, lpBuffer, cols, rows, | |
397 | bufx, bufy, left, top, right, bottom ) | |
398 | if @@m_ReadConsoleOutput == nil | |
399 | @@m_ReadConsoleOutput = Win32API.new( "kernel32", | |
400 | "ReadConsoleOutput", | |
401 | ['l', 'p', 'l', 'l', 'p'], 'l' ) | |
402 | end | |
403 | dwBufferSize = cols * rows * 4 | |
404 | lpBuffer = ' ' * dwBufferSize | |
405 | dwBufferCoord = (bufy << 16) + bufx | |
406 | lpReadRegion = [ left, top, right, bottom ].pack('ssss') | |
407 | @@m_ReadConsoleOutput.call( hConsoleOutput, lpBuffer, dwBufferSize, | |
408 | dwBufferCoord, lpReadRegion ) | |
409 | end | |
410 | ||
411 | def ReadConsoleOutputAttribute( hConsoleOutput, nLength, col, row ) | |
412 | if @@m_ReadConsoleOutputAttribute == nil | |
413 | @@m_ReadConsoleOutputAttribute = Win32API.new( "kernel32", "ReadConsoleOutputAttribute", ['l', 'p', 'l', 'l', 'p'], 'l' ) | |
414 | end | |
415 | lpAttribute = ' ' * nLength | |
416 | dwReadCoord = (row << 16) + col | |
417 | lpNumberOfAttrsRead = ' ' * 4 | |
418 | @@m_ReadConsoleOutputAttribute.call( hConsoleOutput, lpAttribute, | |
419 | nLength, dwReadCoord, | |
420 | lpNumberOfAttrsRead ) | |
421 | return lpAttribute | |
422 | end | |
423 | ||
424 | def ReadConsoleOutputCharacter( hConsoleOutput, lpCharacter, nLength, | |
425 | col, row ) | |
426 | if @@m_ReadConsoleOutputCharacter == nil | |
427 | @@m_ReadConsoleOutputCharacter = Win32API.new( "kernel32", "ReadConsoleOutputCharacter", ['l', 'p', 'l', 'l', 'p'], 'l' ) | |
428 | end | |
429 | dwReadCoord = (row << 16) + col | |
430 | lpNumberOfCharsRead = ' ' * 4 | |
431 | @@m_ReadConsoleOutputCharacter.call( hConsoleOutput, lpCharacter, | |
432 | nLength, dwReadCoord, | |
433 | lpNumberOfCharsRead ) | |
434 | return lpNumberOfCharsRead.unpack('L') | |
435 | end | |
436 | ||
437 | def ScrollConsoleScreenBuffer( hConsoleOutput, | |
438 | left1, top1, right1, bottom1, | |
439 | col, row, char, attr, | |
440 | left2, top2, right2, bottom2 ) | |
441 | if @@m_ScrollConsoleScreenBuffer == nil | |
442 | @@m_ScrollConsoleScreenBuffer = Win32API.new( "kernel32", "ScrollConsoleScreenBuffer", ['l', 'p', 'p', 'l', 'p'], 'l' ) | |
443 | end | |
444 | lpScrollRectangle = [left1, top1, right1, bottom1].pack('ssss') | |
445 | lpClipRectangle = [left2, top2, right2, bottom2].pack('ssss') | |
446 | dwDestinationOrigin = (row << 16) + col | |
447 | lpFill = [char, attr].pack('ss') | |
448 | @@m_ScrollConsoleScreenBuffer.call( hConsoleOutput, lpScrollRectangle, | |
449 | lpClipRectangle, | |
450 | dwDestinationOrigin, lpFill ) | |
451 | end | |
452 | ||
453 | def SetConsoleActiveScreenBuffer( hConsoleOutput ) | |
454 | if @@m_SetConsoleActiveScreenBuffer == nil | |
455 | @@m_SetConsoleActiveScreenBuffer = Win32API.new( "kernel32", "SetConsoleActiveScreenBuffer", ['l'], 'l' ) | |
456 | end | |
457 | @@m_SetConsoleActiveScreenBuffer.call( hConsoleOutput ) | |
458 | end | |
459 | ||
460 | # <<SetConsoleCtrlHandler>>: Will probably not be implemented. | |
461 | ||
462 | def SetConsoleCP( wCodePageID ) | |
463 | if @@m_SetConsoleCP == nil | |
464 | @@m_SetConsoleCP = Win32API.new( "kernel32", "SetConsoleCP", | |
465 | ['l'], 'l' ) | |
466 | end | |
467 | @@m_SetConsoleCP.call( wCodePageID ) | |
468 | end | |
469 | ||
470 | def SetConsoleCursorInfo( hConsoleOutput, col, row ) | |
471 | if @@m_SetConsoleCursorInfo == nil | |
472 | @@m_SetConsoleCursorInfo = Win32API.new( "kernel32", | |
473 | "SetConsoleCursorInfo", | |
474 | ['l', 'p'], 'l' ) | |
475 | end | |
476 | lpConsoleCursorInfo = [size,visi].pack('LL') | |
477 | @@m_SetConsoleCursorInfo.call( hConsoleOutput, lpConsoleCursorInfo ) | |
478 | end | |
479 | ||
480 | def SetConsoleCursorPosition( hConsoleOutput, col, row ) | |
481 | if @@m_SetConsoleCursorPosition == nil | |
482 | @@m_SetConsoleCursorPosition = Win32API.new( "kernel32", "SetConsoleCursorPosition", ['l', 'p'], 'l' ) | |
483 | end | |
484 | dwCursorPosition = (row << 16) + col | |
485 | @@m_SetConsoleCursorPosition.call( hConsoleOutput, dwCursorPosition ) | |
486 | end | |
487 | ||
488 | def SetConsoleMode( hConsoleHandle, lpMode ) | |
489 | if @@m_SetConsoleMode == nil | |
490 | @@m_SetConsoleMode = Win32API.new( "kernel32", "SetConsoleMode", | |
491 | ['l', 'p'], 'l' ) | |
492 | end | |
493 | @@m_SetConsoleMode.call( hConsoleHandle, lpMode ) | |
494 | end | |
495 | ||
496 | def SetConsoleOutputCP( wCodePageID ) | |
497 | if @@m_SetConsoleOutputCP == nil | |
498 | @@m_SetConsoleOutputCP = Win32API.new( "kernel32", | |
499 | "GetConsoleOutputCP", | |
500 | ['l'], 'l' ) | |
501 | end | |
502 | @@m_SetConsoleOutputCP.call( wCodePageID ) | |
503 | end | |
504 | ||
505 | def SetConsoleScreenBufferSize( hConsoleOutput, col, row ) | |
506 | if @@m_SetConsoleScreenBufferSize == nil | |
507 | @@m_SetConsoleScreenBufferSize = Win32API.new( "kernel32", "SetConsoleScreenBufferSize", ['l', 'l'], 'l' ) | |
508 | end | |
509 | dwSize = (row << 16) + col | |
510 | @@m_SetConsoleScreenBufferSize.call( hConsoleOutput, dwSize ) | |
511 | end | |
512 | ||
513 | def SetConsoleTextAttribute( hConsoleOutput, wAttributes ) | |
514 | if @@m_SetConsoleTextAttribute == nil | |
515 | @@m_SetConsoleTextAttribute = Win32API.new( "kernel32", "SetConsoleTextAttribute", ['l', 'i'], 'l' ) | |
516 | end | |
517 | @@m_SetConsoleTextAttribute.call( hConsoleOutput, wAttributes ) | |
518 | end | |
519 | ||
520 | def SetConsoleTitle( lpConsoleTitle ) | |
521 | if @@m_SetConsoleTitle == nil | |
522 | @@m_SetConsoleTitle = Win32API.new( "kernel32", "SetConsoleTitle", | |
523 | ['p'], 'l' ) | |
524 | end | |
525 | @@m_SetConsoleTitle.call( lpConsoleTitle ) | |
526 | end | |
527 | ||
528 | def SetConsoleWindowInfo( hConsoleOutput, bAbsolute, | |
529 | left, top, right, bottom ) | |
530 | if @@m_SetConsoleWindowInfo == nil | |
531 | @@m_SetConsoleWindowInfo = Win32API.new( "kernel32", | |
532 | "SetConsoleWindowInfo", | |
533 | ['l', 'l', 'p'], 'l' ) | |
534 | end | |
535 | lpConsoleWindow = [ left, top, right, bottom ].pack('ssss') | |
536 | @@m_SetConsoleWindowInfo.call( hConsoleOutput, bAbsolute, | |
537 | lpConsoleWindow ) | |
538 | end | |
539 | ||
540 | def SetStdHandle( nStdHandle, hHandle ) | |
541 | if @@m_SetStdHandle == nil | |
542 | @@m_SetStdHandle = Win32API.new( "kernel32", "SetStdHandle", | |
543 | ['l', 'l'], 'l' ) | |
544 | end | |
545 | @@m_SetStdHandle.call( nStdHandle, hHandle ) | |
546 | end | |
547 | ||
548 | def WriteConsole( hConsoleOutput, lpBuffer ) | |
549 | if @@m_WriteConsole == nil | |
550 | @@m_WriteConsole = Win32API.new( "kernel32", "WriteConsole", | |
551 | ['l', 'p', 'l', 'p', 'p'], 'l' ) | |
552 | end | |
553 | nNumberOfCharsToWrite = lpBuffer.length() | |
554 | lpNumberOfCharsWritten = ' ' * 4 | |
555 | lpReserved = ' ' * 4 | |
556 | @@m_WriteConsole.call( hConsoleOutput, lpBuffer, nNumberOfCharsToWrite, | |
557 | lpNumberOfCharsWritten, lpReserved ) | |
558 | return lpNumberOfCharsWritten | |
559 | end | |
560 | ||
561 | def WriteConsoleInput( hConsoleInput, lpBuffer ) | |
562 | if @@m_WriteConsoleInput == nil | |
563 | @@m_WriteConsoleInput = Win32API.new( "kernel32", "WriteConsoleInput", ['l', 'p', 'l', 'p'], 'l' ) | |
564 | end | |
565 | @@m_WriteConsoleInput.call( hConsoleInput, lpBuffer, nLength, | |
566 | lpNumberOfEventsWritten ) | |
567 | end | |
568 | ||
569 | # @@ Todo: Test this | |
570 | def WriteConsoleOutput( hConsoleOutput, buffer, cols, rows, | |
571 | bufx, bufy, left, top, right, bottom ) | |
572 | if @@m_WriteConsoleOutput == nil | |
573 | @@m_WriteConsoleOutput = Win32API.new( "kernel32", "WriteConsoleOutput", ['l', 'p', 'l', 'l', 'p'], 'l' ) | |
574 | end | |
575 | lpBuffer = buffer.flatten.pack('ss' * buffer.length() * 2) | |
576 | dwBufferSize = (buffer.length() << 16) + 2 | |
577 | dwBufferCoord = (row << 16) + col | |
578 | lpWriteRegion = [ left, top, right, bottom ].pack('ssss') | |
579 | @@m_WriteConsoleOutput.call( hConsoleOutput, lpBuffer, dwBufferSize, | |
580 | dwBufferCoord, lpWriteRegion ) | |
581 | end | |
582 | ||
583 | def WriteConsoleOutputAttribute( hConsoleOutput, lpAttribute, col, row ) | |
584 | if @@m_WriteConsoleOutputAttribute == nil | |
585 | @@m_WriteConsoleOutputAttribute = Win32API.new( "kernel32", "WriteConsoleOutputAttribute", ['l', 'p', 'l', 'l', 'p'], 'l' ) | |
586 | end | |
587 | nLength = lpAttribute.length() | |
588 | dwWriteCoord = (row << 16) + col | |
589 | lpNumberOfAttrsWritten = ' ' * 4 | |
590 | @@m_WriteConsoleOutputAttribute.call( hConsoleOutput, lpAttribute, | |
591 | nLength, dwWriteCoord, | |
592 | lpNumberOfAttrsWritten ) | |
593 | return lpNumberOfAttrsWritten.unpack('L') | |
594 | end | |
595 | ||
596 | def WriteConsoleOutputCharacter( hConsoleOutput, lpCharacter, col, row ) | |
597 | if @@m_WriteConsoleOutputCharacter == nil | |
598 | @@m_WriteConsoleOutputCharacter = Win32API.new( "kernel32", "WriteConsoleOutputCharacter", ['l', 'p', 'l', 'l', 'p'], 'l' ) | |
599 | end | |
600 | nLength = lpCharacter.length() | |
601 | dwWriteCoord = (row << 16) + col | |
602 | lpNumberOfCharsWritten = ' ' * 4 | |
603 | @@m_WriteConsoleOutputCharacter.call( hConsoleOutput, lpCharacter, | |
604 | nLength, dwWriteCoord, | |
605 | lpNumberOfCharsWritten ) | |
606 | return lpNumberOfCharsWritten.unpack('L') | |
607 | end | |
608 | ||
609 | end | |
610 | end | |
611 | ||
612 | end # rescue | |
613 | ||
614 | ||
615 | ||
616 | module Win32 | |
617 | class Console | |
618 | ||
619 | VERSION = '1.0' | |
620 | ||
621 | include Win32::Console::Constants | |
622 | ||
623 | def initialize( t = nil ) | |
624 | if t and ( t == STD_INPUT_HANDLE or t == STD_OUTPUT_HANDLE or | |
625 | t == STD_ERROR_HANDLE ) | |
626 | @handle = API.GetStdHandle( t ) | |
627 | else | |
628 | param1 = GENERIC_READ | GENERIC_WRITE | |
629 | param2 = FILE_SHARE_READ | FILE_SHARE_WRITE | |
630 | @handle = API.CreateConsoleScreenBuffer( param1, param2, | |
631 | CONSOLE_TEXTMODE_BUFFER ) | |
632 | end | |
633 | end | |
634 | ||
635 | ||
636 | def Display | |
637 | return API.SetConsoleActiveScreenBuffer(@handle) | |
638 | end | |
639 | ||
640 | def Select(type) | |
641 | return API.SetStdHandle(type,@handle) | |
642 | end | |
643 | ||
644 | def Title(title = nil) | |
645 | if title | |
646 | return API.SetConsoleTitle(title) | |
647 | else | |
648 | return API.GetConsoleTitle() | |
649 | end | |
650 | end | |
651 | ||
652 | def WriteChar(s, col, row) | |
653 | API.WriteConsoleOutputCharacter( @handle, s, col, row ) | |
654 | end | |
655 | ||
656 | def ReadChar(size, col, row) | |
657 | buffer = ' ' * size | |
658 | if API.ReadConsoleOutputCharacter( @handle, buffer, size, col, row ) | |
659 | return buffer | |
660 | else | |
661 | return nil | |
662 | end | |
663 | end | |
664 | ||
665 | def WriteAttr(attr, col, row) | |
666 | API.WriteConsoleOutputAttribute( @handle, attr, col, row ) | |
667 | end | |
668 | ||
669 | def ReadAttr(size, col, row) | |
670 | x = API.ReadConsoleOutputAttribute( @handle, size, col, row ) | |
671 | return x.unpack('c'*size) | |
672 | end | |
673 | ||
674 | ||
675 | def Cursor(*t) | |
676 | col, row, size, visi = t | |
677 | if col | |
678 | row = -1 if !row | |
679 | if col < 0 or row < 0 | |
680 | curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle) | |
681 | col = curr_col if col < 0 | |
682 | row = curr_row if row < 0 | |
683 | end | |
684 | API.SetConsoleCursorPosition( @handle, col, row ) | |
685 | if size and visi | |
686 | curr_size, curr_visi = API.GetConsoleCursorInfo( @handle ) | |
687 | size = curr_size if size < 0 | |
688 | visi = curr_visi if visi < 0 | |
689 | size = 1 if size < 1 | |
690 | size = 99 if size > 99 | |
691 | API.SetConsoleCursorInfo( @handle, size, visi ) | |
692 | end | |
693 | else | |
694 | d, d, curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle) | |
695 | curr_size, curr_visi = API.GetConsoleCursorInfo( @handle ) | |
696 | return [ curr_col, curr_row, curr_size, curr_visi ] | |
697 | end | |
698 | end | |
699 | ||
700 | def Write(s) | |
701 | API.WriteConsole( @handle, s ) | |
702 | end | |
703 | ||
704 | def ReadRect( left, top, right, bottom ) | |
705 | col = right - left + 1 | |
706 | row = bottom - top + 1 | |
707 | size = col * row | |
708 | buffer = ' ' * size * 4 | |
709 | if API.ReadConsoleOutput( @handle, buffer, col, row, 0, 0, | |
710 | left, top, right, bottom ) | |
711 | #return buffer.unpack('US'*size) # for unicode | |
712 | return buffer.unpack('axS'*size) # for ascii | |
713 | else | |
714 | return nil | |
715 | end | |
716 | end | |
717 | ||
718 | def WriteRect( buffer, left, top, right, bottom ) | |
719 | col = right - left + 1 | |
720 | row = bottom - top + 1 | |
721 | API.WriteConsoleOutput( @handle, buffer, col, row, 0, 0, | |
722 | left, top, right, bottom ) | |
723 | end | |
724 | ||
725 | ||
726 | ||
727 | def Scroll( left1, top1, right1, bottom1, | |
728 | col, row, char, attr, | |
729 | left2, top2, right2, bottom2 ) | |
730 | API.ScrollConsoleScreenBuffer(@handle, left1, top1, right1, bottom1, | |
731 | col, row, char, attr, | |
732 | left2, top2, right2, bottom2) | |
733 | end | |
734 | ||
735 | ||
736 | def MaxWindow(flag = nil) | |
737 | if !flag | |
738 | info = API.GetConsoleScreenBufferInfo(@handle) | |
739 | return info[9], info[10] | |
740 | else | |
741 | return API.GetLargestConsoleWindowSize(@handle) | |
742 | end | |
743 | end | |
744 | ||
745 | ||
746 | def Info() | |
747 | return API.GetConsoleScreenBufferInfo( @handle ) | |
748 | end | |
749 | ||
750 | ||
751 | def GetEvents() | |
752 | return API.GetNumberOfConsoleInputEvents(@handle) | |
753 | end | |
754 | ||
755 | ||
756 | def Flush() | |
757 | return API.FlushConsoleInputBuffer(@handle) | |
758 | end | |
759 | ||
760 | def InputChar(number = nil) | |
761 | number = 1 unless number | |
762 | buffer = ' ' * number | |
763 | if API.ReadConsole(@handle, buffer, number) == number | |
764 | return buffer | |
765 | else | |
766 | return nil | |
767 | end | |
768 | end | |
769 | ||
770 | ||
771 | def Input() | |
772 | API.ReadConsoleInput(@handle) | |
773 | end | |
774 | ||
775 | ||
776 | def PeekInput() | |
777 | API.PeekConsoleInput(@handle) | |
778 | end | |
779 | ||
780 | ||
781 | def Mode(mode = nil) | |
782 | if mode | |
783 | mode = mode.pack('L') if mode === Array | |
784 | API.SetConsoleMode(@handle, mode) | |
785 | else | |
786 | return API.GetConsoleMode(@handle) | |
787 | end | |
788 | end | |
789 | ||
790 | def WriteInput(*t) | |
791 | API.WriteConsoleInput(@handle, *t) | |
792 | end | |
793 | ||
794 | def Attr(*attr) | |
795 | if attr.size > 0 | |
796 | API.SetConsoleTextAttribute( @handle, attr[0] ) | |
797 | else | |
798 | info = API.GetConsoleScreenBufferInfo( @handle ) | |
799 | return info[4] | |
800 | end | |
801 | end | |
802 | ||
803 | ||
804 | def Size(*t) | |
805 | if t.size == 0 | |
806 | col, row = API.GetConsoleScreenBufferInfo(@handle ) | |
807 | return [col, row] | |
808 | else | |
809 | row = -1 if !t[1] | |
810 | col = -1 if !t[0] | |
811 | if col < 0 or row < 0 | |
812 | curr_col, curr_row = Size() | |
813 | col = curr_col if col < 0 | |
814 | row = curr_row if row < 0 | |
815 | end | |
816 | API.SetConsoleScreenBufferSize(@handle, row, col) | |
817 | end | |
818 | end | |
819 | ||
820 | def Window(*t) | |
821 | if t.size != 5 | |
822 | info = API.GetConsoleScreenBufferInfo( @handle ) | |
823 | return info[5..8] | |
824 | else | |
825 | API.SetConsoleWindowInfo(@handle, t[0], t[1], t[2], t[3], t[4]) | |
826 | end | |
827 | end | |
828 | ||
829 | def FillAttr(attr, number = 1, col = -1, row = -1) | |
830 | if col < 0 or row < 0 | |
831 | d, d, curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle) | |
832 | col = curr_col if col < 0 | |
833 | row = curr_row if row < 0 | |
834 | end | |
835 | API.FillConsoleOutputAttribute(@handle, attr, number, col, row) | |
836 | end | |
837 | ||
838 | def FillChar(char, number, col = -1, row = -1) | |
839 | if col < 0 or row < 0 | |
840 | d, d, curr_col, curr_row = API.GetConsoleScreenBufferInfo(@handle) | |
841 | col = curr_col if col < 0 | |
842 | row = curr_row if row < 0 | |
843 | end | |
844 | API.FillConsoleOutputCharacter(@handle, char[0], number, col, row) | |
845 | end | |
846 | ||
847 | def Cls() | |
848 | attr = ATTR_NORMAL | |
849 | x, y = Size() | |
850 | left, top, right , bottom = Window() | |
851 | vx = right - left | |
852 | vy = bottom - top | |
853 | FillChar(' ', x*y, 0, 0) | |
854 | FillAttr(attr, x*y, 0, 0) | |
855 | Cursor(0,0) | |
856 | Window(1,0,0,vx,vy) | |
857 | end | |
858 | ||
859 | def Console.Free() | |
860 | API.FreeConsole() | |
861 | end | |
862 | ||
863 | def Console.Alloc() | |
864 | API.AllocConsole() | |
865 | end | |
866 | ||
867 | def Console.MouseButtons() | |
868 | API.GetNumberOfConsoleMouseButtons() | |
869 | end | |
870 | ||
871 | def Console.InputCP(codepage=nil) | |
872 | if codepage | |
873 | API.SetConsoleCP(codepage) | |
874 | else | |
875 | return API.GetConsoleCP() | |
876 | end | |
877 | end | |
878 | ||
879 | def Console.OutputCP(codepage=nil) | |
880 | if codepage | |
881 | API.SetConsoleOutputCP(codepage) | |
882 | else | |
883 | return API.GetConsoleOutputCP() | |
884 | end | |
885 | end | |
886 | ||
887 | def Console.GenerateCtrlEvent( type=nil, pid=nil ) | |
888 | type = API.constant('CTRL_C_EVENT') if type == nil | |
889 | pid = 0 if pid == nil | |
890 | API.GenerateConsoleCtrlEvent(type, pid) | |
891 | end | |
892 | ||
893 | end | |
894 | end | |
895 | ||
896 | ||
897 | ||
898 | ||
899 | ||
900 | FG_BLACK = 0 | |
901 | FG_BLUE = Win32::Console::API.constant("FOREGROUND_BLUE") | |
902 | FG_LIGHTBLUE = Win32::Console::API.constant("FOREGROUND_BLUE")| | |
903 | Win32::Console::API.constant("FOREGROUND_INTENSITY") | |
904 | FG_RED = Win32::Console::API.constant("FOREGROUND_RED") | |
905 | FG_LIGHTRED = Win32::Console::API.constant("FOREGROUND_RED")| | |
906 | Win32::Console::API.constant("FOREGROUND_INTENSITY") | |
907 | FG_GREEN = Win32::Console::API.constant("FOREGROUND_GREEN") | |
908 | FG_LIGHTGREEN = Win32::Console::API.constant("FOREGROUND_GREEN")| | |
909 | Win32::Console::API.constant("FOREGROUND_INTENSITY") | |
910 | FG_MAGENTA = Win32::Console::API.constant("FOREGROUND_RED")| | |
911 | Win32::Console::API.constant("FOREGROUND_BLUE") | |
912 | FG_LIGHTMAGENTA = Win32::Console::API.constant("FOREGROUND_RED")| | |
913 | Win32::Console::API.constant("FOREGROUND_BLUE")| | |
914 | Win32::Console::API.constant("FOREGROUND_INTENSITY") | |
915 | FG_CYAN = Win32::Console::API.constant("FOREGROUND_GREEN")| | |
916 | Win32::Console::API.constant("FOREGROUND_BLUE") | |
917 | FG_LIGHTCYAN = Win32::Console::API.constant("FOREGROUND_GREEN")| | |
918 | Win32::Console::API.constant("FOREGROUND_BLUE")| | |
919 | Win32::Console::API.constant("FOREGROUND_INTENSITY") | |
920 | FG_BROWN = Win32::Console::API.constant("FOREGROUND_RED")| | |
921 | Win32::Console::API.constant("FOREGROUND_GREEN") | |
922 | FG_YELLOW = Win32::Console::API.constant("FOREGROUND_RED")| | |
923 | Win32::Console::API.constant("FOREGROUND_GREEN")| | |
924 | Win32::Console::API.constant("FOREGROUND_INTENSITY") | |
925 | FG_GRAY = Win32::Console::API.constant("FOREGROUND_RED")| | |
926 | Win32::Console::API.constant("FOREGROUND_GREEN")| | |
927 | Win32::Console::API.constant("FOREGROUND_BLUE") | |
928 | FG_WHITE = Win32::Console::API.constant("FOREGROUND_RED")| | |
929 | Win32::Console::API.constant("FOREGROUND_GREEN")| | |
930 | Win32::Console::API.constant("FOREGROUND_BLUE")| | |
931 | Win32::Console::API.constant("FOREGROUND_INTENSITY") | |
932 | ||
933 | BG_BLACK = 0 | |
934 | BG_BLUE = Win32::Console::API.constant("BACKGROUND_BLUE") | |
935 | BG_LIGHTBLUE = Win32::Console::API.constant("BACKGROUND_BLUE")| | |
936 | Win32::Console::API.constant("BACKGROUND_INTENSITY") | |
937 | BG_RED = Win32::Console::API.constant("BACKGROUND_RED") | |
938 | BG_LIGHTRED = Win32::Console::API.constant("BACKGROUND_RED")| | |
939 | Win32::Console::API.constant("BACKGROUND_INTENSITY") | |
940 | BG_GREEN = Win32::Console::API.constant("BACKGROUND_GREEN") | |
941 | BG_LIGHTGREEN = Win32::Console::API.constant("BACKGROUND_GREEN")| | |
942 | Win32::Console::API.constant("BACKGROUND_INTENSITY") | |
943 | BG_MAGENTA = Win32::Console::API.constant("BACKGROUND_RED")| | |
944 | Win32::Console::API.constant("BACKGROUND_BLUE") | |
945 | BG_LIGHTMAGENTA = Win32::Console::API.constant("BACKGROUND_RED")| | |
946 | Win32::Console::API.constant("BACKGROUND_BLUE")| | |
947 | Win32::Console::API.constant("BACKGROUND_INTENSITY") | |
948 | BG_CYAN = Win32::Console::API.constant("BACKGROUND_GREEN")| | |
949 | Win32::Console::API.constant("BACKGROUND_BLUE") | |
950 | BG_LIGHTCYAN = Win32::Console::API.constant("BACKGROUND_GREEN")| | |
951 | Win32::Console::API.constant("BACKGROUND_BLUE")| | |
952 | Win32::Console::API.constant("BACKGROUND_INTENSITY") | |
953 | BG_BROWN = Win32::Console::API.constant("BACKGROUND_RED")| | |
954 | Win32::Console::API.constant("BACKGROUND_GREEN") | |
955 | BG_YELLOW = Win32::Console::API.constant("BACKGROUND_RED")| | |
956 | Win32::Console::API.constant("BACKGROUND_GREEN")| | |
957 | Win32::Console::API.constant("BACKGROUND_INTENSITY") | |
958 | BG_GRAY = Win32::Console::API.constant("BACKGROUND_RED")| | |
959 | Win32::Console::API.constant("BACKGROUND_GREEN")| | |
960 | Win32::Console::API.constant("BACKGROUND_BLUE") | |
961 | BG_WHITE = Win32::Console::API.constant("BACKGROUND_RED")| | |
962 | Win32::Console::API.constant("BACKGROUND_GREEN")| | |
963 | Win32::Console::API.constant("BACKGROUND_BLUE")| | |
964 | Win32::Console::API.constant("BACKGROUND_INTENSITY") | |
965 | ||
966 | ATTR_NORMAL = FG_GRAY | BG_BLACK | |
967 | ATTR_INVERSE = FG_BLACK | BG_GRAY | |
968 | ||
969 | include Win32::Console::Constants |
0 | ||
1 | ||
2 | ||
3 | @_deferred = [] | |
4 | @_errormsg = nil | |
5 | @_finished = nil | |
6 | ||
7 | begin | |
8 | ||
9 | def defer(&i) | |
10 | @_deferred.push( i ) | |
11 | end | |
12 | ||
13 | def reject(*i) | |
14 | if !i || i[0] | |
15 | @_errormsg = i[1] if i[1] | |
16 | throw :paramout | |
17 | end | |
18 | end | |
19 | ||
20 | def finish(i) | |
21 | if !i || i[0] | |
22 | @_finished = 1 | |
23 | end | |
24 | end | |
25 | ||
26 | @unused = [] | |
27 | @cache = {} | |
28 | _FOUND_ = {} | |
29 | _errors = 0 | |
30 | _invalid = {} | |
31 | _lastprefix = nil | |
32 | ||
33 | _pos = 0 # current position to match from | |
34 | _nextpos = 0 # next position to match from | |
35 | ||
36 | catch(:alldone) do | |
37 | while !@_finished | |
38 | begin | |
39 | catch(:arg) do | |
40 | @_errormsg = nil | |
41 | ||
42 | # This is used for clustering of flags | |
43 | while _lastprefix | |
44 | substr = _args[_nextpos..-1] | |
45 | substr =~ /^(?!\s|\0|\Z)(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)/ or | |
46 | begin | |
47 | _lastprefix=nil | |
48 | break | |
49 | end | |
50 | "#{_lastprefix}#{substr}" =~ /^((?:\-r|\-no_directories|\-nd|\-no_sequences|\-ns|\-no_movies|\-nm|\-no_files|\-nf|\-m|\-full_path|\-fp|\-fmt|\-color_directories|\-cd|\-color_sequences|\-cs|\-color_movies|\-cm|\-color_files|\-cf))/ or | |
51 | begin | |
52 | _lastprefix=nil | |
53 | break | |
54 | end | |
55 | _args = _args[0.._nextpos-1] + _lastprefix + _args[_nextpos..-1] | |
56 | break | |
57 | end # while _lastprefix | |
58 | ||
59 | ||
60 | _pos = _nextpos if _args | |
61 | ||
62 | usage(0) if _args && gindex(_args,/\G(--HELP|--Help|-HELP|-Help|-help|-H|-h|--help)(\s|\0|\Z)/,_pos) | |
63 | version(0) if _args && _args =~ /(-version|-VERSION|-Version|--VERSION|--Version|--version|-V|-v)(\s|\0|\Z)/ | |
64 | ||
65 | catch(:paramout) do | |
66 | while !_FOUND_['-color_directories'] | |
67 | begin | |
68 | catch(:param) do | |
69 | _pos = _nextpos if _args | |
70 | _PUNCT_ = {} | |
71 | ||
72 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-color_directories/i, _pos) or throw(:paramout) | |
73 | unless @_errormsg | |
74 | @_errormsg = %q|incorrect specification of '-color_directories' parameter| | |
75 | end | |
76 | ||
77 | _PARAM_ = '-color_directories' | |
78 | ||
79 | _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) | |
80 | _VAR_ = %q|<c>| | |
81 | _VAL_ = @@m[0] | |
82 | _VAL_.tr!("\0"," ") if _VAL_ | |
83 | c = _VAL_ | |
84 | ||
85 | if _invalid.has_key?('-color_directories') | |
86 | @_errormsg = %q|parameter '-color_directories' not allowed with parameter '| + _invalid['-color_directories'] + %q|'| | |
87 | throw(:paramout) | |
88 | else | |
89 | for i in [] | |
90 | _invalid[i] = '-color_directories' | |
91 | end | |
92 | end #if/then | |
93 | ||
94 | ||
95 | @cache['-cd'] = c | |
96 | @cache['-color_directories'] = c | |
97 | _lastprefix = "\-" | |
98 | ||
99 | _FOUND_['-color_directories'] = 1 | |
100 | throw :arg if _pos > 0 | |
101 | _nextpos = _args.length() | |
102 | throw :alldone | |
103 | end # catch(:param) | |
104 | end # begin | |
105 | end # while | |
106 | end # catch(:paramout) | |
107 | ||
108 | catch(:paramout) do | |
109 | while !_FOUND_['-color_sequences'] | |
110 | begin | |
111 | catch(:param) do | |
112 | _pos = _nextpos if _args | |
113 | _PUNCT_ = {} | |
114 | ||
115 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-color_sequences/i, _pos) or throw(:paramout) | |
116 | unless @_errormsg | |
117 | @_errormsg = %q|incorrect specification of '-color_sequences' parameter| | |
118 | end | |
119 | ||
120 | _PARAM_ = '-color_sequences' | |
121 | ||
122 | _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) | |
123 | _VAR_ = %q|<c>| | |
124 | _VAL_ = @@m[0] | |
125 | _VAL_.tr!("\0"," ") if _VAL_ | |
126 | c = _VAL_ | |
127 | ||
128 | if _invalid.has_key?('-color_sequences') | |
129 | @_errormsg = %q|parameter '-color_sequences' not allowed with parameter '| + _invalid['-color_sequences'] + %q|'| | |
130 | throw(:paramout) | |
131 | else | |
132 | for i in [] | |
133 | _invalid[i] = '-color_sequences' | |
134 | end | |
135 | end #if/then | |
136 | ||
137 | ||
138 | @cache['-cs'] = c | |
139 | @cache['-color_sequences'] = c | |
140 | _lastprefix = "\-" | |
141 | ||
142 | _FOUND_['-color_sequences'] = 1 | |
143 | throw :arg if _pos > 0 | |
144 | _nextpos = _args.length() | |
145 | throw :alldone | |
146 | end # catch(:param) | |
147 | end # begin | |
148 | end # while | |
149 | end # catch(:paramout) | |
150 | ||
151 | catch(:paramout) do | |
152 | while !_FOUND_['-no_directories'] | |
153 | begin | |
154 | catch(:param) do | |
155 | _pos = _nextpos if _args | |
156 | _PUNCT_ = {} | |
157 | ||
158 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-no_directories/i, _pos) or throw(:paramout) | |
159 | unless @_errormsg | |
160 | @_errormsg = %q|incorrect specification of '-no_directories' parameter| | |
161 | end | |
162 | ||
163 | _PARAM_ = '-no_directories' | |
164 | ||
165 | _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) | |
166 | ||
167 | if _invalid.has_key?('-no_directories') | |
168 | @_errormsg = %q|parameter '-no_directories' not allowed with parameter '| + _invalid['-no_directories'] + %q|'| | |
169 | throw(:paramout) | |
170 | else | |
171 | for i in [] | |
172 | _invalid[i] = '-no_directories' | |
173 | end | |
174 | end #if/then | |
175 | ||
176 | ||
177 | @cache['-nd'] = '-nd' | |
178 | ||
179 | @cache['-no_directories'] = '-no_directories' | |
180 | _lastprefix = "\-" | |
181 | ||
182 | _FOUND_['-no_directories'] = 1 | |
183 | throw :arg if _pos > 0 | |
184 | _nextpos = _args.length() | |
185 | throw :alldone | |
186 | end # catch(:param) | |
187 | end # begin | |
188 | end # while | |
189 | end # catch(:paramout) | |
190 | ||
191 | catch(:paramout) do | |
192 | while !_FOUND_['-color_movies'] | |
193 | begin | |
194 | catch(:param) do | |
195 | _pos = _nextpos if _args | |
196 | _PUNCT_ = {} | |
197 | ||
198 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-color_movies/i, _pos) or throw(:paramout) | |
199 | unless @_errormsg | |
200 | @_errormsg = %q|incorrect specification of '-color_movies' parameter| | |
201 | end | |
202 | ||
203 | _PARAM_ = '-color_movies' | |
204 | ||
205 | _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) | |
206 | _VAR_ = %q|<c>| | |
207 | _VAL_ = @@m[0] | |
208 | _VAL_.tr!("\0"," ") if _VAL_ | |
209 | c = _VAL_ | |
210 | ||
211 | if _invalid.has_key?('-color_movies') | |
212 | @_errormsg = %q|parameter '-color_movies' not allowed with parameter '| + _invalid['-color_movies'] + %q|'| | |
213 | throw(:paramout) | |
214 | else | |
215 | for i in [] | |
216 | _invalid[i] = '-color_movies' | |
217 | end | |
218 | end #if/then | |
219 | ||
220 | ||
221 | @cache['-cm'] = c | |
222 | @cache['-color_movies'] = c | |
223 | _lastprefix = "\-" | |
224 | ||
225 | _FOUND_['-color_movies'] = 1 | |
226 | throw :arg if _pos > 0 | |
227 | _nextpos = _args.length() | |
228 | throw :alldone | |
229 | end # catch(:param) | |
230 | end # begin | |
231 | end # while | |
232 | end # catch(:paramout) | |
233 | ||
234 | catch(:paramout) do | |
235 | while !_FOUND_['-no_sequences'] | |
236 | begin | |
237 | catch(:param) do | |
238 | _pos = _nextpos if _args | |
239 | _PUNCT_ = {} | |
240 | ||
241 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-no_sequences/i, _pos) or throw(:paramout) | |
242 | unless @_errormsg | |
243 | @_errormsg = %q|incorrect specification of '-no_sequences' parameter| | |
244 | end | |
245 | ||
246 | _PARAM_ = '-no_sequences' | |
247 | ||
248 | _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) | |
249 | ||
250 | if _invalid.has_key?('-no_sequences') | |
251 | @_errormsg = %q|parameter '-no_sequences' not allowed with parameter '| + _invalid['-no_sequences'] + %q|'| | |
252 | throw(:paramout) | |
253 | else | |
254 | for i in [] | |
255 | _invalid[i] = '-no_sequences' | |
256 | end | |
257 | end #if/then | |
258 | ||
259 | ||
260 | @cache['-ns'] = '-ns' | |
261 | ||
262 | @cache['-no_sequences'] = '-no_sequences' | |
263 | _lastprefix = "\-" | |
264 | ||
265 | _FOUND_['-no_sequences'] = 1 | |
266 | throw :arg if _pos > 0 | |
267 | _nextpos = _args.length() | |
268 | throw :alldone | |
269 | end # catch(:param) | |
270 | end # begin | |
271 | end # while | |
272 | end # catch(:paramout) | |
273 | ||
274 | catch(:paramout) do | |
275 | while !_FOUND_['-color_files'] | |
276 | begin | |
277 | catch(:param) do | |
278 | _pos = _nextpos if _args | |
279 | _PUNCT_ = {} | |
280 | ||
281 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-color_files/i, _pos) or throw(:paramout) | |
282 | unless @_errormsg | |
283 | @_errormsg = %q|incorrect specification of '-color_files' parameter| | |
284 | end | |
285 | ||
286 | _PARAM_ = '-color_files' | |
287 | ||
288 | _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) | |
289 | _VAR_ = %q|<c>| | |
290 | _VAL_ = @@m[0] | |
291 | _VAL_.tr!("\0"," ") if _VAL_ | |
292 | c = _VAL_ | |
293 | ||
294 | if _invalid.has_key?('-color_files') | |
295 | @_errormsg = %q|parameter '-color_files' not allowed with parameter '| + _invalid['-color_files'] + %q|'| | |
296 | throw(:paramout) | |
297 | else | |
298 | for i in [] | |
299 | _invalid[i] = '-color_files' | |
300 | end | |
301 | end #if/then | |
302 | ||
303 | ||
304 | @cache['-cf'] = c | |
305 | @cache['-color_files'] = c | |
306 | _lastprefix = "\-" | |
307 | ||
308 | _FOUND_['-color_files'] = 1 | |
309 | throw :arg if _pos > 0 | |
310 | _nextpos = _args.length() | |
311 | throw :alldone | |
312 | end # catch(:param) | |
313 | end # begin | |
314 | end # while | |
315 | end # catch(:paramout) | |
316 | ||
317 | catch(:paramout) do | |
318 | while !_FOUND_['-no_movies'] | |
319 | begin | |
320 | catch(:param) do | |
321 | _pos = _nextpos if _args | |
322 | _PUNCT_ = {} | |
323 | ||
324 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-no_movies/i, _pos) or throw(:paramout) | |
325 | unless @_errormsg | |
326 | @_errormsg = %q|incorrect specification of '-no_movies' parameter| | |
327 | end | |
328 | ||
329 | _PARAM_ = '-no_movies' | |
330 | ||
331 | _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) | |
332 | ||
333 | if _invalid.has_key?('-no_movies') | |
334 | @_errormsg = %q|parameter '-no_movies' not allowed with parameter '| + _invalid['-no_movies'] + %q|'| | |
335 | throw(:paramout) | |
336 | else | |
337 | for i in [] | |
338 | _invalid[i] = '-no_movies' | |
339 | end | |
340 | end #if/then | |
341 | ||
342 | ||
343 | @cache['-nm'] = '-nm' | |
344 | ||
345 | @cache['-no_movies'] = '-no_movies' | |
346 | _lastprefix = "\-" | |
347 | ||
348 | _FOUND_['-no_movies'] = 1 | |
349 | throw :arg if _pos > 0 | |
350 | _nextpos = _args.length() | |
351 | throw :alldone | |
352 | end # catch(:param) | |
353 | end # begin | |
354 | end # while | |
355 | end # catch(:paramout) | |
356 | ||
357 | catch(:paramout) do | |
358 | while !_FOUND_['-full_path'] | |
359 | begin | |
360 | catch(:param) do | |
361 | _pos = _nextpos if _args | |
362 | _PUNCT_ = {} | |
363 | ||
364 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-full_path/i, _pos) or throw(:paramout) | |
365 | unless @_errormsg | |
366 | @_errormsg = %q|incorrect specification of '-full_path' parameter| | |
367 | end | |
368 | ||
369 | _PARAM_ = '-full_path' | |
370 | ||
371 | _args && _pos = gindex( _args, /\G(?:()(?:\s|\0)*((?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)s)())?/xi, _pos ) or throw(:paramout) | |
372 | if @@m[1] && !@@m[1].empty? | |
373 | _PUNCT_['s'] = @@m[1] | |
374 | end | |
375 | ||
376 | if _invalid.has_key?('-full_path') | |
377 | @_errormsg = %q|parameter '-full_path' not allowed with parameter '| + _invalid['-full_path'] + %q|'| | |
378 | throw(:paramout) | |
379 | else | |
380 | for i in [] | |
381 | _invalid[i] = '-full_path' | |
382 | end | |
383 | end #if/then | |
384 | ||
385 | @cache['-full_path'] = _PUNCT_['s'] || 1 | |
386 | _lastprefix = "\-" | |
387 | ||
388 | _FOUND_['-full_path'] = 1 | |
389 | throw :arg if _pos > 0 | |
390 | _nextpos = _args.length() | |
391 | throw :alldone | |
392 | end # catch(:param) | |
393 | end # begin | |
394 | end # while | |
395 | end # catch(:paramout) | |
396 | ||
397 | catch(:paramout) do | |
398 | while !_FOUND_['-no_files'] | |
399 | begin | |
400 | catch(:param) do | |
401 | _pos = _nextpos if _args | |
402 | _PUNCT_ = {} | |
403 | ||
404 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-no_files/i, _pos) or throw(:paramout) | |
405 | unless @_errormsg | |
406 | @_errormsg = %q|incorrect specification of '-no_files' parameter| | |
407 | end | |
408 | ||
409 | _PARAM_ = '-no_files' | |
410 | ||
411 | _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) | |
412 | ||
413 | if _invalid.has_key?('-no_files') | |
414 | @_errormsg = %q|parameter '-no_files' not allowed with parameter '| + _invalid['-no_files'] + %q|'| | |
415 | throw(:paramout) | |
416 | else | |
417 | for i in [] | |
418 | _invalid[i] = '-no_files' | |
419 | end | |
420 | end #if/then | |
421 | ||
422 | ||
423 | @cache['-nf'] = '-nf' | |
424 | ||
425 | @cache['-no_files'] = '-no_files' | |
426 | _lastprefix = "\-" | |
427 | ||
428 | _FOUND_['-no_files'] = 1 | |
429 | throw :arg if _pos > 0 | |
430 | _nextpos = _args.length() | |
431 | throw :alldone | |
432 | end # catch(:param) | |
433 | end # begin | |
434 | end # while | |
435 | end # catch(:paramout) | |
436 | ||
437 | catch(:paramout) do | |
438 | while !_FOUND_['-fmt'] | |
439 | begin | |
440 | catch(:param) do | |
441 | _pos = _nextpos if _args | |
442 | _PUNCT_ = {} | |
443 | ||
444 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-fmt/i, _pos) or throw(:paramout) | |
445 | unless @_errormsg | |
446 | @_errormsg = %q|incorrect specification of '-fmt' parameter| | |
447 | end | |
448 | ||
449 | _PARAM_ = '-fmt' | |
450 | ||
451 | _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)ilm|dd|shake))/xi, _pos ) or throw(:paramout) | |
452 | _VAR_ = %q|<p>| | |
453 | _VAL_ = @@m[0] | |
454 | _VAL_.tr!("\0"," ") if _VAL_ | |
455 | p = _VAL_ | |
456 | ||
457 | if _invalid.has_key?('-fmt') | |
458 | @_errormsg = %q|parameter '-fmt' not allowed with parameter '| + _invalid['-fmt'] + %q|'| | |
459 | throw(:paramout) | |
460 | else | |
461 | for i in [] | |
462 | _invalid[i] = '-fmt' | |
463 | end | |
464 | end #if/then | |
465 | ||
466 | @cache['-fmt'] = p | |
467 | _lastprefix = "\-" | |
468 | ||
469 | _FOUND_['-fmt'] = 1 | |
470 | throw :arg if _pos > 0 | |
471 | _nextpos = _args.length() | |
472 | throw :alldone | |
473 | end # catch(:param) | |
474 | end # begin | |
475 | end # while | |
476 | end # catch(:paramout) | |
477 | ||
478 | catch(:paramout) do | |
479 | while !_FOUND_['-cf'] | |
480 | begin | |
481 | catch(:param) do | |
482 | _pos = _nextpos if _args | |
483 | _PUNCT_ = {} | |
484 | ||
485 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-cf/i, _pos) or throw(:paramout) | |
486 | unless @_errormsg | |
487 | @_errormsg = %q|incorrect specification of '-cf' parameter| | |
488 | end | |
489 | ||
490 | _PARAM_ = '-cf' | |
491 | ||
492 | _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) | |
493 | _VAR_ = %q|<c>| | |
494 | _VAL_ = @@m[0] | |
495 | _VAL_.tr!("\0"," ") if _VAL_ | |
496 | c = _VAL_ | |
497 | ||
498 | if _invalid.has_key?('-cf') | |
499 | @_errormsg = %q|parameter '-cf' not allowed with parameter '| + _invalid['-cf'] + %q|'| | |
500 | throw(:paramout) | |
501 | else | |
502 | for i in [] | |
503 | _invalid[i] = '-cf' | |
504 | end | |
505 | end #if/then | |
506 | ||
507 | ||
508 | @cache['-cf'] = c | |
509 | @cache['-cf'] = c | |
510 | _lastprefix = "\-" | |
511 | ||
512 | _FOUND_['-cf'] = 1 | |
513 | throw :arg if _pos > 0 | |
514 | _nextpos = _args.length() | |
515 | throw :alldone | |
516 | end # catch(:param) | |
517 | end # begin | |
518 | end # while | |
519 | end # catch(:paramout) | |
520 | ||
521 | catch(:paramout) do | |
522 | while !_FOUND_['-nf'] | |
523 | begin | |
524 | catch(:param) do | |
525 | _pos = _nextpos if _args | |
526 | _PUNCT_ = {} | |
527 | ||
528 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-nf/i, _pos) or throw(:paramout) | |
529 | unless @_errormsg | |
530 | @_errormsg = %q|incorrect specification of '-nf' parameter| | |
531 | end | |
532 | ||
533 | _PARAM_ = '-nf' | |
534 | ||
535 | _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) | |
536 | ||
537 | if _invalid.has_key?('-nf') | |
538 | @_errormsg = %q|parameter '-nf' not allowed with parameter '| + _invalid['-nf'] + %q|'| | |
539 | throw(:paramout) | |
540 | else | |
541 | for i in [] | |
542 | _invalid[i] = '-nf' | |
543 | end | |
544 | end #if/then | |
545 | ||
546 | ||
547 | @cache['-nf'] = '-nf' | |
548 | _lastprefix = "\-" | |
549 | ||
550 | _FOUND_['-nf'] = 1 | |
551 | throw :arg if _pos > 0 | |
552 | _nextpos = _args.length() | |
553 | throw :alldone | |
554 | end # catch(:param) | |
555 | end # begin | |
556 | end # while | |
557 | end # catch(:paramout) | |
558 | ||
559 | catch(:paramout) do | |
560 | while !_FOUND_['-nm'] | |
561 | begin | |
562 | catch(:param) do | |
563 | _pos = _nextpos if _args | |
564 | _PUNCT_ = {} | |
565 | ||
566 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-nm/i, _pos) or throw(:paramout) | |
567 | unless @_errormsg | |
568 | @_errormsg = %q|incorrect specification of '-nm' parameter| | |
569 | end | |
570 | ||
571 | _PARAM_ = '-nm' | |
572 | ||
573 | _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) | |
574 | ||
575 | if _invalid.has_key?('-nm') | |
576 | @_errormsg = %q|parameter '-nm' not allowed with parameter '| + _invalid['-nm'] + %q|'| | |
577 | throw(:paramout) | |
578 | else | |
579 | for i in [] | |
580 | _invalid[i] = '-nm' | |
581 | end | |
582 | end #if/then | |
583 | ||
584 | ||
585 | @cache['-nm'] = '-nm' | |
586 | _lastprefix = "\-" | |
587 | ||
588 | _FOUND_['-nm'] = 1 | |
589 | throw :arg if _pos > 0 | |
590 | _nextpos = _args.length() | |
591 | throw :alldone | |
592 | end # catch(:param) | |
593 | end # begin | |
594 | end # while | |
595 | end # catch(:paramout) | |
596 | ||
597 | catch(:paramout) do | |
598 | while !_FOUND_['-ns'] | |
599 | begin | |
600 | catch(:param) do | |
601 | _pos = _nextpos if _args | |
602 | _PUNCT_ = {} | |
603 | ||
604 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-ns/i, _pos) or throw(:paramout) | |
605 | unless @_errormsg | |
606 | @_errormsg = %q|incorrect specification of '-ns' parameter| | |
607 | end | |
608 | ||
609 | _PARAM_ = '-ns' | |
610 | ||
611 | _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) | |
612 | ||
613 | if _invalid.has_key?('-ns') | |
614 | @_errormsg = %q|parameter '-ns' not allowed with parameter '| + _invalid['-ns'] + %q|'| | |
615 | throw(:paramout) | |
616 | else | |
617 | for i in [] | |
618 | _invalid[i] = '-ns' | |
619 | end | |
620 | end #if/then | |
621 | ||
622 | ||
623 | @cache['-ns'] = '-ns' | |
624 | _lastprefix = "\-" | |
625 | ||
626 | _FOUND_['-ns'] = 1 | |
627 | throw :arg if _pos > 0 | |
628 | _nextpos = _args.length() | |
629 | throw :alldone | |
630 | end # catch(:param) | |
631 | end # begin | |
632 | end # while | |
633 | end # catch(:paramout) | |
634 | ||
635 | catch(:paramout) do | |
636 | while !_FOUND_['-cd'] | |
637 | begin | |
638 | catch(:param) do | |
639 | _pos = _nextpos if _args | |
640 | _PUNCT_ = {} | |
641 | ||
642 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-cd/i, _pos) or throw(:paramout) | |
643 | unless @_errormsg | |
644 | @_errormsg = %q|incorrect specification of '-cd' parameter| | |
645 | end | |
646 | ||
647 | _PARAM_ = '-cd' | |
648 | ||
649 | _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) | |
650 | _VAR_ = %q|<c>| | |
651 | _VAL_ = @@m[0] | |
652 | _VAL_.tr!("\0"," ") if _VAL_ | |
653 | c = _VAL_ | |
654 | ||
655 | if _invalid.has_key?('-cd') | |
656 | @_errormsg = %q|parameter '-cd' not allowed with parameter '| + _invalid['-cd'] + %q|'| | |
657 | throw(:paramout) | |
658 | else | |
659 | for i in [] | |
660 | _invalid[i] = '-cd' | |
661 | end | |
662 | end #if/then | |
663 | ||
664 | ||
665 | @cache['-cd'] = c | |
666 | @cache['-cd'] = c | |
667 | _lastprefix = "\-" | |
668 | ||
669 | _FOUND_['-cd'] = 1 | |
670 | throw :arg if _pos > 0 | |
671 | _nextpos = _args.length() | |
672 | throw :alldone | |
673 | end # catch(:param) | |
674 | end # begin | |
675 | end # while | |
676 | end # catch(:paramout) | |
677 | ||
678 | catch(:paramout) do | |
679 | while !_FOUND_['-nd'] | |
680 | begin | |
681 | catch(:param) do | |
682 | _pos = _nextpos if _args | |
683 | _PUNCT_ = {} | |
684 | ||
685 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-nd/i, _pos) or throw(:paramout) | |
686 | unless @_errormsg | |
687 | @_errormsg = %q|incorrect specification of '-nd' parameter| | |
688 | end | |
689 | ||
690 | _PARAM_ = '-nd' | |
691 | ||
692 | _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) | |
693 | ||
694 | if _invalid.has_key?('-nd') | |
695 | @_errormsg = %q|parameter '-nd' not allowed with parameter '| + _invalid['-nd'] + %q|'| | |
696 | throw(:paramout) | |
697 | else | |
698 | for i in [] | |
699 | _invalid[i] = '-nd' | |
700 | end | |
701 | end #if/then | |
702 | ||
703 | ||
704 | @cache['-nd'] = '-nd' | |
705 | _lastprefix = "\-" | |
706 | ||
707 | _FOUND_['-nd'] = 1 | |
708 | throw :arg if _pos > 0 | |
709 | _nextpos = _args.length() | |
710 | throw :alldone | |
711 | end # catch(:param) | |
712 | end # begin | |
713 | end # while | |
714 | end # catch(:paramout) | |
715 | ||
716 | catch(:paramout) do | |
717 | while !_FOUND_['-cs'] | |
718 | begin | |
719 | catch(:param) do | |
720 | _pos = _nextpos if _args | |
721 | _PUNCT_ = {} | |
722 | ||
723 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-cs/i, _pos) or throw(:paramout) | |
724 | unless @_errormsg | |
725 | @_errormsg = %q|incorrect specification of '-cs' parameter| | |
726 | end | |
727 | ||
728 | _PARAM_ = '-cs' | |
729 | ||
730 | _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) | |
731 | _VAR_ = %q|<c>| | |
732 | _VAL_ = @@m[0] | |
733 | _VAL_.tr!("\0"," ") if _VAL_ | |
734 | c = _VAL_ | |
735 | ||
736 | if _invalid.has_key?('-cs') | |
737 | @_errormsg = %q|parameter '-cs' not allowed with parameter '| + _invalid['-cs'] + %q|'| | |
738 | throw(:paramout) | |
739 | else | |
740 | for i in [] | |
741 | _invalid[i] = '-cs' | |
742 | end | |
743 | end #if/then | |
744 | ||
745 | ||
746 | @cache['-cs'] = c | |
747 | @cache['-cs'] = c | |
748 | _lastprefix = "\-" | |
749 | ||
750 | _FOUND_['-cs'] = 1 | |
751 | throw :arg if _pos > 0 | |
752 | _nextpos = _args.length() | |
753 | throw :alldone | |
754 | end # catch(:param) | |
755 | end # begin | |
756 | end # while | |
757 | end # catch(:paramout) | |
758 | ||
759 | catch(:paramout) do | |
760 | while !_FOUND_['-fp'] | |
761 | begin | |
762 | catch(:param) do | |
763 | _pos = _nextpos if _args | |
764 | _PUNCT_ = {} | |
765 | ||
766 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-fp/i, _pos) or throw(:paramout) | |
767 | unless @_errormsg | |
768 | @_errormsg = %q|incorrect specification of '-fp' parameter| | |
769 | end | |
770 | ||
771 | _PARAM_ = '-fp' | |
772 | ||
773 | _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) | |
774 | ||
775 | if _invalid.has_key?('-fp') | |
776 | @_errormsg = %q|parameter '-fp' not allowed with parameter '| + _invalid['-fp'] + %q|'| | |
777 | throw(:paramout) | |
778 | else | |
779 | for i in [] | |
780 | _invalid[i] = '-fp' | |
781 | end | |
782 | end #if/then | |
783 | ||
784 | ||
785 | @cache['-fp'] = '-fp' | |
786 | _lastprefix = "\-" | |
787 | ||
788 | _FOUND_['-fp'] = 1 | |
789 | throw :arg if _pos > 0 | |
790 | _nextpos = _args.length() | |
791 | throw :alldone | |
792 | end # catch(:param) | |
793 | end # begin | |
794 | end # while | |
795 | end # catch(:paramout) | |
796 | ||
797 | catch(:paramout) do | |
798 | while !_FOUND_['-cm'] | |
799 | begin | |
800 | catch(:param) do | |
801 | _pos = _nextpos if _args | |
802 | _PUNCT_ = {} | |
803 | ||
804 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-cm/i, _pos) or throw(:paramout) | |
805 | unless @_errormsg | |
806 | @_errormsg = %q|incorrect specification of '-cm' parameter| | |
807 | end | |
808 | ||
809 | _PARAM_ = '-cm' | |
810 | ||
811 | _args && _pos = gindex( _args, /\G(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:clear|reset|bold|dark|italic|underline|underscore|blink|rapid_blink|negative|concealed|strikethrough|black|red|green|yellow|blue|magenta|cyan|white|on_black|on_red|on_green|on_yellow|on_blue|on_magenta|on_cyan|on_white))))/xi, _pos ) or throw(:paramout) | |
812 | _VAR_ = %q|<c>| | |
813 | _VAL_ = @@m[0] | |
814 | _VAL_.tr!("\0"," ") if _VAL_ | |
815 | c = _VAL_ | |
816 | ||
817 | if _invalid.has_key?('-cm') | |
818 | @_errormsg = %q|parameter '-cm' not allowed with parameter '| + _invalid['-cm'] + %q|'| | |
819 | throw(:paramout) | |
820 | else | |
821 | for i in [] | |
822 | _invalid[i] = '-cm' | |
823 | end | |
824 | end #if/then | |
825 | ||
826 | ||
827 | @cache['-cm'] = c | |
828 | @cache['-cm'] = c | |
829 | _lastprefix = "\-" | |
830 | ||
831 | _FOUND_['-cm'] = 1 | |
832 | throw :arg if _pos > 0 | |
833 | _nextpos = _args.length() | |
834 | throw :alldone | |
835 | end # catch(:param) | |
836 | end # begin | |
837 | end # while | |
838 | end # catch(:paramout) | |
839 | ||
840 | catch(:paramout) do | |
841 | while !_FOUND_['-r'] | |
842 | begin | |
843 | catch(:param) do | |
844 | _pos = _nextpos if _args | |
845 | _PUNCT_ = {} | |
846 | ||
847 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-r/i, _pos) or throw(:paramout) | |
848 | unless @_errormsg | |
849 | @_errormsg = %q|incorrect specification of '-r' parameter| | |
850 | end | |
851 | ||
852 | _PARAM_ = '-r' | |
853 | ||
854 | _args && _pos = gindex( _args, /\G/xi, _pos ) or throw(:paramout) | |
855 | ||
856 | if _invalid.has_key?('-r') | |
857 | @_errormsg = %q|parameter '-r' not allowed with parameter '| + _invalid['-r'] + %q|'| | |
858 | throw(:paramout) | |
859 | else | |
860 | for i in [] | |
861 | _invalid[i] = '-r' | |
862 | end | |
863 | end #if/then | |
864 | ||
865 | ||
866 | @cache['-r'] = '-r' | |
867 | _lastprefix = "\-" | |
868 | ||
869 | _FOUND_['-r'] = 1 | |
870 | throw :arg if _pos > 0 | |
871 | _nextpos = _args.length() | |
872 | throw :alldone | |
873 | end # catch(:param) | |
874 | end # begin | |
875 | end # while | |
876 | end # catch(:paramout) | |
877 | ||
878 | catch(:paramout) do | |
879 | while !_FOUND_['-m'] | |
880 | begin | |
881 | catch(:param) do | |
882 | _pos = _nextpos if _args | |
883 | _PUNCT_ = {} | |
884 | ||
885 | _args && _pos = gindex( _args, /\G(?:\s|\0)*\-m/i, _pos) or throw(:paramout) | |
886 | unless @_errormsg | |
887 | @_errormsg = %q|incorrect specification of '-m' parameter| | |
888 | end | |
889 | ||
890 | _PARAM_ = '-m' | |
891 | ||
892 | _args && _pos = gindex( _args, /\G(?:()(?:\s|\0)*((?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)issing)())?/xi, _pos ) or throw(:paramout) | |
893 | if @@m[1] && !@@m[1].empty? | |
894 | _PUNCT_['issing'] = @@m[1] | |
895 | end | |
896 | ||
897 | if _invalid.has_key?('-m') | |
898 | @_errormsg = %q|parameter '-m' not allowed with parameter '| + _invalid['-m'] + %q|'| | |
899 | throw(:paramout) | |
900 | else | |
901 | for i in [] | |
902 | _invalid[i] = '-m' | |
903 | end | |
904 | end #if/then | |
905 | ||
906 | @cache['-m'] = _PUNCT_['issing'] || 1 | |
907 | _lastprefix = "\-" | |
908 | ||
909 | _FOUND_['-m'] = 1 | |
910 | throw :arg if _pos > 0 | |
911 | _nextpos = _args.length() | |
912 | throw :alldone | |
913 | end # catch(:param) | |
914 | end # begin | |
915 | end # while | |
916 | end # catch(:paramout) | |
917 | ||
918 | catch(:paramout) do | |
919 | while !_FOUND_['<dirs>'] | |
920 | begin | |
921 | catch(:param) do | |
922 | _pos = _nextpos if _args | |
923 | _PUNCT_ = {} | |
924 | ||
925 | _args && _pos = gindex( _args, /\G(?:\s|\0)*/i, _pos) or throw(:paramout) | |
926 | unless @_errormsg | |
927 | @_errormsg = %q|incorrect specification of '' parameter| | |
928 | end | |
929 | ||
930 | _PARAM_ = '<dirs>' | |
931 | ||
932 | _args && _pos = gindex( _args, /\G(?:()(?:\s|\0)*((?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:\S|\0))+)(?:\s+(?:(?!\-r)(?!\-no_directories)(?!\-nd)(?!\-no_sequences)(?!\-ns)(?!\-no_movies)(?!\-nm)(?!\-no_files)(?!\-nf)(?!\-m)(?!\-full_path)(?!\-fp)(?!\-fmt)(?!\-color_directories)(?!\-cd)(?!\-color_sequences)(?!\-cs)(?!\-color_movies)(?!\-cm)(?!\-color_files)(?!\-cf)(?:(?:\S|\0))+))*)())?/xi, _pos ) or throw(:paramout) | |
933 | _VAR_ = %q|<dirs>| | |
934 | _VAL_ = nil | |
935 | dirs = (@@m[1]||'').split(' ').map { |i| | |
936 | i.tr("\0", " ") } | |
937 | ||
938 | if _invalid.has_key?('') | |
939 | @_errormsg = %q|parameter '' not allowed with parameter '| + _invalid[''] + %q|'| | |
940 | throw(:paramout) | |
941 | else | |
942 | for i in [] | |
943 | _invalid[i] = '' | |
944 | end | |
945 | end #if/then | |
946 | ||
947 | @cache['<dirs>'] = dirs | |
948 | _lastprefix = nil | |
949 | ||
950 | _FOUND_['<dirs>'] = 1 | |
951 | throw :arg if _pos > 0 | |
952 | _nextpos = _args.length() | |
953 | throw :alldone | |
954 | end # catch(:param) | |
955 | end # begin | |
956 | end # while | |
957 | end # catch(:paramout) | |
958 | ||
959 | ||
960 | if _lastprefix | |
961 | _pos = _nextpos + _lastprefix.length() | |
962 | _lastprefix = nil | |
963 | next | |
964 | end | |
965 | ||
966 | _pos = _nextpos | |
967 | ||
968 | _args && _pos = gindex( _args, /\G(?:\s|\0)*(\S+)/, _pos ) or throw(:alldone) | |
969 | ||
970 | if @_errormsg | |
971 | $stderr.puts( "Error#{source}: #{@_errormsg}\n" ) | |
972 | else | |
973 | @unused.push( @@m[0] ) | |
974 | end | |
975 | ||
976 | _errors += 1 if @_errormsg | |
977 | ||
978 | end # catch(:arg) | |
979 | ||
980 | ensure # begin | |
981 | _pos = 0 if _pos.nil? | |
982 | _nextpos = _pos if _args | |
983 | if _args and _args.index( /\G(\s|\0)*\Z/, _pos ) | |
984 | _args = _get_nextline.call(self) if !@_finished | |
985 | throw(:alldone) unless _args | |
986 | _pos = _nextpos = 0 | |
987 | _lastprefix = '' | |
988 | end # if | |
989 | end # begin/ensure | |
990 | end # while @_finished | |
991 | end # catch(:alldone) | |
992 | end # begin | |
993 | ||
994 | ||
995 | #################### Add unused arguments | |
996 | if _args && _nextpos > 0 && _args.length() > 0 | |
997 | @unused.push( _args[_nextpos..-1].split(' ' ) ) | |
998 | end | |
999 | ||
1000 | for i in @unused | |
1001 | i.tr!( "\0", " " ) | |
1002 | end | |
1003 | ||
1004 | ||
1005 | #################### Print help hint | |
1006 | if _errors > 0 && !@source.nil? | |
1007 | $stderr.puts "\n(try '#$0 -help' for more information)" | |
1008 | end | |
1009 | ||
1010 | ## cannot just assign unused to ARGV in ruby | |
1011 | unless @source != '' | |
1012 | ARGV.clear | |
1013 | @unused.map { |i| ARGV.push(i) } | |
1014 | end | |
1015 | ||
1016 | unless _errors > 0 | |
1017 | for i in @_deferred | |
1018 | begin | |
1019 | i.call() | |
1020 | rescue => e | |
1021 | raise "Error: action in Getopt::Declare specification produced:\n" + e | |
1022 | end | |
1023 | end | |
1024 | end | |
1025 | ||
1026 | !(_errors>0) # return true or false (false for errors) | |
1027 |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | require "Win32/Console" | |
3 | ||
4 | ||
5 | a = Win32::Console.new(STD_OUTPUT_HANDLE) | |
6 | ||
7 | puts "Setting cursor to visible and 100% fat" | |
8 | a.Cursor(-1,-1,100,1) |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | require "Win32/Console" | |
3 | ||
4 | a = Win32::Console.new() | |
5 | puts "# of Mouse buttons: #{Win32::Console.MouseButtons}" |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | require "Win32/Console" | |
3 | ||
4 | include Win32::Console::Constants | |
5 | a = Win32::Console.new(STD_INPUT_HANDLE) | |
6 | ||
7 | puts "InputChar: Type a phrase then ENTER, please:" | |
8 | ||
9 | x1 = a.InputChar(1) | |
10 | puts "Your phrase starts with the character #{x1}" | |
11 | ||
12 | ||
13 | fdwMode = ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT | |
14 | ||
15 | a.Mode(fdwMode) | |
16 | ||
17 | puts | |
18 | puts "PeekInput: Type a character without ENTER or do something, please:" | |
19 | ||
20 | while (x1 = a.PeekInput()).size < 1 | |
21 | end | |
22 | ||
23 | if x1[0] == KEY_EVENT | |
24 | puts "You typed #{x1[5]}='#{x1[5].chr}'" | |
25 | else | |
26 | print "You did not typed, but " | |
27 | case x1[0] | |
28 | when MOUSE_EVENT | |
29 | puts "used mouse" | |
30 | when WINDOW_BUFFER_SIZE_EVENT | |
31 | puts "resize window" | |
32 | when MENU_EVENT | |
33 | puts "called menu" | |
34 | when FOCUS_EVENT | |
35 | puts "changed focus" | |
36 | else | |
37 | puts "...should never get here" | |
38 | end | |
39 | end | |
40 | ||
41 | puts | |
42 | puts "Input (as PeekInput keeps event, this reuses PeekInput value):" | |
43 | x1 = a.Input() | |
44 | if x1[0] == KEY_EVENT | |
45 | puts "You typed #{x1[5]}='#{x1[5].chr}'" | |
46 | else | |
47 | print "You did not typed, but " | |
48 | case x1[0] | |
49 | when MOUSE_EVENT | |
50 | puts "used mouse" | |
51 | when WINDOW_BUFFER_SIZE_EVENT | |
52 | puts "resize window" | |
53 | when MENU_EVENT | |
54 | puts "called menu" | |
55 | when FOCUS_EVENT | |
56 | puts "changed focus" | |
57 | else | |
58 | puts "...should never get here" | |
59 | end | |
60 | end | |
61 |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | require "Win32/Console" | |
3 | ||
4 | include Win32::Console::Constants | |
5 | a = Win32::Console.new(STD_OUTPUT_HANDLE) | |
6 | ||
7 | puts <<'EOF' | |
8 | This is a simple | |
9 | test of test to grab | |
10 | from the console. | |
11 | Hopefully this will work | |
12 | easily and merrily. | |
13 | This is a simple | |
14 | test of test to grab | |
15 | from the console. | |
16 | Hopefully this will work | |
17 | easily and merrily. | |
18 | This is a simple | |
19 | test of test to grab | |
20 | from the console. | |
21 | Hopefully this will work | |
22 | easily and merrily. | |
23 | EOF | |
24 | ||
25 | x1 = a.ReadChar(10,10,10) | |
26 | x2 = a.ReadAttr(10,10,10) | |
27 | x3 = a.ReadRect(10,10,20,10) | |
28 | puts "ReadChar .#{x1}." | |
29 | puts x2.class, x2.size | |
30 | print "ReadAttr ." | |
31 | for i in x2 | |
32 | print "#{i}|" | |
33 | end | |
34 | print "\nReadRect ." | |
35 | ||
36 | i = 0 | |
37 | while i < x3.length-1 | |
38 | print "#{x3[i]}" | |
39 | i += 2 | |
40 | end | |
41 | print "\n " | |
42 | i = 1 | |
43 | while i < x3.length-1 | |
44 | print "#{x3[i]}|" | |
45 | i += 2 | |
46 | end | |
47 | print "\n" | |
48 | ||
49 | #puts "read=",x1 | |
50 | #print "Attributes:",x2 | |
51 |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | require "Win32/Console" | |
3 | ||
4 | ||
5 | i = 0 | |
6 | begin | |
7 | while i < 99 | |
8 | if i == 10 | |
9 | Win32::Console::GenerateCtrlEvent() | |
10 | end | |
11 | i = i.next | |
12 | end | |
13 | rescue Exception | |
14 | end | |
15 | ||
16 | puts "if i=10, then OK! i=#{i}" |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | require "Win32/Console" | |
3 | ||
4 | a = Win32::Console.new() | |
5 | ||
6 | title = a.Title() | |
7 | puts "Old title: \"#{title}\"" | |
8 | ||
9 | a.Title("This is a new title") | |
10 | title = a.Title() | |
11 | puts "I just changed the title to '#{title}'" | |
12 | ||
13 | sleep(5) |
0 | #!/usr/bin/env ruby | |
1 | ||
2 | if $0 == __FILE__ | |
3 | require "Term/ANSIColor" | |
4 | include Term::ANSIColor | |
5 | ||
6 | require "benchmark" | |
7 | include Benchmark | |
8 | ||
9 | require "Win32/Console/ANSI" | |
10 | ||
11 | bm do |x| | |
12 | num = 100 | |
13 | x.report("#{num} times") { | |
14 | 0.upto(num) { | |
15 | print "\e[2J" | |
16 | ||
17 | print red, bold, "Usage as constants:", reset, "\n" | |
18 | ||
19 | print clear, "clear", reset, reset, "reset", reset, | |
20 | bold, "bold", reset, dark, "dark", reset, | |
21 | underscore, "underscore", reset, blink, "blink", reset, | |
22 | negative, "negative", reset, concealed, "concealed", reset, "|\n", | |
23 | black, "black", reset, red, "red", reset, green, "green", reset, | |
24 | yellow, "yellow", reset, blue, "blue", reset, magenta, "magenta", reset, | |
25 | cyan, "cyan", reset, white, "white", reset, "|\n", | |
26 | on_black, "on_black", reset, on_red, "on_red", reset, | |
27 | on_green, "on_green", reset, on_yellow, "on_yellow", reset, | |
28 | on_blue, "on_blue", reset, on_magenta, "on_magenta", reset, | |
29 | on_cyan, "on_cyan", reset, on_white, "on_white", reset, "|\n\n" | |
30 | print "\e[s\e[20P.................." | |
31 | } | |
32 | } | |
33 | end | |
34 | end | |
35 |
0 | def guess_color_availability | |
1 | return false unless @output.tty? | |
2 | case ENV["TERM"] | |
3 | when /term(?:-color)?\z/, "screen" | |
4 | true | |
5 | else | |
6 | return true if ENV["EMACS"] == "t" | |
7 | false | |
8 | end | |
9 | end | |
10 | ||
11 | def guess_progress_row_max | |
12 | term_width = guess_term_width | |
13 | if term_width.zero? | |
14 | if ENV["EMACS"] == "t" | |
15 | -1 | |
16 | else | |
17 | 79 | |
18 | end | |
19 | else | |
20 | term_width | |
21 | end | |
22 | end | |
23 | ||
24 | def guess_term_width | |
25 | Integer(ENV["COLUMNS"] || ENV["TERM_WIDTH"] || 0) | |
26 | rescue ArgumentError | |
27 | 0 | |
28 | end | |
29 |