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 93 def initialize(repo, param) @repository = repo @config = param end
strip(f)
click to toggle source
# File lib/review/preprocessor.rb, line 54 def Preprocessor.strip(f) buf = '' Strip.new(f).each do |line| buf << line.rstrip << "\n" end buf end
Public Instance Methods
process(inf, outf)
click to toggle source
# File lib/review/preprocessor.rb, line 98 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 275 def defvar(name, value) @vartable[name] = value end
evaluate(path, chunk)
click to toggle source
# File lib/review/preprocessor.rb, line 299 def evaluate(path, chunk) outputs = get_output("ruby #{path}", false).split(/\n/).map {|s| s.strip } chunk.map {|line| if /\# \$\d+/ =~ line.string # map result into source. line.edit {|s| s.sub(/\$(\d+)/) { outputs[$1.to_i - 1] } } else line end } end
expand(str)
click to toggle source
# File lib/review/preprocessor.rb, line 279 def expand(str) str.gsub(/\$\w+/) {|name| s = @vartable[name.sub('$', '')] s ? expand(s) : name } end
get_output(cmd, use_stderr)
click to toggle source
# File lib/review/preprocessor.rb, line 315 def get_output(cmd, use_stderr) out = err = nil Open3.popen3(cmd) {|stdin, stdout, stderr| out = stdout.readlines if use_stderr out.concat stderr.readlines else err = stderr.readlines end } if err and !err.empty? $stderr.puts "[unexpected stderr message]" err.each do |line| $stderr.print line end 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 271 def init_vars @vartable = {} end
known_directive?(op)
click to toggle source
# File lib/review/preprocessor.rb, line 166 def known_directive?(op) KNOWN_DIRECTIVES.index(op) end
minimum_indent(chunk)
click to toggle source
# File lib/review/preprocessor.rb, line 294 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 259 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 228 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 249 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 112 def preproc(f) init_vars while line = f.gets 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 do |out| @f.print out.string end 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) #error "unkown directive: #{line.strip}" unless known_directive?(op) warn "unkown 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 179 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 170 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 183 def skip_list(f) begline = f.lineno while line = f.gets case line when %r[\A\#@end] @f.print line return when %r[\A//\}] warn '//} seen in list' @f.print line return when %r[\A\#@\w] warn "#{line.slice(/\A\#@\w+/)} seen in list" @f.print line when %r[\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 286 def unindent(chunk, n) n = minimum_indent(chunk) unless n.kind_of?(Integer) re = /\A#{' ' * n}/ chunk.map {|line| line.edit {|s| s.sub(re,'') } } end