Subversion Repositories svnkaklik

Rev

Details | Last modification | View Log

Rev Author Line No. Line
36 kaklik 1
# Written by John Hoffman
2
# see LICENSE.txt for license information
3
 
4
'''
5
reads/writes a Windows-style INI file
6
format:
7
 
8
  aa = "bb"
9
  cc = 11
10
 
11
  [eee]
12
  ff = "gg"
13
 
14
decodes to:
15
d = { '': {'aa':'bb','cc':'11'}, 'eee': {'ff':'gg'} }
16
 
17
the encoder can also take this as input:
18
 
19
d = { 'aa': 'bb, 'cc': 11, 'eee': {'ff':'gg'} }
20
 
21
though it will only decode in the above format.  Keywords must be strings.
22
Values that are strings are written surrounded by quotes, and the decoding
23
routine automatically strips any.
24
Booleans are written as integers.  Anything else aside from string/int/float
25
may have unpredictable results.
26
'''
27
 
28
from cStringIO import StringIO
29
from traceback import print_exc
30
from types import DictType, StringType
31
try:
32
    from types import BooleanType
33
except ImportError:
34
    BooleanType = None
35
 
36
try:
37
    True
38
except:
39
    True = 1
40
    False = 0
41
 
42
DEBUG = False
43
 
44
def ini_write(f, d, comment=''):
45
    try:
46
        a = {'':{}}
47
        for k,v in d.items():
48
            assert type(k) == StringType
49
            k = k.lower()
50
            if type(v) == DictType:
51
                if DEBUG:
52
                    print 'new section:' +k
53
                if k:
54
                    assert not a.has_key(k)
55
                    a[k] = {}
56
                aa = a[k]
57
                for kk,vv in v:
58
                    assert type(kk) == StringType
59
                    kk = kk.lower()
60
                    assert not aa.has_key(kk)
61
                    if type(vv) == BooleanType:
62
                        vv = int(vv)
63
                    if type(vv) == StringType:
64
                        vv = '"'+vv+'"'
65
                    aa[kk] = str(vv)
66
                    if DEBUG:
67
                        print 'a['+k+']['+kk+'] = '+str(vv)
68
            else:
69
                aa = a['']
70
                assert not aa.has_key(k)
71
                if type(v) == BooleanType:
72
                    v = int(v)
73
                if type(v) == StringType:
74
                    v = '"'+v+'"'
75
                aa[k] = str(v)
76
                if DEBUG:
77
                    print 'a[\'\']['+k+'] = '+str(v)
78
        r = open(f,'w')
79
        if comment:
80
            for c in comment.split('\n'):
81
                r.write('# '+c+'\n')
82
            r.write('\n')
83
        l = a.keys()
84
        l.sort()
85
        for k in l:
86
            if k:
87
                r.write('\n['+k+']\n')
88
            aa = a[k]
89
            ll = aa.keys()
90
            ll.sort()
91
            for kk in ll:
92
                r.write(kk+' = '+aa[kk]+'\n')
93
        success = True
94
    except:
95
        if DEBUG:
96
            print_exc()
97
        success = False
98
    try:
99
        r.close()
100
    except:
101
        pass
102
    return success
103
 
104
 
105
if DEBUG:
106
    def errfunc(lineno, line, err):
107
        print '('+str(lineno)+') '+err+': '+line
108
else:
109
    errfunc = lambda lineno, line, err: None
110
 
111
def ini_read(f, errfunc = errfunc):
112
    try:
113
        r = open(f,'r')
114
        ll = r.readlines()
115
        d = {}
116
        dd = {'':d}
117
        for i in xrange(len(ll)):
118
            l = ll[i]
119
            l = l.strip()
120
            if not l:
121
                continue
122
            if l[0] == '#':
123
                continue
124
            if l[0] == '[':
125
                if l[-1] != ']':
126
                    errfunc(i,l,'syntax error')
127
                    continue
128
                l1 = l[1:-1].strip().lower()
129
                if not l1:
130
                    errfunc(i,l,'syntax error')
131
                    continue
132
                if dd.has_key(l1):
133
                    errfunc(i,l,'duplicate section')
134
                    d = dd[l1]
135
                    continue
136
                d = {}
137
                dd[l1] = d
138
                continue
139
            try:
140
                k,v = l.split('=',1)
141
            except:
142
                try:
143
                    k,v = l.split(':',1)
144
                except:
145
                    errfunc(i,l,'syntax error')
146
                    continue
147
            k = k.strip().lower()
148
            v = v.strip()
149
            if len(v) > 1 and ( (v[0] == '"' and v[-1] == '"') or
150
                                (v[0] == "'" and v[-1] == "'") ):
151
                v = v[1:-1]
152
            if not k:
153
                errfunc(i,l,'syntax error')
154
                continue
155
            if d.has_key(k):
156
                errfunc(i,l,'duplicate entry')
157
                continue
158
            d[k] = v
159
        if DEBUG:
160
            print dd
161
    except:
162
        if DEBUG:
163
            print_exc()
164
        dd = None
165
    try:
166
        r.close()
167
    except:
168
        pass
169
    return dd