ragweed 0.1.7.2 → 0.1.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -27,8 +27,8 @@ The most complete set is for Win32.
27
27
 
28
28
  == INSTALL:
29
29
 
30
- gem sources -a http://gems.github.com
31
- sudo gem install tduehr-ragweed
30
+ # we're using gemcutter now. once gemcutter is a source just:
31
+ sudo gem install ragweed
32
32
 
33
33
  == LICENSE:
34
34
 
data/Rakefile CHANGED
@@ -1,34 +1,28 @@
1
- # Look in the tasks/setup.rb file for the various options that can be
2
- # configured in this Rakefile. The .rake files in the tasks directory
3
- # are where the options are used.
4
1
 
5
2
  begin
6
3
  require 'bones'
7
- Bones.setup
8
4
  rescue LoadError
9
- begin
10
- load 'tasks/setup.rb'
11
- rescue LoadError
12
- raise RuntimeError, '### please install the "bones" gem ###'
13
- end
5
+ abort '### Please install the "bones" gem ###'
14
6
  end
15
7
 
16
8
  ensure_in_path 'lib'
17
9
  require 'ragweed'
18
10
 
19
- task :default => 'spec:run'
20
-
21
- PROJ.name = 'ragweed'
22
- PROJ.ignore_file = '.gitignore'
23
- PROJ.authors = 'tduehr, tqbf, struct'
24
- PROJ.email = 'td@matasano.com'
25
- PROJ.description = 'General debugging tool written in Ruby for OSX/Win32/Linux'
26
- PROJ.summary = 'Scriptable debugger'
27
- PROJ.exclude << %w(old$)
28
- PROJ.url = 'http://github.com/tduehr/ragweed/tree/master'
29
- PROJ.version = Ragweed::VERSION
30
- PROJ.rdoc.opts << "--inline-source"
31
- PROJ.rdoc.opts << "--line-numbers"
32
- PROJ.spec.opts << '--color'
11
+ task :default => 'test:run'
12
+ task 'gem:release' => 'test:run'
33
13
 
14
+ Bones {
15
+ name 'ragweed'
16
+ ignore_file '.gitignore'
17
+ authors 'tduehr, tqbf, struct'
18
+ email 'td@matasano.com'
19
+ description 'General debugging tool written in Ruby for OSX/Win32/Linux'
20
+ summary 'Scriptable debugger'
21
+ exclude << %w(old$)
22
+ url 'http://github.com/tduehr/ragweed/tree/master'
23
+ version Ragweed::VERSION
24
+ rdoc.opts << "--inline-source"
25
+ rdoc.opts << "--line-numbers"
26
+ spec.opts << '--color'
27
+ }
34
28
  # EOF
data/lib/ragweed/arena.rb CHANGED
@@ -40,7 +40,7 @@ class Ragweed::Arena
40
40
  @avail -= (sz + round)
41
41
  end
42
42
 
43
- return Ptr.new(@cur + ret)
43
+ return Ragweed::Ptr.new(@cur + ret)
44
44
  end
45
45
 
46
46
  # Copy a buffer into the arena and return its new address.
@@ -8,7 +8,7 @@ module Ragweed::Blocks
8
8
  extend Ragweed::Rasm
9
9
 
10
10
  def remote_trampoline(argc, opts={})
11
- i = Rasm::Subprogram.new
11
+ i = Ragweed::Rasm::Subprogram.new
12
12
 
13
13
  # drop directly to debugger
14
14
  i << Int(3) if opts[:debug]
@@ -46,7 +46,7 @@ module Ragweed::Blocks
46
46
  module_function :remote_trampoline
47
47
 
48
48
  def event_pair_stub(opts={})
49
- i = Rasm::Subprogram.new
49
+ i = Ragweed::Rasm::Subprogram.new
50
50
 
51
51
  i << Int(3) if opts[:debug]
52
52
 
@@ -73,7 +73,7 @@ class Ragweed::Detour
73
73
  # Hook function. Override this in subclasses to provide different
74
74
  # behavior.
75
75
  def inner_block
76
- i = Rasm::Subprogram.new
76
+ i = Ragweed::Rasm::Subprogram.new
77
77
  i.<< Int(3)
78
78
  end
79
79
 
@@ -106,13 +106,13 @@ class Ragweed::Detour
106
106
  goto = there - here
107
107
  end
108
108
 
109
- i = Rasm::Subprogram.new
110
- i.<< Rasm::Jmp(goto.to_i)
109
+ i = Ragweed::Rasm::Subprogram.new
110
+ i.<< Ragweed::Rasm::Jmp(goto.to_i)
111
111
  end
112
112
 
113
113
  # Create the detours trampoline:
114
114
  def trampoline(stack)
115
- i = Rasm::Subprogram.new
115
+ i = Ragweed::Rasm::Subprogram.new
116
116
  i.concat push_stack(stack) # 1. Give us a new stack
117
117
  i.concat save_all # 2. Save all the GPRs just in case
118
118
  i.concat inner_block # 3. The hook function
@@ -124,35 +124,35 @@ class Ragweed::Detour
124
124
  # Swap in a new stack, pushing the old stack address
125
125
  # onto the top of it.
126
126
  def push_stack(addr, sz=2048)
127
- i = Rasm::Subprogram.new
128
- i.<< Rasm::Push(eax)
129
- i.<< Rasm::Mov(eax, addr+(sz-4))
130
- i.<< Rasm::Mov([eax], esp)
131
- i.<< Rasm::Pop(eax)
132
- i.<< Rasm::Mov(esp, addr+(sz-4))
127
+ i = Ragweed::Rasm::Subprogram.new
128
+ i.<< Ragweed::Rasm::Push(eax)
129
+ i.<< Ragweed::Rasm::Mov(eax, addr+(sz-4))
130
+ i.<< Ragweed::Rasm::Mov([eax], esp)
131
+ i.<< Ragweed::Rasm::Pop(eax)
132
+ i.<< Ragweed::Rasm::Mov(esp, addr+(sz-4))
133
133
  end
134
134
 
135
135
  # Swap out the new stack.
136
136
  def pop_stack
137
- i = Rasm::Subprogram.new
138
- i.<< Rasm::Pop(esp)
139
- i.<< Rasm::Add(esp, 4)
137
+ i = Ragweed::Rasm::Subprogram.new
138
+ i.<< Ragweed::Rasm::Pop(esp)
139
+ i.<< Ragweed::Rasm::Add(esp, 4)
140
140
  end
141
141
 
142
142
  # Just push all the registers in order
143
143
  def save_all
144
- i = Rasm::Subprogram.new
144
+ i = Ragweed::Rasm::Subprogram.new
145
145
  [eax,ecx,edx,ebx,ebp,esi,edi].each do |r|
146
- i.<< Rasm::Push(r)
146
+ i.<< Ragweed::Rasm::Push(r)
147
147
  end
148
148
  i
149
149
  end
150
150
 
151
151
  # Just pop all the registers
152
152
  def restore_all
153
- i = Rasm::Subprogram.new
153
+ i = Ragweed::Rasm::Subprogram.new
154
154
  [edi,esi,ebp,ebx,edx,ecx,eax].each do |r|
155
- i.<< Rasm::Pop(r)
155
+ i.<< Ragweed::Rasm::Pop(r)
156
156
  end
157
157
  i
158
158
  end
@@ -191,7 +191,7 @@ class Ragweed::Detour
191
191
  end
192
192
 
193
193
  def inner_block
194
- i = Rasm::Subprogram.new
194
+ i = Ragweed::Rasm::Subprogram.new
195
195
  i.<< Push(eax)
196
196
  i.<< Xor(eax, eax)
197
197
  i.<< Or(eax, @data)
data/lib/ragweed/ptr.rb CHANGED
@@ -40,7 +40,7 @@ class Ragweed::Ptr
40
40
  def method_missing(meth, *args)
41
41
  ret = @val.send meth, *args
42
42
  if ret.kind_of? Numeric
43
- ret = Ptr.new(ret)
43
+ ret = Ragweed::Ptr.new(ret)
44
44
  ret.p = self.p
45
45
  end
46
46
  ret
@@ -19,7 +19,7 @@ module Ragweed::Rasm
19
19
  ## ------------------------------------------------------------------------
20
20
 
21
21
  def method_missing(meth, *args)
22
- Rasm.const_get(meth).new *args
22
+ Ragweed::Rasm.const_get(meth).new *args
23
23
  end
24
24
 
25
25
  ## ------------------------------------------------------------------------
@@ -197,7 +197,7 @@ module Ragweed::Rasm
197
197
  # Produce an array of insns. This is pretty much broken, because
198
198
  # it doesn't pre-patch the instructions.
199
199
  def disassemble
200
- select {|i| i.kind_of? Rasm::Instruction}.map {|i| i.decode}
200
+ select {|i| i.kind_of? Ragweed::Rasm::Instruction}.map {|i| i.decode}
201
201
  end
202
202
 
203
203
  def dump_disassembly
data/lib/ragweed/rasm.rb CHANGED
@@ -5,7 +5,7 @@ module Ragweed; end
5
5
  module Ragweed::Rasm
6
6
 
7
7
  # :stopdoc:
8
- VERSION = '0.1.7.2'
8
+ VERSION = '0.1.7.3'
9
9
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
10
10
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
11
11
  # :startdoc:
data/lib/ragweed/utils.rb CHANGED
@@ -1,3 +1,15 @@
1
+ require 'iconv'
2
+
3
+ #do not rely on this extension to range. it'll be removed at some point.
4
+ class Range
5
+ module RangeExtensions
6
+ def each_backwards
7
+ max.to_i.downto(min) {|i| yield i}
8
+ end
9
+ end
10
+ include RangeExtensions
11
+ end
12
+
1
13
  class Array
2
14
  module ArrayExtensions
3
15
  # Convert to hash
@@ -67,6 +79,20 @@ class String
67
79
  def shift_l16; shift(2).to_l16; end
68
80
  def shift_b16; shift(2).to_b16; end
69
81
  def shift_u8; shift(1).to_u8; end
82
+ def to_utf16
83
+ Iconv.iconv("utf-16LE", "utf-8", self).first + "\x00\x00"
84
+ end
85
+ def from_utf16
86
+ ret = Iconv.iconv("utf-8", "utf-16le", self).first
87
+ if ret[-1] == 0
88
+ ret = ret[0..-2]
89
+ end
90
+ end
91
+ alias_method :to_utf8, :from_utf16
92
+ alias_method :to_ascii, :from_utf16
93
+ def from_utf16_buffer
94
+ self[0..index("\0\0\0")+2].from_utf16
95
+ end
70
96
 
71
97
  def shift(count=1)
72
98
  return self if count == 0
@@ -16,7 +16,7 @@ class Ragweed::Process
16
16
  # Get a pointer into the remote process; pointers are just fixnums
17
17
  # with a read/write method and a to_s.
18
18
  def ptr(x)
19
- ret = Ptr.new(x)
19
+ ret = Ragweed::Ptr.new(x)
20
20
  ret.p = self
21
21
  return ret
22
22
  end
@@ -30,7 +30,7 @@ class Ragweed::Process
30
30
  # which is broken --- a heuristic that sometimes works for w32 functions,
31
31
  # but probably never otherwise.
32
32
  def get_proc(name)
33
- return Ptr.new(name) if name.kind_of? Numeric or name.kind_of? Ptr
33
+ return Ragweed::Ptr.new(name) if name.kind_of? Numeric or name.kind_of? Ptr
34
34
  ptr(Ragweed::Wrap32::get_proc_address(name))
35
35
  end
36
36
 
@@ -123,7 +123,7 @@ class Ragweed::Process
123
123
  def remote_call(meth, *args)
124
124
  loc = meth
125
125
  loc = get_proc(loc) if loc.kind_of? String
126
- loc = Ptr.new loc
126
+ loc = Ragweed::Ptr.new loc
127
127
  raise "bad proc name" if loc.null?
128
128
  t = Trampoline.new(self, loc)
129
129
  t.call *args
@@ -5,7 +5,7 @@ module Ragweed; end
5
5
  module Ragweed::Wrap32
6
6
 
7
7
  # :stopdoc:
8
- VERSION = '0.1.7.2'
8
+ VERSION = '0.1.7.3'
9
9
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
10
10
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
11
11
  # :startdoc:
@@ -5,7 +5,7 @@ module Ragweed; end
5
5
  module Ragweed::Wraposx
6
6
 
7
7
  # :stopdoc:
8
- VERSION = '0.1.7.2'
8
+ VERSION = '0.1.7.3'
9
9
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
10
10
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
11
11
  # :startdoc:
@@ -5,7 +5,7 @@ module Ragweed; end
5
5
  module Ragweed::Wraptux
6
6
 
7
7
  # :stopdoc:
8
- VERSION = '0.1.7.2'
8
+ VERSION = '0.1.7.3'
9
9
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
10
10
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
11
11
  # :startdoc:
data/lib/ragweed.rb CHANGED
@@ -2,7 +2,7 @@
2
2
  module Ragweed
3
3
 
4
4
  # :stopdoc:
5
- VERSION = '0.1.7.2'
5
+ VERSION = '0.1.7.3'
6
6
  LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
7
7
  PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
8
8
  # :startdoc:
data/ragweed.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{ragweed}
5
- s.version = "0.1.7.2"
5
+ s.version = "0.1.7.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["tduehr, tqbf, struct"]
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  s.description = %q{General debugging tool written in Ruby for OSX/Win32/Linux}
11
11
  s.email = %q{td@matasano.com}
12
12
  s.extra_rdoc_files = ["History.txt", "README.rdoc", "README.txt"]
13
- s.files = ["History.txt", "README.rdoc", "README.txt", "Rakefile", "examples/hittracertux.rb", "examples/hittracerx.rb", "examples/hook_notepad.rb", "examples/snicker.rb", "examples/tux-example.rb", "lib/ragweed.rb", "lib/ragweed/arena.rb", "lib/ragweed/blocks.rb", "lib/ragweed/debugger32.rb", "lib/ragweed/debuggerosx.rb", "lib/ragweed/debuggertux.rb", "lib/ragweed/detour.rb", "lib/ragweed/ptr.rb", "lib/ragweed/rasm.rb", "lib/ragweed/rasm/bblock.rb", "lib/ragweed/rasm/isa.rb", "lib/ragweed/sbuf.rb", "lib/ragweed/trampoline.rb", "lib/ragweed/utils.rb", "lib/ragweed/wrap32.rb", "lib/ragweed/wrap32/debugging.rb", "lib/ragweed/wrap32/device.rb", "lib/ragweed/wrap32/event.rb", "lib/ragweed/wrap32/hooks.rb", "lib/ragweed/wrap32/overlapped.rb", "lib/ragweed/wrap32/process.rb", "lib/ragweed/wrap32/process_token.rb", "lib/ragweed/wrap32/thread_context.rb", "lib/ragweed/wrap32/winx.rb", "lib/ragweed/wrap32/wrap32.rb", "lib/ragweed/wraposx.rb", "lib/ragweed/wraposx/constants.rb", "lib/ragweed/wraposx/kernelerrorx.rb", "lib/ragweed/wraposx/region_info.rb", "lib/ragweed/wraposx/thread_context.rb", "lib/ragweed/wraposx/thread_info.rb", "lib/ragweed/wraposx/wraposx.rb", "lib/ragweed/wraptux.rb", "lib/ragweed/wraptux/constants.rb", "lib/ragweed/wraptux/threads.rb", "lib/ragweed/wraptux/wraptux.rb", "ragweed.gemspec", "spec/ragweed_spec.rb", "spec/spec_helper.rb", "tasks/ann.rake", "tasks/bones.rake", "tasks/gem.rake", "tasks/git.rake", "tasks/notes.rake", "tasks/post_load.rake", "tasks/rdoc.rake", "tasks/rubyforge.rake", "tasks/setup.rb", "tasks/spec.rake", "tasks/svn.rake", "tasks/test.rake", "tasks/zentest.rake", "test/test_ragweed.rb"]
13
+ s.files = ["History.txt", "README.rdoc", "README.txt", "Rakefile", "examples/hittracertux.rb", "examples/hittracerx.rb", "examples/hook_notepad.rb", "examples/snicker.rb", "examples/tux-example.rb", "lib/ragweed.rb", "lib/ragweed/arena.rb", "lib/ragweed/blocks.rb", "lib/ragweed/debugger32.rb", "lib/ragweed/debuggerosx.rb", "lib/ragweed/debuggertux.rb", "lib/ragweed/detour.rb", "lib/ragweed/ptr.rb", "lib/ragweed/rasm.rb", "lib/ragweed/rasm/bblock.rb", "lib/ragweed/rasm/isa.rb", "lib/ragweed/sbuf.rb", "lib/ragweed/trampoline.rb", "lib/ragweed/utils.rb", "lib/ragweed/wrap32.rb", "lib/ragweed/wrap32/debugging.rb", "lib/ragweed/wrap32/device.rb", "lib/ragweed/wrap32/event.rb", "lib/ragweed/wrap32/hooks.rb", "lib/ragweed/wrap32/overlapped.rb", "lib/ragweed/wrap32/process.rb", "lib/ragweed/wrap32/process_token.rb", "lib/ragweed/wrap32/thread_context.rb", "lib/ragweed/wrap32/winx.rb", "lib/ragweed/wrap32/wrap32.rb", "lib/ragweed/wraposx.rb", "lib/ragweed/wraposx/constants.rb", "lib/ragweed/wraposx/kernelerrorx.rb", "lib/ragweed/wraposx/region_info.rb", "lib/ragweed/wraposx/thread_context.rb", "lib/ragweed/wraposx/thread_info.rb", "lib/ragweed/wraposx/wraposx.rb", "lib/ragweed/wraptux.rb", "lib/ragweed/wraptux/constants.rb", "lib/ragweed/wraptux/threads.rb", "lib/ragweed/wraptux/wraptux.rb", "ragweed.gemspec", "spec/ragweed_spec.rb", "spec/spec_helper.rb", "test/test_ragweed.rb"]
14
14
  s.homepage = %q{http://github.com/tduehr/ragweed/tree/master}
15
15
  s.rdoc_options = ["--inline-source", "--line-numbers", "--main", "README.txt"]
16
16
  s.require_paths = ["lib"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ragweed
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7.2
4
+ version: 0.1.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - tduehr, tqbf, struct
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-07 00:00:00 -05:00
12
+ date: 2009-09-21 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -81,19 +81,6 @@ files:
81
81
  - ragweed.gemspec
82
82
  - spec/ragweed_spec.rb
83
83
  - spec/spec_helper.rb
84
- - tasks/ann.rake
85
- - tasks/bones.rake
86
- - tasks/gem.rake
87
- - tasks/git.rake
88
- - tasks/notes.rake
89
- - tasks/post_load.rake
90
- - tasks/rdoc.rake
91
- - tasks/rubyforge.rake
92
- - tasks/setup.rb
93
- - tasks/spec.rake
94
- - tasks/svn.rake
95
- - tasks/test.rake
96
- - tasks/zentest.rake
97
84
  - test/test_ragweed.rb
98
85
  has_rdoc: true
99
86
  homepage: http://github.com/tduehr/ragweed/tree/master
@@ -121,9 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
121
108
  version:
122
109
  requirements: []
123
110
 
124
- rubyforge_project: !binary |
125
- AA==
126
-
111
+ rubyforge_project: ""
127
112
  rubygems_version: 1.3.5
128
113
  signing_key:
129
114
  specification_version: 3
data/tasks/ann.rake DELETED
@@ -1,80 +0,0 @@
1
-
2
- begin
3
- require 'bones/smtp_tls'
4
- rescue LoadError
5
- require 'net/smtp'
6
- end
7
- require 'time'
8
-
9
- namespace :ann do
10
-
11
- # A prerequisites task that all other tasks depend upon
12
- task :prereqs
13
-
14
- file PROJ.ann.file do
15
- ann = PROJ.ann
16
- puts "Generating #{ann.file}"
17
- File.open(ann.file,'w') do |fd|
18
- fd.puts("#{PROJ.name} version #{PROJ.version}")
19
- fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
20
- fd.puts(" #{PROJ.url}") if PROJ.url.valid?
21
- fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
22
- fd.puts
23
- fd.puts("== DESCRIPTION")
24
- fd.puts
25
- fd.puts(PROJ.description)
26
- fd.puts
27
- fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
28
- fd.puts
29
- ann.paragraphs.each do |p|
30
- fd.puts "== #{p.upcase}"
31
- fd.puts
32
- fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
33
- fd.puts
34
- end
35
- fd.puts ann.text if ann.text
36
- end
37
- end
38
-
39
- desc "Create an announcement file"
40
- task :announcement => ['ann:prereqs', PROJ.ann.file]
41
-
42
- desc "Send an email announcement"
43
- task :email => ['ann:prereqs', PROJ.ann.file] do
44
- ann = PROJ.ann
45
- from = ann.email[:from] || Array(PROJ.authors).first || PROJ.email
46
- to = Array(ann.email[:to])
47
-
48
- ### build a mail header for RFC 822
49
- rfc822msg = "From: #{from}\n"
50
- rfc822msg << "To: #{to.join(',')}\n"
51
- rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
52
- rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
53
- rfc822msg << "\n"
54
- rfc822msg << "Date: #{Time.new.rfc822}\n"
55
- rfc822msg << "Message-Id: "
56
- rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
57
- rfc822msg << File.read(ann.file)
58
-
59
- params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
60
- ann.email[key]
61
- end
62
-
63
- params[3] = PROJ.email if params[3].nil?
64
-
65
- if params[4].nil?
66
- STDOUT.write "Please enter your e-mail password (#{params[3]}): "
67
- params[4] = STDIN.gets.chomp
68
- end
69
-
70
- ### send email
71
- Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
72
- end
73
- end # namespace :ann
74
-
75
- desc 'Alias to ann:announcement'
76
- task :ann => 'ann:announcement'
77
-
78
- CLOBBER << PROJ.ann.file
79
-
80
- # EOF
data/tasks/bones.rake DELETED
@@ -1,20 +0,0 @@
1
-
2
- if HAVE_BONES
3
-
4
- namespace :bones do
5
-
6
- desc 'Show the PROJ open struct'
7
- task :debug do |t|
8
- atr = if t.application.top_level_tasks.length == 2
9
- t.application.top_level_tasks.pop
10
- end
11
-
12
- if atr then Bones::Debug.show_attr(PROJ, atr)
13
- else Bones::Debug.show PROJ end
14
- end
15
-
16
- end # namespace :bones
17
-
18
- end # HAVE_BONES
19
-
20
- # EOF