Skip to content

Commit

Permalink
A little bit of refactor, add smalltalk syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
manveru committed Jun 25, 2009
1 parent 1536ae9 commit f490840
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 29 deletions.
5 changes: 4 additions & 1 deletion bin/sloc
@@ -1,5 +1,6 @@
#!/usr/bin/env ruby

require 'pathname'
require 'optparse'
require 'ostruct'

Expand All @@ -13,7 +14,9 @@ require_sloc = lambda{
begin
require 'sloc'
rescue LoadError
$LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
file = Pathname(__FILE__)
file = file.readlink if file.symlink?
$LOAD_PATH.unshift(File.expand_path('../../lib', file))
require 'sloc'
end
}
Expand Down
51 changes: 26 additions & 25 deletions lib/sloc.rb
Expand Up @@ -7,17 +7,25 @@
module SLOC
GRAMMAR_ROOT = File.expand_path('../sloc/grammar/', __FILE__)

COUNTERS_NAMES = {
:ruby => 'RubyParser',
:sh => 'ShParser',
:lisp => 'LispParser',
}
SYNTAX_LIST = {}
COUNTER_CACHE = {}

module_function

def counter_for(type)
if name = COUNTERS_NAMES[type]
Counter.new(type.to_s, name)
def syntax(name, ext, shebang = nil)
SYNTAX_LIST[name] = [ext, shebang]
end

# name ext shebang
syntax :ruby, /\.(rb|rake)$/, /ruby/
syntax :sh, /\.(sh|zsh)/, /sh|zsh|bash/
syntax :lisp, /\.lisp/, /lisp|scheme|sbcl/
syntax :smalltalk, /\.st/, /gst/
syntax :javascript, /\.js/, /js/

def counter_for(name)
if found = SYNTAX_LIST[name]
COUNTER_CACHE[name] ||= Counter.new(name.to_s, "#{name.to_s.capitalize}Parser")
end
end

Expand All @@ -34,29 +42,26 @@ def glob(globname)
total
end

def file(filename, override_type = nil)
def file(filename, override_name = nil)
path = Pathname(filename.to_s)
path = path.readlink if path.symlink?

return unless path.file?

type = override_type || detect_ext(path) || detect_shebang(path)
name = override_name || detect_ext(path) || detect_shebang(path)

if counter = counter_for(type)
if counter = counter_for(name)
count = counter.file(path)
yield count if count && block_given?
count
end
end

def detect_ext(path)
case path.extname
when /\.(rb|rake)$/
:ruby
when /\.(sh|zsh)$/
:sh
when /\.(lisp)/
:lisp
extname = path.extname

SYNTAX_LIST.find do |key, (ext, shebang)|
return key if extname =~ ext
end
end

Expand All @@ -65,14 +70,10 @@ def detect_shebang(path)
return unless shebang && shebang.valid_encoding?

if shebang =~ /^#!/
case shebang
when /ruby/
:ruby
when /zsh/
:sh
else
warn "Unknown ext of %p, shebang detection for %p failed as well." % [path.to_s, shebang]
SYNTAX_LIST.find do |key, (ext, l_shebang)|
return key if shebang && shebang =~ l_shebang
end
warn "Unknown ext of %p, shebang detection for %p failed as well." % [path.to_s, shebang]
else
warn "Unknown ext of %p, no shebang found." % [path.to_s]
end
Expand Down
18 changes: 15 additions & 3 deletions lib/sloc/counter.rb
Expand Up @@ -4,7 +4,7 @@ module SLOC
class Counter
def initialize(file, name)
Treetop.load(File.join(GRAMMAR_ROOT, "#{file}.tt"))
@parser = Module.const_get(name).new
@parser_class = Module.const_get(name)
rescue NameError
Treetop.load(File.join(GRAMMAR_ROOT, "common.tt"))
retry
Expand All @@ -19,17 +19,29 @@ def glob(*files)
end

def file(file, total = Hash.new(0))
SLOC.aggregate(@parser.parse(File.read(file)).count, total)
SLOC.aggregate(count(File.read(file)), total)
rescue => ex
p ex
raise "In #{file} - #{@parser.failure_reason}"
end

def string(string, total = Hash.new(0))
SLOC.aggregate(@parser.parse(string).count, total)
SLOC.aggregate(count(string), total)
rescue => ex
p ex
raise @parser.failure_reason.dump
end

private

def count(string)
@parser = @parser_class.new
@parser.parse(string).count
ensure
count_objects = ObjectSpace.count_objects
total, free = count_objects.values_at(:TOTAL, :FREE)
@parser = nil
GC.start if free < 524288
end
end
end
11 changes: 11 additions & 0 deletions lib/sloc/grammar/javascript.tt
@@ -0,0 +1,11 @@
grammar Javascript
include Common

rule file
lines
end

rule comment_token
'//'
end
end
23 changes: 23 additions & 0 deletions lib/sloc/grammar/smalltalk.tt
@@ -0,0 +1,23 @@
grammar Smalltalk
include Common

rule file
lines
end

rule code
('$"' / [^"])+ {
def count
{code: text_value.count("\n")}
end
}
end

rule comment
'"' (!'"' .)* '"' {
def count
{comment: text_value.count("\n")}
end
}
end
end

0 comments on commit f490840

Please sign in to comment.