starscope 0.1.3 → 0.1.4

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/CHANGELOG.md CHANGED
@@ -1,7 +1,21 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
- v0.1.3 (trunk)
4
+ v0.1.4 (trunk)
5
+ -------------------
6
+
7
+ New Features:
8
+ * Export to cscope databases.
9
+ * Regexes are now accepted in the last ('key') term of a query
10
+
11
+ Bug Fixes:
12
+ * Don't match Golang function names ending with a dot.
13
+
14
+ Misc:
15
+ * Dumping tables now sorts by key.
16
+ * Various bugfixes and improvements via updated dependencies.
17
+
18
+ v0.1.3 (2013-10-15)
5
19
  -------------------
6
20
 
7
21
  Misc:
data/Gemfile.lock CHANGED
@@ -1,38 +1,38 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- starscope (0.1.3)
5
- oj (~> 2.1)
6
- parser (~> 2.0)
7
- ruby-progressbar (~> 1.2)
4
+ starscope (0.1.4)
5
+ oj (~> 2.5)
6
+ parser (~> 2.1)
7
+ ruby-progressbar (~> 1.4)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
12
  ast (1.1.0)
13
- coderay (1.0.9)
13
+ coderay (1.1.0)
14
14
  columnize (0.3.6)
15
- debugger (1.6.0)
15
+ debugger (1.6.5)
16
16
  columnize (>= 0.3.1)
17
17
  debugger-linecache (~> 1.2.0)
18
- debugger-ruby_core_source (~> 1.2.1)
18
+ debugger-ruby_core_source (~> 1.3.1)
19
19
  debugger-linecache (1.2.0)
20
- debugger-ruby_core_source (1.2.2)
21
- method_source (0.8.1)
22
- oj (2.1.6)
23
- parser (2.0.0)
20
+ debugger-ruby_core_source (1.3.1)
21
+ method_source (0.8.2)
22
+ oj (2.5.3)
23
+ parser (2.1.2)
24
24
  ast (~> 1.1)
25
25
  slop (~> 3.4, >= 3.4.5)
26
- pry (0.9.12.2)
27
- coderay (~> 1.0.5)
26
+ pry (0.9.12.4)
27
+ coderay (~> 1.0)
28
28
  method_source (~> 0.8)
29
29
  slop (~> 3.4)
30
30
  pry-debugger (0.2.2)
31
31
  debugger (~> 1.3)
32
32
  pry (~> 0.9.10)
33
- rake (10.0.4)
34
- ruby-progressbar (1.2.0)
35
- slop (3.4.5)
33
+ rake (10.1.1)
34
+ ruby-progressbar (1.4.0)
35
+ slop (3.4.7)
36
36
 
37
37
  PLATFORMS
38
38
  ruby
data/README.md CHANGED
@@ -3,9 +3,6 @@ StarScope
3
3
 
4
4
  https://rubygems.org/gems/starscope
5
5
 
6
- *Note to those users looking at the GitHub language statistics: there is no perl
7
- here, that is their bug to fix.*
8
-
9
6
  Anyone who has done much programming in C (or C++) on a unix-based OS has come
10
7
  across the fantastic Cscope tool [1]. Sadly, it only works for C (and sort of
11
8
  works for C++).
@@ -34,5 +31,9 @@ Export it for use with your editor
34
31
  ```
35
32
  $ starscope -e ctags
36
33
  ```
34
+ or
35
+ ```
36
+ $ starscope -e cscope
37
+ ```
37
38
 
38
39
  [1] http://cscope.sourceforge.net/
data/TODO.md CHANGED
@@ -3,5 +3,5 @@ TODO
3
3
 
4
4
  * Add --quiet to hide progress bar and --verbose to print each file
5
5
  * Parallelization, perhaps via https://github.com/grosser/parallel
6
+ * Fuzzy matching, perhaps via https://github.com/seamusabshere/fuzzy_match
6
7
  * Export advanced ctags annotations
7
- * Export to cscope format
data/bin/starscope CHANGED
@@ -57,8 +57,9 @@ END
57
57
 
58
58
  opts.separator <<END
59
59
  \nEXPORTING
60
- At the moment only one export format is supported: 'ctags'. If you don't
61
- specify a path, the file is written to 'tags' in the current directory.
60
+ At the moment two export formats are supported: 'ctags' and 'cscope'. If you
61
+ don't specify a path, the output is written to the files 'tags' (for ctags)
62
+ or 'cscope.out' (for cscope) in the current directory.
62
63
  END
63
64
 
64
65
  end.parse!
@@ -75,7 +76,7 @@ def run_query(db, table, value)
75
76
  return false
76
77
  end
77
78
  key, results = db.query(table.to_sym, value)
78
- puts results.map {|val| StarScope::Datum.to_s(key, val)} if results
79
+ puts results.map {|val| StarScope::Datum.to_s(val)} if results
79
80
  return true
80
81
  rescue StarScope::DB::NoTableError
81
82
  $stderr.puts "Table '#{table}' doesn't exist."
@@ -128,6 +129,8 @@ if options[:export]
128
129
  case format
129
130
  when 'ctags'
130
131
  db.export_ctags(path || 'tags')
132
+ when 'cscope'
133
+ db.export_cscope(path || 'cscope.out')
131
134
  else
132
135
  puts "Unrecognized export format"
133
136
  end
@@ -1,7 +1,8 @@
1
1
  class StarScope::Datum
2
2
 
3
- def self.build(file, args)
3
+ def self.build(file, key, args)
4
4
  args[:file] = file
5
+ args[:key] = key
5
6
 
6
7
  if args[:line_no]
7
8
  args[:line] = File.readlines(file)[args[:line_no]-1].chomp
@@ -40,14 +41,51 @@ class StarScope::Datum
40
41
  "#{dat[:file]}:#{dat[:line_no]}"
41
42
  end
42
43
 
43
- def self.to_s(key, dat)
44
+ def self.to_s(dat)
44
45
  str = ""
45
46
  str << "#{dat[:scope].join " "} " if dat[:scope]
46
- str << "#{key} -- #{location dat}"
47
+ str << "#{dat[:key]} -- #{location dat}"
47
48
  str << " (#{dat[:line].strip})"
48
49
  end
49
50
 
50
- def self.ctag_line(key, dat)
51
- "#{key}\t#{dat[:file]}\t/^#{dat[:line]}$/;"
51
+ def self.ctag_line(dat)
52
+ "#{dat[:key]}\t#{dat[:file]}\t/^#{dat[:line]}$/;"
53
+ end
54
+
55
+ def self.cscope_mark(tbl, dat)
56
+ case tbl
57
+ when :end
58
+ case dat[:type]
59
+ when :func
60
+ ret = "}"
61
+ else
62
+ return ""
63
+ end
64
+ when :file
65
+ ret = "@"
66
+ when :defs
67
+ case dat[:type]
68
+ when :func
69
+ ret = "$"
70
+ when :class, :module
71
+ ret = "c"
72
+ when :type
73
+ ret = "t"
74
+ else
75
+ ret = "g"
76
+ end
77
+ when :calls
78
+ ret = "`"
79
+ when :requires
80
+ ret = "~\""
81
+ when :imports
82
+ ret = "~<"
83
+ when :assigns
84
+ ret = "="
85
+ else
86
+ return ""
87
+ end
88
+
89
+ return "\t" + ret
52
90
  end
53
91
  end
data/lib/starscope/db.rb CHANGED
@@ -13,7 +13,7 @@ LANGS = [
13
13
 
14
14
  class StarScope::DB
15
15
 
16
- DB_FORMAT = 3
16
+ DB_FORMAT = 4
17
17
  PBAR_FORMAT = '%t: %c/%C %E ||%b>%i||'
18
18
 
19
19
  class NoTableError < StandardError; end
@@ -89,11 +89,11 @@ class StarScope::DB
89
89
  def dump_table(table)
90
90
  raise NoTableError if not @tables[table]
91
91
  puts "== Table: #{table} =="
92
- @tables[table].each do |val, data|
92
+ @tables[table].sort_by{|k,v| k.downcase}.each do |val, data|
93
93
  puts "#{val}"
94
94
  data.each do |datum|
95
95
  print "\t"
96
- puts StarScope::Datum.to_s(val, datum)
96
+ puts StarScope::Datum.to_s(datum)
97
97
  end
98
98
  end
99
99
  end
@@ -115,9 +115,18 @@ class StarScope::DB
115
115
  def query(table, value)
116
116
  fqn = value.split("::")
117
117
  raise NoTableError if not @tables[table]
118
- key = fqn.last.to_sym
119
- results = @tables[table][key]
120
- return [] if results.nil? || results.empty?
118
+ key = fqn.last
119
+ results = @tables[table][key.to_sym] || []
120
+ if results.empty?
121
+ matcher = Regexp.new(key, Regexp::IGNORECASE)
122
+ @tables[table].each do |k,v|
123
+ if matcher.match(k)
124
+ results << v
125
+ end
126
+ end
127
+ results.flatten!
128
+ end
129
+ return results if results.empty?
121
130
  results.sort! do |a,b|
122
131
  StarScope::Datum.score_match(b, fqn) <=> StarScope::Datum.score_match(a, fqn)
123
132
  end
@@ -125,7 +134,7 @@ class StarScope::DB
125
134
  results = results.select do |result|
126
135
  best_score - StarScope::Datum.score_match(result, fqn) < 4
127
136
  end
128
- return key, results
137
+ return fqn.last.to_sym, results
129
138
  end
130
139
 
131
140
  def export_ctags(filename)
@@ -141,12 +150,67 @@ END
141
150
  defs = (@tables[:defs] || {}).sort
142
151
  defs.each do |key, val|
143
152
  val.each do |entry|
144
- file.puts StarScope::Datum.ctag_line(key, entry)
153
+ file.puts StarScope::Datum.ctag_line(entry)
145
154
  end
146
155
  end
147
156
  end
148
157
  end
149
158
 
159
+ # ftp://ftp.eeng.dcu.ie/pub/ee454/cygwin/usr/share/doc/mlcscope-14.1.8/html/cscope.html
160
+ def export_cscope(filename)
161
+ buf = ""
162
+ files = []
163
+ db_by_line().each do |file, lines|
164
+ if not lines.empty?
165
+ buf << "\t@#{file}\n\n"
166
+ files << file
167
+ end
168
+ lines.sort.each do |line_no, vals|
169
+ line = vals.first[:entry][:line].strip.gsub(/\s+/, ' ')
170
+ toks = {}
171
+
172
+ vals.each do |val|
173
+ index = line.index(val[:key].to_s)
174
+ while index
175
+ toks[index] = val
176
+ index = line.index(val[:key].to_s, index + 1)
177
+ end
178
+ end
179
+
180
+ next if toks.empty?
181
+
182
+ prev = 0
183
+ buf << line_no.to_s << " "
184
+ toks.sort().each do |offset, val|
185
+ buf << line.slice(prev...offset) << "\n"
186
+ buf << StarScope::Datum.cscope_mark(val[:tbl], val[:entry])
187
+ buf << val[:key].to_s << "\n"
188
+ prev = offset + val[:key].to_s.length
189
+ end
190
+ buf << line.slice(prev..-1) << "\n\n"
191
+ end
192
+ end
193
+
194
+ buf << "\t@\n"
195
+
196
+ header = "cscope 15 #{Dir.pwd} -c "
197
+ offset = "%010d\n" % (header.length + 11 + buf.length)
198
+
199
+ File.open(filename, 'w') do |file|
200
+ file.print(header)
201
+ file.print(offset)
202
+ file.print(buf)
203
+
204
+ file.print("#{@paths.length}\n")
205
+ @paths.each {|p| file.print("#{p}\n")}
206
+ file.print("0\n")
207
+ file.print("#{files.length}\n")
208
+ buf = ""
209
+ files.each {|f| buf << f + "\n"}
210
+ file.print("#{buf.length}\n#{buf}")
211
+ end
212
+ end
213
+
150
214
  private
151
215
 
152
216
  def self.files_from_path(path)
@@ -159,6 +223,22 @@ END
159
223
  end
160
224
  end
161
225
 
226
+ def db_by_line()
227
+ tmpdb = {}
228
+ @tables.each do |tbl, vals|
229
+ vals.each do |key, val|
230
+ val.each do |entry|
231
+ if entry[:line_no]
232
+ tmpdb[entry[:file]] ||= {}
233
+ tmpdb[entry[:file]][entry[:line_no]] ||= []
234
+ tmpdb[entry[:file]][entry[:line_no]] << {tbl: tbl, key: key, entry: entry}
235
+ end
236
+ end
237
+ end
238
+ end
239
+ return tmpdb
240
+ end
241
+
162
242
  def add_file(file)
163
243
  return if not File.file? file
164
244
 
@@ -170,7 +250,7 @@ END
170
250
  key = key.to_sym
171
251
  @tables[tbl] ||= {}
172
252
  @tables[tbl][key] ||= []
173
- @tables[tbl][key] << StarScope::Datum.build(file, args)
253
+ @tables[tbl][key] << StarScope::Datum.build(file, key, args)
174
254
  end
175
255
  end
176
256
  end
@@ -1,6 +1,6 @@
1
1
  module StarScope::Lang
2
2
  module Go
3
- FUNC_CALL = /([\w\.]+?)\(.*\)/
3
+ FUNC_CALL = /([\w\.]*?\w)\(.*\)/
4
4
  BUILTIN_FUNCS = ['new', 'make', 'len', 'close', 'copy', 'delete',
5
5
  'int', 'int8', 'int16', 'int32', 'int64',
6
6
  'uint', 'uint8', 'uint16', 'uint32', 'uint64',
@@ -14,6 +14,7 @@ module StarScope::Lang
14
14
  stack = []
15
15
  scope = []
16
16
  str = File.readlines(file).each_with_index do |line, line_no|
17
+ line_no += 1 # zero-index to one-index
17
18
  # strip single-line comments like // foo
18
19
  match = /(.*)\/\//.match(line)
19
20
  if match
@@ -47,23 +48,25 @@ module StarScope::Lang
47
48
  when :struct
48
49
  case line
49
50
  when /\s*(\w+)\s+\w+/
50
- yield :defs, $1, line_no: line_no+1, scope: scope
51
+ yield :defs, $1, line_no: line_no, scope: scope
51
52
  when /}/
53
+ yield :end, "}", line_no: line_no, scope: scope, type: :class
52
54
  stack.pop
53
55
  scope.pop
54
56
  end
55
57
  when :interface
56
58
  case line
57
59
  when /\s*(\w+)\(.*\)\s+/
58
- yield :defs, $1, line_no: line_no+1, scope: scope
60
+ yield :defs, $1, line_no: line_no, scope: scope
59
61
  when /}/
62
+ yield :end, "}", line_no: line_no, scope: scope, type: :class
60
63
  stack.pop
61
64
  scope.pop
62
65
  end
63
66
  when :def
64
67
  case line
65
68
  when /\s*(\w+)\s+/
66
- yield :defs, $1, line_no: line_no+1, scope: scope
69
+ yield :defs, $1, line_no: line_no, scope: scope
67
70
  when /\)/
68
71
  stack.pop
69
72
  end
@@ -71,56 +74,57 @@ module StarScope::Lang
71
74
  case line
72
75
  when /"(.+)"/
73
76
  name = $1.split('/')
74
- yield :imports, name[-1], line_no: line_no+1, scope: name[0...-1]
77
+ yield :imports, name[-1], line_no: line_no, scope: name[0...-1]
75
78
  when /\)/
76
79
  stack.pop
77
80
  end
78
81
  else
79
82
  if stack[-1] == :func and /^}/ =~ line
83
+ yield :end, "}", line_no: line_no, type: :func
80
84
  stack.pop
81
85
  end
82
86
  case line
83
87
  when /^func\s+(\w+)\(/
84
- yield :defs, $1, line_no: line_no+1, scope: scope
88
+ yield :defs, $1, line_no: line_no, scope: scope, type: :func
85
89
  stack.push(:func)
86
90
  when /^func\s+\(\w+\s+\*?(\w+)\)\s*(\w+)\(/
87
- yield :defs, $2, line_no: line_no+1, scope: scope + [$1]
91
+ yield :defs, $2, line_no: line_no, scope: scope + [$1], type: :func
88
92
  stack.push(:func)
89
93
  when /^package\s+(\w+)/
90
- yield :defs, $1, line_no: line_no+1, scope: scope
94
+ yield :defs, $1, line_no: line_no, scope: scope, type: :package
91
95
  scope.push($1)
92
96
  when /^type\s+(\w+)\s+struct\s*{/
93
- yield :defs, $1, line_no: line_no+1, scope: scope
97
+ yield :defs, $1, line_no: line_no, scope: scope, type: :class
94
98
  scope.push($1)
95
99
  stack.push(:struct)
96
100
  when /^type\s+(\w+)\s+interface\s*{/
97
- yield :defs, $1, line_no: line_no+1, scope: scope
101
+ yield :defs, $1, line_no: line_no, scope: scope, type: :class
98
102
  scope.push($1)
99
103
  stack.push(:interface)
100
104
  when /^type\s+(\w+)/
101
- yield :defs, $1, line_no: line_no+1, scope: scope
105
+ yield :defs, $1, line_no: line_no, scope: scope, type: :type
102
106
  when /^import\s+"(.+)"/
103
107
  name = $1.split('/')
104
- yield :imports, name[-1], line_no: line_no+1, scope: name[0...-1]
108
+ yield :imports, name[-1], line_no: line_no, scope: name[0...-1]
105
109
  when /^import\s+\(/
106
110
  stack.push(:import)
107
111
  when /^var\s+\(/
108
112
  stack.push(:def)
109
113
  when /^var\s+(\w+)\s+\w+/
110
- yield :defs, $1, line_no: line_no+1, scope: scope
114
+ yield :defs, $1, line_no: line_no, scope: scope
111
115
  when /^const\s+\(/
112
116
  stack.push(:def)
113
117
  when /^const\s+(\w+)\s+\w+/
114
- yield :defs, $1, line_no: line_no+1, scope: scope
118
+ yield :defs, $1, line_no: line_no, scope: scope
115
119
  when /^\s+(.*?) :?= ((.*?)\(.*\))?/
116
120
  $1.split(',').each do |var|
117
121
  var = var.strip
118
122
  name = var.split('.')
119
123
  case name.length
120
124
  when 1
121
- yield :assigns, name[0], line_no: line_no+1, scope: scope
125
+ yield :assigns, name[0], line_no: line_no, scope: scope
122
126
  when 2
123
- yield :assigns, name[1], line_no: line_no+1, scope: [name[0]]
127
+ yield :assigns, name[1], line_no: line_no, scope: [name[0]]
124
128
  end
125
129
  end
126
130
  if $2
@@ -149,12 +153,12 @@ module StarScope::Lang
149
153
  when 1
150
154
  return nil if name[0] == 'func'
151
155
  if BUILTIN_FUNCS.include?(name[0])
152
- return :calls, name[0], line_no: line_no+1
156
+ return :calls, name[0], line_no: line_no
153
157
  else
154
- return :calls, name[0], line_no: line_no+1, scope: scope
158
+ return :calls, name[0], line_no: line_no, scope: scope
155
159
  end
156
160
  else
157
- return :calls, name[-1], line_no: line_no+1, scope: name[0...-1]
161
+ return :calls, name[-1], line_no: line_no, scope: name[0...-1]
158
162
  end
159
163
  end
160
164
  end
@@ -59,15 +59,18 @@ module StarScope::Lang
59
59
  when :def
60
60
  yield :defs, node.children[0],
61
61
  line_no: node.location.expression.line,
62
- scope: @scope
62
+ scope: @scope, type: :func
63
+ yield :end, :end, line_no: node.location.end.line, type: :func
63
64
  when :defs
64
65
  yield :defs, node.children[1],
65
66
  line_no: node.location.expression.line,
66
- scope: @scope
67
+ scope: @scope, type: :func
68
+ yield :end, :end, line_no: node.location.end.line, type: :func
67
69
  when :module, :class
68
70
  fqn = @scope + scoped_name(node.children[0])
69
71
  yield :defs, fqn.last, line_no: node.location.expression.line,
70
- scope: fqn[0...-1]
72
+ scope: fqn[0...-1], type: node.type
73
+ yield :end, :end, line_no: node.location.end.line, type: node.type
71
74
  when :casgn
72
75
  fqn = scoped_name(node)
73
76
  yield :assigns, fqn.last,
@@ -1,3 +1,3 @@
1
1
  module StarScope
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
data/starscope.gemspec CHANGED
@@ -13,9 +13,9 @@ Gem::Specification.new do |gem|
13
13
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
14
14
  gem.require_paths = ["lib"]
15
15
 
16
- gem.add_dependency 'oj', '~> 2.1'
17
- gem.add_dependency 'parser', '~> 2.0'
18
- gem.add_dependency 'ruby-progressbar', '~> 1.2'
16
+ gem.add_dependency 'oj', '~> 2.5'
17
+ gem.add_dependency 'parser', '~> 2.1'
18
+ gem.add_dependency 'ruby-progressbar', '~> 1.4'
19
19
  gem.add_development_dependency 'bundler', '~> 1.3'
20
20
  gem.add_development_dependency 'rake'
21
21
  gem.add_development_dependency 'pry'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: starscope
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-15 00:00:00.000000000 Z
12
+ date: 2014-01-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: oj
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: '2.1'
21
+ version: '2.5'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: '2.1'
29
+ version: '2.5'
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: parser
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -34,7 +34,7 @@ dependencies:
34
34
  requirements:
35
35
  - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: '2.0'
37
+ version: '2.1'
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +42,7 @@ dependencies:
42
42
  requirements:
43
43
  - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: '2.0'
45
+ version: '2.1'
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: ruby-progressbar
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ~>
52
52
  - !ruby/object:Gem::Version
53
- version: '1.2'
53
+ version: '1.4'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
@@ -58,7 +58,7 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: '1.2'
61
+ version: '1.4'
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: bundler
64
64
  requirement: !ruby/object:Gem::Requirement