Skip to content

Instantly share code, notes, and snippets.

@alesya-h
Created December 12, 2012 14:51
Show Gist options
  • Save alesya-h/4268343 to your computer and use it in GitHub Desktop.
Save alesya-h/4268343 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
RubyVM::InstructionSequence.compile_option = {tailcall_optimization: true, trace_instruction: false}
def parse_line(line)
case line.strip
when /^\s*\[\s*(.+?)\s*\]\s*$/ then {section: $1}
when /^\s*(.+?)\s*=\s*(.+?)\s*$/ then {key: $1, value: $2}
when /^\s*$/ then {}
else {error: line}
end
end
def read(content)
content.gsub(/\\\s*\n\s*/, "").split("\n")
end
def parse_conf(lines, section="default", res={})
return res if lines.empty?
l = parse_line(lines.shift)
if l[:section]
parse_conf(lines, l[:section], res)
elsif (k = l[:key] and v = l[:value])
res[section] ||= {}
res[section][k] = v
parse_conf(lines, section, res)
elsif l[:error]
STDERR.puts "Bad line: #{l[:error]}"
parse_conf(lines, section, res)
else parse_conf(lines, section, res)
end
end
require 'minitest/spec'
require 'minitest/autorun'
describe :read do
it "should drop line wraps" do
{ "abc \\ \n def" => ["abc def"],
"abc\\\n def" => ["abcdef"],
"abc\\\ndef" => ["abcdef"],
"abc\\\n" => ["abc"],
"abc\\\n" => ["abc"],
"abc\\\ndef\\\n" => ["abcdef"]
}.each do |k,v|
read(k).must_equal v
end
end
it "shouldn't drop last line wraps" do
{ "abc\\" => ["abc\\"],
"abc\\\ndef\\" => ["abcdef\\"]
}.each do |k,v|
read(k).must_equal v
end
end
end
describe :parse_line do
it "should parse key-value pairs" do
{ "k=v" => {key:"k", value:"v"},
" k = v " => {key:"k", value:"v"},
"k=v=v1=v2" => {key:"k", value:"v=v1=v2"}
}.each do |k,v|
parse_line(k).must_equal v
end
end
it "should parse sections" do
{ "[sec]" => {section:"sec"},
" [ s e c ] " => {section:"s e c"},
" [ k = v ] " => {section:"k = v"}
}.each do |k,v|
parse_line(k).must_equal v
end
end
it "should detect format errors" do
{ "[sec" => {error:"[sec"},
"sec]" => {error:"sec]"},
"k" => {error:"k"},
"k = " => {error:"k = "},
" " => {}
}.each do |k,v|
parse_line(k).must_equal v
end
end
end
describe :parse_conf do
it "should parse complete configs" do
{ ["k=v"] => {"default" => {"k" => "v"}},
["k=v", "x=y"] => {"default" => {"k" => "v", "x" => "y"}},
["k=v", "k=v1"] => {"default" => {"k" => "v1"}},
["[s1]", "k=v", "[s2]", "x=y"] => {"s1" => {"k" => "v"}, "s2" => {"x" => "y"}},
["[s1]", "k=v", "", "[s2]", "k=w", "", "[s1]", "l=u"] => {"s1" => {"k" => "v", "l" => "u"}, "s2" => {"k" => "w"}},
["[s1]", "k=v", "[s2]", "k=w", "[s1]", "k=v1"] => {"s1" => {"k" => "v1"}, "s2" => {"k" => "w"}}
}.each do |k,v|
parse_conf(k).must_equal v
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment