Skip to content

Instantly share code, notes, and snippets.

@swillits
Created March 4, 2017 21:40
Show Gist options
  • Save swillits/addbe0b6c31ed09c95e0c9c4c50ed054 to your computer and use it in GitHub Desktop.
Save swillits/addbe0b6c31ed09c95e0c9c4c50ed054 to your computer and use it in GitHub Desktop.
#!/usr/bin/ruby
# Keith Bauer made this.
require 'find'
require 'getoptlong'
EXTS = Regexp.compile('^.*\.(' + %w[
h hh hpp H
c cc cpp cxx C
m mm M
rb py pl sh
lua
scm hs lisp
java
swift].join('|') + ')$')
OPTS = [
[ '--exclude', '-x', GetoptLong::REQUIRED_ARGUMENT ],
[ '--no-blank-lines', '-n', GetoptLong::NO_ARGUMENT ],
[ '--help', '-h', GetoptLong::NO_ARGUMENT ]]
HELP = {
'--exclude' => {
:argument_placeholder => 'pattern',
:help_text => 'exclude files matching glob pattern <pattern>'
},
'--no-blank-lines' => {
:help_text => "don't count blank lines in source files"
},
'--help' => {
:help_text => "this help text"
}
}
opts = GetoptLong.new(*OPTS)
REGEXP_METACHARACTERS = '\\$^*(){}+.?'
exclusions = nil
blank_lines = true
opts.each do |opt, arg|
if opt == '--exclude' then
re = ''
arg.each_byte do |b|
if b == ?* then
re += '.*'
elsif b == ?? then
re += '.'
else
if REGEXP_METACHARACTERS.include?(b) then
re += '\\'
end
re << b
end
end
re += '$'
if exclusions then
exclusions += "|(#{re})"
else
exclusions = "(#{re})"
end
elsif opt == '--no-blank-lines' then
blank_lines = false
elsif opt == '--help' then
puts "Usage: #{$0} [options] [paths to search]\n\nOptions:"
puts OPTS.map { |option|
if option[-1] == GetoptLong::REQUIRED_ARGUMENT then
joiner = " <#{HELP[option[0]][:argument_placeholder]}>\n "
elsif option[-1] == GetoptLong::OPTIONAL_ARGUMENT then
joiner = " [#{HELP[option[0]][:argument_placeholder]}]\n "
elsif option[-1] == GetoptLong::NO_ARGUMENT then
joiner = "\n "
end
" " + option[0..-2].map { |o| o + joiner }.join +
" " + HELP[option[0]][:help_text] + "\n"
}.join("\n")
puts
exit
end
end
if ARGV.size == 0 then
ARGV << '.'
end
exclusions_re = if exclusions then Regexp.compile(exclusions) else nil end
lc = 0
ARGV.each do |root|
Find.find(root) do |path|
if exclusions_re && exclusions_re =~ path then
Find.prune
next
end
if EXTS =~ path then
begin
File.read(path).each_line do |line|
unless line == "\n" && !blank_lines then
lc += 1
end
end
rescue => e
$stderr.puts(e)
end
end
end
end
puts lc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment