Codebase list ruby-ansi / e010b2e8-9834-4f0c-a383-8827dfcfffde/upstream
Import upstream version 1.5.0+git20150226.1.1700234 Debian Janitor 2 years ago
47 changed file(s) with 6236 addition(s) and 269 deletion(s). Raw diff Collapse all Expand all
0 .reap/digest
1 .rdoc
2 .yardoc
3 log
4 pkg
5 tmp
6 doc
7 web
8 *.lock
9 *.gem
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 source "https://rubygems.org"
1 gemspec
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
11
22 [HOME](http://rubyworks.github.com/ansi) &middot;
33 [API](http://rubydoc.info/gems/ansi/frames) &middot;
4 [MAIL](http://googlegroups.com/group/rubyworks-mailinglist) &middot;
54 [ISSUES](http://github.com/rubyworks/ansi/issues) &middot;
65 [SOURCE](http://github.com/rubyworks/ansi)
76
5554
5655 ## Installation
5756
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
5865 ### RubyGems
5966
6067 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
5151 pbar.format("%-14s %3d%% %s %s",:title, :percentage, :bar, :stat_for_file_transfer)
5252 run(pbar)
5353
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.
5656
5757 pbar.standard_mode
5858 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
-77
lib/ansi.yml less more
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
-189
metadata.yml less more
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
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