]> mj.ucw.cz Git - moe.git/blob - t/moe/status.py
Status files are now handled almost properly
[moe.git] / t / moe / status.py
1 #!/usr/bin/env python
2
3 import sys
4 import types
5 import re
6
7 key_pattern = re.compile("^[A-Za-z0-9_-]+$")
8
9 class MoeStatusInvalid(Exception):
10     pass
11
12 class MoeStatus:
13     """Moe status file."""
14
15     def __init__(self):
16         self.stat = {}
17
18     def __getitem__(self, k):
19         if not self.stat.has_key(k): return None
20         v = self.stat[k]
21         if type(v) == types.ListType:
22             if len(v) > 0: return v[0]
23             else: return None
24         else: return v
25
26     def __setitem__(self, k, v):
27         self.stat[k] = v
28
29     def keys(self):
30         return self.stat.keys()
31
32     def get_list(self, k):
33         m = self.stat
34         if not m.has_key(k):
35             m[k] = []
36         elif type(m[k]) != types.ListType:
37             m[k] = [m[k]]
38         return m[k]
39
40     def write(self, file=None, name=None):
41         if file is None:
42             if name is not None:
43                 file = open(name, "w")
44             else:
45                 file = sys.stdout
46         self.write_nested(file, 0)
47
48     def write_nested(self, file, indent):
49         for k,v in self.stat.items():
50             if type(v) == types.ListType: vals = v
51             else: vals = [v]
52             for w in vals:
53                 if isinstance(w, MoeStatus):
54                     file.write("\t" * indent + k + "(\n")
55                     w.write_nested(file, indent+1);
56                     file.write("\t" * indent + ")\n")
57                 else:
58                     file.write("\t" * indent + k + ":" + str(w) + "\n")
59
60     def read(self, file=None, name=None):
61         if file is None:
62             if name is not None:
63                 file = open(name, "r")
64             else:
65                 file = sys.stdin
66         self.stat = {}
67         self.do_read(file)
68
69     def read_val(self, k, v):
70         if not key_pattern.match(k):
71             raise MoeStatusInvalid, "Parse error: invalid key syntax"
72         m = self.stat
73         if not m.has_key(k):
74             m[k] = v
75         else:
76             self.get_list(k).append(v)
77
78     def do_read(self, file):
79         stk = []
80         this = self
81         for x in file.readlines():
82             x = x.rstrip("\n").lstrip(" \t")
83             if x=="" or x.startswith("#"):
84                 pass
85             else:
86                 sep = x.find(":")
87                 if sep >= 0:
88                     k = x[:sep]
89                     v = x[sep+1:]
90                     this.read_val(k, v)
91                 elif x.endswith("("):
92                     k = x[:-1]
93                     new = MoeStatus()
94                     this.read_val(k, new)
95                     stk.append(this)
96                     this = new
97                 elif x == ")":
98                     if len(stk) == 0:
99                         raise MoeStatusInvalid, "Parse error: incorrect nesting"
100                     else:
101                         this = stk.pop()
102                 else:
103                     raise MoeStatusInvalid, "Parse error: malformed line"