]> mj.ucw.cz Git - moe.git/blob - t/moe/meta.py
A brief experiment with pipelines
[moe.git] / t / moe / meta.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 MoeMetaInvalid(Exception):
10     pass
11
12 class MoeMeta:
13     """Moe meta-file."""
14
15     def __init__(self):
16         self.meta = {}
17
18     def __getitem__(self, k):
19         if not self.meta.has_key(k): return None
20         v = self.meta[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.meta[k] = v
28
29     def get_list(self, k):
30         m = self.meta
31         if not m.has_key(k):
32             m[k] = []
33         elif type(m[k]) != types.ListType:
34             m[k] = [m[k]]
35         return m[k]
36
37     def write(self, file=None, name=None):
38         if file is None:
39             if name is not None:
40                 file = open(name, 'w')
41             else:
42                 file = sys.stdout
43         self.write_nested(file, 0)
44
45     def write_nested(self, file, indent):
46         for k,v in self.meta.items():
47             if type(v) == types.ListType: vals = v
48             else: vals = [v]
49             for w in vals:
50                 if isinstance(w, MoeMeta):
51                     file.write("\t" * indent + k + "(\n")
52                     w.write_nested(file, indent+1);
53                     file.write("\t" * indent + ")\n")
54                 else:
55                     file.write("\t" * indent + k + ':' + str(w) + "\n")
56
57     def read(self, file=None, name=None):
58         if file is None:
59             if name is not None:
60                 file = open(name, 'r')
61             else:
62                 file = sys.stdin
63         self.meta = {}
64         self.do_read(file)
65
66     def read_val(self, k, v):
67         if not key_pattern.match(k):
68             raise MoeMetaInvalid, "Parse error: invalid key syntax"
69         m = self.meta
70         if not m.has_key(k):
71             m[k] = v
72         else:
73             self.get_list(k).append(v)
74
75     def do_read(self, file):
76         stk = []
77         this = self
78         for x in file.readlines():
79             x = x.rstrip("\n").lstrip(" \t")
80             if x=='' or x.startswith('#'):
81                 pass
82             else:
83                 sep = x.find(':')
84                 if sep >= 0:
85                     k = x[:sep]
86                     v = x[sep+1:]
87                     this.read_val(k, v)
88                 elif x.endswith('('):
89                     k = x[:-1]
90                     new = MoeMeta()
91                     this.read_val(k, new)
92                     stk.append(this)
93                     this = new
94                 elif x == ')':
95                     if len(stk) == 0:
96                         raise MoeMetaInvalid, "Parse error: incorrect nesting"
97                     else:
98                         this = stk.pop()
99                 else:
100                     raise MoeMetaInvalid, "Parse error: malformed line"