fiveruns / brigit

Git utilities for multiple repositories & submodules

This URL has Read+Write access

brigit / lib / brigit / config_parser.rb
d8894e6a » bruce 2008-07-06 Initial commit 1 module Brigit
2
3 # Reworked from Sam Ruby's Ruby "PythonConfigParser," http://intertwingly.net/code/mars/planet/config.rb
4 # which in turn is a port of Python's ConfigParser, http://docs.python.org/lib/module-ConfigParser.html
5 class ConfigParser
6
7 class Section
8
9 attr_reader :name
10 def initialize(name)
11 @name = name
12 end
13
14 def options
15 @options ||= {}
16 end
17
18 def method_missing(*args, &block)
19 options.__send__(*args, &block)
20 end
21
22 end
de8569e8 » bruce 2008-07-07 Add `grab' command to clone... 23
24 def self.section_pattern
25 @section_pattern ||= /
26 \[ # [
27 ([^\]]+) # very permissive!
28 \] # ]
29 /x
30 end
31
32 def self.option_pattern
33 @option_pattern ||= /
34 ([^:=\s][^:=]*) # very permissive!
35 \s*[:=]\s* # any number of space chars,
36 # followed by separator
37 # (either : or =), followed
38 # by any # space chars
39 (.*)$ # everything up to eol
40 /x
41 end
d8894e6a » bruce 2008-07-06 Initial commit 42
43
44 # FIXME: This is *way* ugly
45 def parse(lines)
46 sections = Hash.new { |_, name| Section.new(name) }
47 section = nil
48 option = nil
49 lines.each_with_index do |line, number|
50 next if skip? line
de8569e8 » bruce 2008-07-07 Add `grab' command to clone... 51 if line =~ self.class.option_pattern
d8894e6a » bruce 2008-07-06 Initial commit 52 # option line
53 option, value = $1, $2
54 option = option.downcase.strip
55 value.sub!(/\s;.*/, '')
56 value = '' if value == '""'
57 section[option] = clean value
58 elsif line =~ /^\s/ && section && option
59 # continuation line
60 value = line.strip
61 section[option] = section[option] ? (section[option] << "\n#{clean value}") : clean(value)
de8569e8 » bruce 2008-07-07 Add `grab' command to clone... 62 elsif line =~ self.class.section_pattern
d8894e6a » bruce 2008-07-06 Initial commit 63 section = sections[$1]
64 sections[$1] = section
65 option = nil
66 elsif !section
67 raise SyntaxError, 'Missing section header'
68 else
69 raise SyntaxError, "Invalid syntax on line #{number}"
70 end
71 end
72 sections
73 end
74
75 #######
76 private
77 #######
78
79 def clean(value)
80 value.sub(/\s*#.*/, '')
81 end
82
83 def skip?(line)
84 line.strip.empty? || line =~ /^\s*[#;]/ || line =~ /^rem(\s|$)/i
85 end
86
87 end
88
89 end
90