unmangler 0.0.1 → 0.0.2

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.
@@ -61,7 +61,11 @@ class StringPtr
61
61
  end
62
62
 
63
63
  def index needle
64
- @string[@pos..-1].index(needle)
64
+ (@string[@pos..-1] || '').index(needle)
65
+ end
66
+
67
+ def strlen
68
+ (@string[@pos..-1] || '').bytesize
65
69
  end
66
70
 
67
71
  def =~ re
@@ -71,6 +75,23 @@ class StringPtr
71
75
  def inc!; @pos+=1; end
72
76
  def dec!; @pos-=1; end
73
77
 
78
+ # get current character and then increment
79
+ # like in C:
80
+ # c = *p++
81
+ def get_inc!
82
+ c = @string[@pos]
83
+ @pos+=1
84
+ c
85
+ end
86
+
87
+ # increment and then get current character
88
+ # like in C:
89
+ # c = *++p
90
+ def inc_get!
91
+ @pos+=1
92
+ @string[@pos]
93
+ end
94
+
74
95
  def trim!
75
96
  return unless @string
76
97
  if idx = @string.index("\x00")
@@ -94,6 +115,10 @@ class StringPtr
94
115
  @pos - x.pos
95
116
  end
96
117
  end
118
+
119
+ def inspect
120
+ "#<StringPtr @pos=#{@pos.inspect}: #{@string[@pos..-1].inspect}>"
121
+ end
97
122
  end
98
123
 
99
124
  if $0 == __FILE__
@@ -1,3 +1,3 @@
1
1
  module Unmangler
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Unmangler::Borland do
4
+ if max_idx = ENV['LONG_RUN']
5
+ max_idx = max_idx.to_i
6
+ idx = 0
7
+ YAML::load_file(File.join(SAMPLES_DIR, "borland.yaml")).each do |mangled, unmangled|
8
+ unmangled = preprocess_borland unmangled
9
+ idx += 1
10
+ break if idx > max_idx
11
+ it "should unmangle #{mangled}" do
12
+ Unmangler::Borland.unmangle(mangled).should == unmangled
13
+ end
14
+ end
15
+ else
16
+ it "should unmangle" do
17
+ YAML::load_file(File.join(SAMPLES_DIR, "borland.yaml")).each do |mangled, unmangled|
18
+ unmangled = preprocess_borland unmangled
19
+ actual = Unmangler::Borland.unmangle(mangled)
20
+ actual.should eql(unmangled), [
21
+ "mangled : #{mangled.white}",
22
+ "expected: #{unmangled.green}",
23
+ "actual : #{actual.red}"
24
+ ].join("\n")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -70,4 +70,6 @@ describe Unmangler::Borland do
70
70
  check "@Dbcommon@GetTableNameFromSQLEx$qqrx17System@WideString25Dbcommon@IDENTIFIEROption",
71
71
  "__fastcall Dbcommon::GetTableNameFromSQLEx(const System::WideString, Dbcommon::IDENTIFIEROption)"
72
72
 
73
+ check '@Classes@TThread@$bcdtr$qqrv', '__fastcall Classes::TThread::`class destructor`()'
74
+ check '@Timespan@TTimeSpan@$bcctr$qqrv', '__fastcall Timespan::TTimeSpan::`class constructor`()'
73
75
  end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe Unmangler::MSVC do
4
+ if max_idx = ENV['LONG_RUN']
5
+ max_idx = max_idx.to_i
6
+ idx = 0
7
+ YAML::load_file(File.join(SAMPLES_DIR, "msvc.yaml")).each do |mangled, unmangled|
8
+ idx += 1
9
+ break if idx > max_idx
10
+ it "should unmangle #{mangled}" do
11
+ unmangled = preprocess_msvc unmangled
12
+ Unmangler::MSVC.unmangle(mangled).should == unmangled
13
+ end
14
+ end
15
+ else
16
+ it "should unmangle" do
17
+ YAML::load_file(File.join(SAMPLES_DIR, "msvc.yaml")).each do |mangled, unmangled|
18
+ unmangled = preprocess_msvc unmangled
19
+ actual = Unmangler::MSVC.unmangle(mangled)
20
+ actual.should eql(unmangled), [
21
+ "mangled : #{mangled.white}",
22
+ "expected: #{unmangled.green}",
23
+ "actual : #{actual.red}"
24
+ ].join("\n")
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ describe Unmangler::MSVC do
4
+
5
+ it "keeps original name if not mangled" do
6
+ s = "foo::bar(@)"
7
+ Unmangler::MSVC.unmangle(s).should == s
8
+ end
9
+
10
+ # describe "#unmangle" do
11
+ # it "raises error on bad input" do
12
+ # lambda{
13
+ # Unmangler::MSVC.unmangle("@TTabPage@$bctr")
14
+ # }.should raise_error
15
+ # end
16
+ # end
17
+
18
+ describe "#safe_unmangle" do
19
+ it "raises no error and returns original on bad input" do
20
+ s = "@TTabPage@$bctr"
21
+ Unmangler::MSVC.safe_unmangle(s).should == s
22
+ end
23
+ end
24
+
25
+ def self.check mangled, unmangled, test_no_args = true
26
+ it "unmangles #{mangled}" do
27
+ Unmangler::MSVC.unmangle(mangled).should == unmangled
28
+ end
29
+
30
+ it "unmangles #{mangled} w/o args" do
31
+ x = unmangled.split('(').first.strip.
32
+ gsub(/(public|private|protected): /,'').
33
+ gsub(/(void|__ptr64|int|__thiscall|__cdecl|virtual|class|struct) /,'').
34
+ strip
35
+
36
+ Unmangler::MSVC.unmangle(mangled, :args => false).should == x
37
+ end if test_no_args
38
+ end
39
+
40
+ check "?h@@YAXH@Z", "void __cdecl h(int)"
41
+ check "?AFXSetTopLevelFrame@@YAXPAVCFrameWnd@@@Z", "void __cdecl AFXSetTopLevelFrame(class CFrameWnd *)"
42
+ check "??0_Lockit@std@@QAE@XZ", "public: __thiscall std::_Lockit::_Lockit(void)"
43
+
44
+ check "?SetAt@CString@@QAEXHD@Z", "public: void __thiscall CString::SetAt(int, char)"
45
+ check "?LoadFrame@CMDIFrameWndEx@@UAEHIKPAVCWnd@@PAUCCreateContext@@@Z",
46
+ "public: virtual int __thiscall CMDIFrameWndEx::LoadFrame(unsigned int, unsigned long, class CWnd *, struct CCreateContext *)"
47
+
48
+ check "??0DNameStatusNode@@AEAA@W4DNameStatus@@@Z",
49
+ "private: __cdecl DNameStatusNode::DNameStatusNode(enum DNameStatus) __ptr64"
50
+
51
+ check "?Add@?$CArray@VCSize@@V1@@@QAEHVCSize@@@Z",
52
+ "public: int __thiscall CArray<class CSize, class CSize>::Add(class CSize)"
53
+
54
+ check "??$_Char_traits_cat@U?$char_traits@D@std@@@std@@YA?AU_Secure_char_traits_tag@0@XZ",
55
+ "struct std::_Secure_char_traits_tag __cdecl std::_Char_traits_cat<struct std::char_traits<char> >(void)",
56
+ false
57
+
58
+ check "?dtor$0@?0???0CDockSite@@QEAA@XZ@4HA",
59
+ "int `public: __cdecl CDockSite::CDockSite(void) __ptr64'::`1'::dtor$0",
60
+ false
61
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ def combined_samples
4
+ @@combined_samples ||=
5
+ begin
6
+ msvc = YAML::load_file(File.join(SAMPLES_DIR, "msvc.yaml"))
7
+ borland = YAML::load_file(File.join(SAMPLES_DIR, "borland.yaml"))
8
+
9
+ combined = {}
10
+ (msvc.keys + borland.keys).uniq.each do |key|
11
+ um = msvc[key]
12
+ ub = borland[key]
13
+
14
+ combined[key] =
15
+ if um && um != key
16
+ preprocess_msvc um
17
+ elsif ub && ub != key
18
+ preprocess_borland ub
19
+ else
20
+ # neither
21
+ key
22
+ end
23
+ end
24
+ combined
25
+ end
26
+ end
27
+
28
+ describe Unmangler do
29
+ if max_idx = ENV['LONG_RUN']
30
+ max_idx = max_idx.to_i
31
+ idx = 0
32
+ combined_samples.each do |mangled, unmangled|
33
+ idx += 1
34
+ break if idx > max_idx
35
+ it "should unmangle #{mangled}" do
36
+ Unmangler.unmangle(mangled).should == unmangled
37
+ end
38
+ end
39
+ else
40
+ it "should unmangle" do
41
+ combined_samples.each do |mangled, unmangled|
42
+ actual = Unmangler.unmangle(mangled)
43
+ actual.should eql(unmangled), [
44
+ "mangled : #{mangled.white}",
45
+ "expected: #{unmangled.green}",
46
+ "actual : #{actual.red}"
47
+ ].join("\n")
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,14 +1,39 @@
1
+ require 'yaml'
2
+ require 'awesome_print'
3
+
1
4
  $: << File.expand_path("../lib", File.dirname(__FILE__))
2
5
  require 'unmangler'
3
6
 
7
+ SAMPLES_DIR = File.expand_path("../samples", File.dirname(__FILE__))
8
+
9
+ def preprocess_msvc s
10
+ s.gsub(',',', ')
11
+ end
12
+
13
+ def preprocess_borland s
14
+ r = s.gsub('const const ','const ')
15
+
16
+ # move '__fastcall' to start of the string if its found in middle of string
17
+ pos = r.index(" __fastcall ")
18
+ if pos && pos != 0
19
+ r = "__fastcall " + r.sub("__fastcall ", "")
20
+ end
21
+
22
+ r
23
+ end
24
+
4
25
  RSpec.configure do |config|
5
26
  config.treat_symbols_as_metadata_keys_with_true_values = true
6
27
  config.run_all_when_everything_filtered = true
7
- #config.filter_run :focus
8
28
 
9
- # Run specs in random order to surface order dependencies. If you find an
10
- # order dependency and want to debug it, you can fix the order by providing
11
- # the seed, which is printed after each run.
12
- # --seed 1234
13
- #config.order = 'random'
29
+ config.before(:suite) do
30
+ Dir[File.join(SAMPLES_DIR, "*.bz2")].each do |fname|
31
+ unless File.exist?(fname.sub(/\.bz2$/,''))
32
+ puts "[.] unpacking #{fname} .."
33
+ system("bunzip2", "-dk", fname)
34
+ end
35
+ end
36
+ end
37
+
38
+ config.backtrace_clean_patterns = [/\/rspec/]
14
39
  end
@@ -12,7 +12,9 @@ Gem::Specification.new do |gem|
12
12
  gem.summary = gem.description + %q{, i.e. '@myclass@func$qil' => 'myclass::func(int, long)'}
13
13
  gem.homepage = "http://zed.0xff.me"
14
14
 
15
- gem.files = `git ls-files`.split($/)
15
+ gem.files = `git ls-files`.split($/).
16
+ delete_if{ |x| x.end_with?(".bz2") || x.include?("misc/") }
17
+
16
18
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
19
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
20
  gem.require_paths = ["lib"]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unmangler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrey "Zed" Zaikin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-03 00:00:00.000000000 Z
11
+ date: 2013-05-05 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Unmangles mangled C++/Delphi names"
14
14
  email:
@@ -25,10 +25,16 @@ files:
25
25
  - README.md.tpl
26
26
  - Rakefile
27
27
  - lib/unmangler.rb
28
+ - lib/unmangler/base.rb
28
29
  - lib/unmangler/borland.rb
30
+ - lib/unmangler/msvc.rb
29
31
  - lib/unmangler/string_ptr.rb
30
32
  - lib/unmangler/version.rb
33
+ - spec/borland_samples_spec.rb
31
34
  - spec/borland_spec.rb
35
+ - spec/msvc_samples_spec.rb
36
+ - spec/msvc_spec.rb
37
+ - spec/samples_spec.rb
32
38
  - spec/spec_helper.rb
33
39
  - unmangler.gemspec
34
40
  homepage: http://zed.0xff.me
@@ -56,5 +62,9 @@ specification_version: 4
56
62
  summary: Unmangles mangled C++/Delphi names", i.e. '@myclass@func$qil' => 'myclass::func(int,
57
63
  long)'
58
64
  test_files:
65
+ - spec/borland_samples_spec.rb
59
66
  - spec/borland_spec.rb
67
+ - spec/msvc_samples_spec.rb
68
+ - spec/msvc_spec.rb
69
+ - spec/samples_spec.rb
60
70
  - spec/spec_helper.rb