diff options
author | Andrew Shadura <andrew@shadura.me> | 2015-08-20 15:58:26 +0200 |
---|---|---|
committer | Andrew Shadura <andrew@shadura.me> | 2015-08-20 15:58:26 +0200 |
commit | ff1408420159488a106492ccd11dd234967029b6 (patch) | |
tree | 473420cee1c5229a427ec4cafead1aa6c0a26800 /reconfigure/parsers/ssv.py |
Imported Upstream version 0.1.29
Diffstat (limited to 'reconfigure/parsers/ssv.py')
-rw-r--r-- | reconfigure/parsers/ssv.py | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/reconfigure/parsers/ssv.py b/reconfigure/parsers/ssv.py new file mode 100644 index 0000000..2119a4a --- /dev/null +++ b/reconfigure/parsers/ssv.py @@ -0,0 +1,72 @@ +from reconfigure.nodes import * +from reconfigure.parsers import BaseParser + + +class SSVParser (BaseParser): + """ + A parser for files containing space-separated value (notably, ``/etc/fstab`` and friends) + + :param separator: separator character, defaults to whitespace + :param maxsplit: max number of tokens per line, defaults to infinity + :param comment: character denoting comments + :param continuation: line continuation character, None to disable + """ + + def __init__(self, separator=None, maxsplit=-1, comment='#', continuation=None, *args, **kwargs): + self.separator = separator + self.maxsplit = maxsplit + self.comment = comment + self.continuation = continuation + BaseParser.__init__(self, *args, **kwargs) + + def parse(self, content): + rawlines = content.splitlines() + lines = [] + while rawlines: + l = rawlines.pop(0).strip() + while self.continuation and rawlines and l.endswith(self.continuation): + l = l[:-len(self.continuation)] + l += rawlines.pop(0) + lines.append(l) + root = RootNode() + last_comment = None + for line in lines: + line = line.strip() + if line: + if line.startswith(self.comment): + c = line.strip(self.comment).strip() + if last_comment: + last_comment += '\n' + c + else: + last_comment = c + continue + if len(line) == 0: + continue + tokens = line.split(self.separator, self.maxsplit) + node = Node('line') + if last_comment: + node.comment = last_comment + last_comment = None + for token in tokens: + if token.startswith(self.comment): + node.comment = ' '.join(tokens[tokens.index(token):])[1:].strip() + break + node.append(Node( + name='token', + children=[ + PropertyNode(name='value', value=token) + ] + )) + root.append(node) + return root + + def stringify(self, tree): + r = '' + for node in tree.children: + if node.comment and '\n' in node.comment: + r += ''.join('%s %s\n' % (self.comment, x) for x in node.comment.splitlines()) + r += (self.separator or '\t').join(x.get('value').value for x in node.children) + if node.comment and not '\n' in node.comment: + r += ' # %s' % node.comment + r += '\n' + return r |