class ReVIEW::Preprocessor
Constants
- INF_INDENT
- KNOWN_DIRECTIVES
- TYPES
Public Class Methods
new(repo, param)
click to toggle source
# File lib/review/preprocessor.rb, line 80 def initialize(repo, param) @repository = repo @config = param @logger = ReVIEW.logger end
strip(f)
click to toggle source
# File lib/review/preprocessor.rb, line 46 def self.strip(f) buf = '' Strip.new(f).each { |line| buf << line.rstrip << "\n" } buf end
Public Instance Methods
process(inf, outf)
click to toggle source
# File lib/review/preprocessor.rb, line 86 def process(inf, outf) init_errorutils inf @f = outf begin preproc inf rescue Errno::ENOENT => err error err.message end end
Private Instance Methods
defvar(name, value)
click to toggle source
# File lib/review/preprocessor.rb, line 260 def defvar(name, value) @vartable[name] = value end
evaluate(path, chunk)
click to toggle source
# File lib/review/preprocessor.rb, line 284 def evaluate(path, chunk) outputs = get_output("ruby #{path}", false).split(/\n/).map(&:strip) chunk.map do |line| if /\# \$\d+/ =~ line.string # map result into source. line.edit { |s| s.sub(/\$(\d+)/) { outputs[$1.to_i - 1] } } else line end end end
expand(str)
click to toggle source
# File lib/review/preprocessor.rb, line 264 def expand(str) str.gsub(/\$\w+/) do |name| s = @vartable[name.sub('$', '')] s ? expand(s) : name end end
get_output(cmd, use_stderr)
click to toggle source
# File lib/review/preprocessor.rb, line 298 def get_output(cmd, use_stderr) out = err = nil Open3.popen3(cmd) do |_stdin, stdout, stderr| out = stdout.readlines if use_stderr out.concat stderr.readlines else err = stderr.readlines end end if err and !err.empty? $stderr.puts '[unexpected stderr message]' err.each { |line| $stderr.print line } error 'get_output: got unexpected output' end num = 0 out.map { |line| Line.new(num += 1, line) } end
init_vars()
click to toggle source
# File lib/review/preprocessor.rb, line 256 def init_vars @vartable = {} end
known_directive?(op)
click to toggle source
# File lib/review/preprocessor.rb, line 151 def known_directive?(op) KNOWN_DIRECTIVES.index(op) end
minimum_indent(chunk)
click to toggle source
# File lib/review/preprocessor.rb, line 279 def minimum_indent(chunk) n = chunk.map { |line| line.empty? ? INF_INDENT : line.num_indent }.min n == INF_INDENT ? 0 : n end
optarg_value(spec)
click to toggle source
# File lib/review/preprocessor.rb, line 244 def optarg_value(spec) case spec when 'true' then true # [name=true] when 'false' then false # [name=false] when 'nil' then nil # [name=nil] when nil then true # [name] when /^\d+$/ then $&.to_i # [name=8] else # [name=val] spec end end
parse_directive(line, argc, *optdecl)
click to toggle source
# File lib/review/preprocessor.rb, line 213 def parse_directive(line, argc, *optdecl) m = /\A\#@(\w+)\((.*?)\)(?:\[(.*?)\])?\z/.match(line.strip) or error "wrong directive: #{line.strip}" op = m[1] args = m[2].split(/,\s*/) opts = parse_optargs(m[3]) return if argc == 0 and args.empty? if argc == -1 # Any number of arguments are allowed. elsif args.size != argc error 'wrong arg size' end if opts wrong_opts = opts.keys - optdecl unless wrong_opts.empty? error "wrong option: #{wrong_opts.keys.join(' ')}" end end Directive.new(op, args, opts || {}) end
parse_optargs(str)
click to toggle source
# File lib/review/preprocessor.rb, line 234 def parse_optargs(str) return nil unless str table = {} str.split(/,\s*/).each do |a| name, spec = a.split('=', 2) table[name] = optarg_value(spec) end table end
preproc(f)
click to toggle source
# File lib/review/preprocessor.rb, line 100 def preproc(f) init_vars f.each_line do |line| case line when /\A\#@\#/, /\A\#\#\#\#/ @f.print line when /\A\#@defvar/ @f.print line direc = parse_directive(line, 2) defvar(*direc.args) when /\A\#@mapoutput/ direc = parse_directive(line, 1, 'stderr') @f.print line get_output(expand(direc.arg), direc['stderr']).each { |out| @f.print out.string } skip_list f when /\A\#@mapfile/ direc = parse_directive(line, 1, 'eval') path = expand(direc.arg) ent = @repository.fetch_file(path) ent = evaluate(path, ent) if direc['eval'] replace_block(f, line, ent, false) # FIXME: turn off lineno: tmp when /\A\#@map(?:range)?/ direc = parse_directive(line, 2, 'unindent') path = expand(direc.args[0]) ent = @repository.fetch_range(path, direc.args[1]) or error "unknown range: #{path}: #{direc.args[1]}" ent = (direc['unindent'] ? unindent(ent, direc['unindent']) : ent) replace_block(f, line, ent, false) # FIXME: turn off lineno: tmp when /\A\#@end/ error 'unbaranced #@end' when /\A\#@/ op = line.slice(/@(\w+)/, 1) warn "unknown directive: #{line.strip}" unless known_directive?(op) @f.print line when /\A\s*\z/ # empty line @f.puts else @f.print line end end end
print_number(num)
click to toggle source
# File lib/review/preprocessor.rb, line 164 def print_number(num) @f.printf '%4s ', (num ? num.to_s : '') end
replace_block(f, directive_line, newlines, with_lineno)
click to toggle source
# File lib/review/preprocessor.rb, line 155 def replace_block(f, directive_line, newlines, with_lineno) @f.print directive_line newlines.each do |line| print_number line.number if with_lineno @f.print line.string end skip_list f end
skip_list(f)
click to toggle source
# File lib/review/preprocessor.rb, line 168 def skip_list(f) begline = f.lineno f.each_line do |line| case line when /\A\#@end/ @f.print line return nil when %r{\A//\}} warn '//} seen in list' @f.print line return nil when /\A\#@\w/ warn "#{line.slice(/\A\#@\w+/)} seen in list" @f.print line when /\A\#@/ @f.print line end end error "list reached end of file (beginning line = #{begline})" end
unindent(chunk, n)
click to toggle source
# File lib/review/preprocessor.rb, line 271 def unindent(chunk, n) n = minimum_indent(chunk) unless n.is_a?(Integer) re = /\A#{' ' * n}/ chunk.map { |line| line.edit { |s| s.sub(re, '') } } end