From e47d578a9cc92cbaf5291ee87d4e2a9da2d76fef Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sat, 8 Aug 2009 15:29:45 +0200 Subject: [PATCH] Initial experimental version of the meta-file module. --- t/moe/__init__.py | 1 + t/moe/config.py | 13 ++++++ t/moe/meta.py | 100 ++++++++++++++++++++++++++++++++++++++++++++++ t/test.py | 10 +++++ 4 files changed, 124 insertions(+) create mode 100644 t/moe/__init__.py create mode 100644 t/moe/config.py create mode 100644 t/moe/meta.py create mode 100755 t/test.py diff --git a/t/moe/__init__.py b/t/moe/__init__.py new file mode 100644 index 0000000..02cc0ce --- /dev/null +++ b/t/moe/__init__.py @@ -0,0 +1 @@ +# No initialization needed diff --git a/t/moe/config.py b/t/moe/config.py new file mode 100644 index 0000000..3075d80 --- /dev/null +++ b/t/moe/config.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python + +class MoeConfig: + """Moe configuration file.""" + + def __init__(self): + cfg = { 'XYZZY' : 'brum' } + +class MoeConfigStack: + """Stack of configuration files.""" + + def __init__(self): + stk = [] diff --git a/t/moe/meta.py b/t/moe/meta.py new file mode 100644 index 0000000..f565904 --- /dev/null +++ b/t/moe/meta.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +import sys +import types +import re + +key_pattern = re.compile('^[A-Za-z0-9_-]+$') + +class MoeMetaInvalid(Exception): + pass + +class MoeMeta: + """Moe meta-file.""" + + def __init__(self): + self.meta = {} + + def __getitem__(self, k): + if not self.meta.has_key(k): return None + v = self.meta[k] + if type(v) == types.ListType: + if len(v) > 0: return v[0] + else: return None + else: return v + + def __setitem__(self, k, v): + self.meta[k] = v + + def get_list(self, k): + m = self.meta + if not m.has_key(k): + m[k] = [] + elif type(m[k]) != types.ListType: + m[k] = [m[k]] + return m[k] + + def write(self, file=None, name=None): + if file is None: + if name is not None: + file = open(name, 'w') + else: + file = sys.stdout + self.write_nested(file, 0) + + def write_nested(self, file, indent): + for k,v in self.meta.items(): + if type(v) == types.ListType: vals = v + else: vals = [v] + for w in vals: + if isinstance(w, MoeMeta): + file.write("\t" * indent + k + "(\n") + w.write_nested(file, indent+1); + file.write("\t" * indent + ")\n") + else: + file.write("\t" * indent + k + ':' + str(w) + "\n") + + def read(self, file=None, name=None): + if file is None: + if name is not None: + file = open(name, 'r') + else: + file = sys.stdin + self.meta = {} + self.do_read(file) + + def read_val(self, k, v): + if not key_pattern.match(k): + raise MoeMetaInvalid, "Parse error: invalid key syntax" + m = self.meta + if not m.has_key(k): + m[k] = v + else: + self.get_list(k).append(v) + + def do_read(self, file): + stk = [] + this = self + for x in file.readlines(): + x = x.rstrip("\n").lstrip(" \t") + if x=='' or x.startswith('#'): + pass + else: + sep = x.find(':') + if sep >= 0: + k = x[:sep] + v = x[sep+1:] + this.read_val(k, v) + elif x.endswith('('): + k = x[:-1] + new = MoeMeta() + this.read_val(k, new) + stk.append(this) + this = new + elif x == ')': + if len(stk) == 0: + raise MoeMetaInvalid, "Parse error: incorrect nesting" + else: + this = stk.pop() + else: + raise MoeMetaInvalid, "Parse error: malformed line" diff --git a/t/test.py b/t/test.py new file mode 100755 index 0000000..e928214 --- /dev/null +++ b/t/test.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python + +import sys +sys.path.append('.') + +import moe.meta + +m = moe.meta.MoeMeta() +m['a'] = '1' +m.write() -- 2.39.2