--- a/pvl/dhcp/config.py Wed Feb 25 15:55:23 2015 +0200
+++ b/pvl/dhcp/config.py Thu Feb 26 14:31:16 2015 +0200
@@ -219,3 +219,83 @@
assert not self.block
return self.items, self.blocks
+
+def build_field (value):
+ """
+ Build a single field as part of a dhcp.conf line.
+
+ >>> print build_field('foo')
+ foo
+ >>> print build_field('foo bar')
+ "foo bar"
+ """
+
+ value = str(value)
+
+ if any(c.isspace() for c in value):
+ # quoted
+ return '"{value}"'.format(value=value)
+ else:
+ return value
+
+def build_line (item, end, indent=0):
+ """
+ Build a structured line.
+
+ >>> print build_line(['foo'], ';')
+ foo;
+ >>> print build_line(['host', 'foo'], ' {')
+ host foo {
+ >>> print build_line(['foo', 'bar quux'], ';', indent=1)
+ foo "bar quux";
+ """
+
+ return ' '*indent + ' '.join(build_field(field) for field in item) + end
+
+def build_item (item, **opts):
+ """
+ Build a single parameter line.
+
+ >>> print build_item(['foo'])
+ foo;
+ """
+
+ return build_line(item, end=';', **opts)
+
+def build_block (block, items, blocks=(), indent=0, comment=None):
+ """
+ Build a complete block.
+
+ >>> for line in build_block(('host', 'foo'), [('hardware', 'ethernet', '00:11:22:33:44:55')], comment="Testing"): print line
+ # Testing
+ host foo {
+ hardware ethernet 00:11:22:33:44:55;
+ }
+ >>> for line in build_block(('group', ), [('next-server', 'booter')], [ \
+ (('host', 'foo'), [('hardware', 'ethernet', '00:11:22:33:44:55')], ()) \
+ ]): print line
+ group {
+ next-server booter;
+ <BLANKLINE>
+ host foo {
+ hardware ethernet 00:11:22:33:44:55;
+ }
+ }
+ """
+
+ if comment:
+ yield build_line((), end="# {comment}".format(comment=comment), indent=indent)
+
+ yield build_line(block, end=' {', indent=indent)
+
+ for item in items:
+ yield build_item(item, indent=indent+1)
+
+ for subblock, subitems, subblocks in blocks:
+ yield ''
+
+ for line in build_block(subblock, subitems, subblocks, indent=indent+1):
+ yield line
+
+ yield build_line((), end='}', indent=indent)
+