~ubuntu-branches/ubuntu/intrepid/prewikka/intrepid

« back to all changes in this revision

Viewing changes to prewikka/MyConfigParser.py

  • Committer: Bazaar Package Importer
  • Author(s): Pierre Chifflier
  • Date: 2007-04-11 14:41:09 UTC
  • Revision ID: james.westby@ubuntu.com-20070411144109-2hh7zx3amwd27b4l
Tags: upstream-0.9.10
ImportĀ upstreamĀ versionĀ 0.9.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2004,2005 PreludeIDS Technologies. All Rights Reserved.
 
2
# Author: Nicolas Delon <nicolas.delon@prelude-ids.com>
 
3
#
 
4
# This file is part of the Prewikka program.
 
5
#
 
6
# This program is free software; you can redistribute it and/or modify
 
7
# it under the terms of the GNU General Public License as published by
 
8
# the Free Software Foundation; either version 2, or (at your option)
 
9
# any later version.
 
10
#
 
11
# This program is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU General Public License for more details.
 
15
#
 
16
# You should have received a copy of the GNU General Public License
 
17
# along with this program; see the file COPYING.  If not, write to
 
18
# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
 
 
20
 
 
21
import re
 
22
 
 
23
class Error(Exception):
 
24
    pass
 
25
 
 
26
 
 
27
 
 
28
class ParseError(Error):
 
29
    def __init__(self, filename, lineno, line):
 
30
        self.filename = filename
 
31
        self.lineno = lineno
 
32
        self.line = line
 
33
 
 
34
    def __str__(self):
 
35
        return "parse error in \"%s\" at %s line %d" % (self.line.rstrip(), self.filename, self.lineno)
 
36
 
 
37
 
 
38
 
 
39
class OrderedDict(dict):
 
40
    def __init__(self):
 
41
        dict.__init__(self)
 
42
        self.ordered_key_list = [ ]
 
43
 
 
44
    def __delitem__(self, key):
 
45
        dict.__delitem__(self, key)
 
46
        self.ordered_key_list.remove(key)
 
47
 
 
48
    def __setitem__(self, key, value):
 
49
        dict.__setitem__(self, key, value)
 
50
        if not key in self.ordered_key_list:
 
51
            self.ordered_key_list.append(key)
 
52
 
 
53
    def values(self):
 
54
        return map(lambda k: self[k], self.ordered_key_list)
 
55
 
 
56
    def keys(self):
 
57
        return self.ordered_key_list
 
58
 
 
59
    def items(self):
 
60
        return map(lambda key: (key, self[key]), self.ordered_key_list)
 
61
    
 
62
    def copy(self):
 
63
        new = OrderedDict()
 
64
        for key in self.keys():
 
65
            new[key] = self[key]
 
66
        return new
 
67
 
 
68
 
 
69
 
 
70
class ConfigParserSection(OrderedDict):
 
71
    def __init__(self, name):
 
72
        OrderedDict.__init__(self)
 
73
        self.name = name
 
74
 
 
75
    def __nonzero__(self):
 
76
        return True
 
77
 
 
78
    def getOption(self, name):
 
79
        return self[name]
 
80
 
 
81
    def getOptionValue(self, key, value=None):
 
82
        try:
 
83
            return self[key].value
 
84
        except KeyError:
 
85
            return value
 
86
    
 
87
    def getOptions(self):
 
88
        return self.values()
 
89
 
 
90
 
 
91
 
 
92
class ConfigParserOption:
 
93
    def __init__(self, name, value, lineno, line):
 
94
        self.name = name
 
95
        self.value = value
 
96
        self.lineno = lineno
 
97
        self.line = line
 
98
 
 
99
 
 
100
 
 
101
class MyConfigParser:
 
102
    """
 
103
    A config parser class ala ConfigParser.ConfigParser (only read operations
 
104
    are (will be) supported).
 
105
    ConfigParser.ConfigParser did not feed all our needs:
 
106
    - we need the '= value' part of option to be optionnal
 
107
    - we need to support special characters (like ':') in option name (for urls)
 
108
    - we need to keep the right order of options in sections (this is done via
 
109
      the OrderedDict class that subclass dict)
 
110
    """
 
111
    
 
112
    EMPTY_LINE_REGEXP = re.compile("^\s*(\#.*)?$")
 
113
    SECTION_REGEXP = re.compile("\[(?P<name>.+)]")
 
114
    OPTION_REGEXP = re.compile("^\s*(?P<name>[\s]*[^:]+)(\:\s*(?P<value>.+))?$")
 
115
 
 
116
    def __init__(self, filename):
 
117
        self.filename = filename
 
118
        self._sections = OrderedDict()
 
119
        self._root_section = OrderedDict()
 
120
        self._current_section = self._root_section
 
121
 
 
122
    def load(self):
 
123
        lineno = 0
 
124
        
 
125
        for line in open(self.filename).readlines():
 
126
            lineno += 1
 
127
            result = self.EMPTY_LINE_REGEXP.match(line)
 
128
            if result:
 
129
                continue
 
130
            else:
 
131
                result = self.SECTION_REGEXP.match(line)
 
132
                if result:
 
133
                    name = result.group("name")
 
134
                    name = name.strip()
 
135
                    self._current_section = self._sections[name] = ConfigParserSection(name)
 
136
                else:
 
137
                    result = self.OPTION_REGEXP.match(line)
 
138
                    if result:
 
139
                        name, value = result.group("name", "value")
 
140
                        name = name.strip()
 
141
                        if value:
 
142
                            value = value.strip()
 
143
                        self._current_section[name] = ConfigParserOption(name, value, lineno, line)
 
144
                    else:
 
145
                        raise ParseError(file.name, lineno, line)
 
146
    
 
147
    def getSection(self, name):
 
148
        return self._sections[name]
 
149
 
 
150
    def getSections(self):
 
151
        return self._sections.values()
 
152
 
 
153
    def __str__(self):
 
154
        content = ""
 
155
        for section in self.getSections():
 
156
            content += "[%s]\n" % section.name
 
157
            for option in section.getOptions():
 
158
                content += "%s: %s\n" % (option.name, option.value)
 
159
            content += "\n"
 
160
            
 
161
        return content