1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
import re
import tempfile
import os
CommentRe = re.compile('\s*(#|$)')
ParseRe = re.compile('\s*(\S+):\s+(.*\S)\s+$')
class SimpleCfgError(Exception):
pass
class SimpleCfg(dict):
"""
Read/write support for a simple config file format.
Entries can be of the form "key: value".
"#" comments are supported. Whitespace-only lines are ignored.
"""
def __init__(self, *a, **kw):
dict.__init__(self, *a, **kw)
self.klist = dict.keys(self)
def __setitem__(self, k, v):
k = k.replace('-', '_')
if not k in self:
self.klist.append(k)
dict.__setitem__(self, k, v)
def __iter__(self):
return self.klist.__iter__()
def keys(self):
return self.klist
def pop(self, key, *a):
e = dict.pop(self, key, *a)
self.klist.remove(key)
return e
def readstream(self, s):
while True:
l = s.readline()
if not l:
break
m = ParseRe.match(l)
if m:
k, v = m.groups()
self[k] = v
elif not CommentRe.match(l):
raise SimpleCfgError('syntax error')
def writestream(self, s):
for k in self:
s.write('%s: %s\n' % (k, self[k]))
def read(self, file):
f = None
try:
f = open(file)
self.readstream(f)
finally:
if f:
f.close()
def write(self, file):
tfd = None
tfil = None
try:
tfd, tname = tempfile.mkstemp(dir=os.path.dirname(file))
tfil, tfd = os.fdopen(tfd, 'w'), None
self.writestream(tfil)
os.fsync(tfil.fileno())
os.rename(tname, file)
finally:
if tfd != None:
os.close(tfd)
if tfil != None:
tfil.close()
|