pvl/dhcp/config.py
author Tero Marttila <tero.marttila@aalto.fi>
Tue, 03 Mar 2015 11:15:39 +0200
changeset 707 13283078a929
parent 699 d34567c1b21a
permissions -rw-r--r--
pvl.dhcp.config: format pseudo-Block's as items
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
     1
import logging; log = logging.getLogger('pvl.dhcp.config')
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
     2
import shlex
673
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
     3
import string
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
     4
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
     5
# simplified model of lexer chars
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
     6
TOKEN_START = string.ascii_letters + string.digits + '-'
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
     7
TOKEN = TOKEN_START + '_'
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
     8
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
     9
# be far more lenient when parsing
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
    10
TOKEN_EXTRA = TOKEN + ':.'
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
    11
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
    12
UNQUOTED_CONTEXT = set((
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
    13
    ('host', ),
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
    14
    ('fixed-address', ),
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
    15
    ('next-server', ),
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
    16
    ('hardware', 'ethernet'),
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
    17
))
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    18
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    19
class DHCPConfigError(Exception):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    20
    def __init__ (self, parser, error, line=None):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    21
        self.parser = parser
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    22
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    23
        self.name = parser.name
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    24
        self.line = line
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    25
        self.error = error
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    26
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    27
    def __str__ (self):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    28
        return "{self.name}:{self.line}: {self.error}".format(self=self)
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    29
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    30
def split (line) :
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
    31
    """
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    32
        Split given line-data into raw tokens.
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    33
        
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    34
        >>> list(split('foo'))
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    35
        ['foo']
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    36
        >>> list(split('foo bar'))
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    37
        ['foo', 'bar']
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    38
        >>> list(split('foo;'))
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    39
        ['foo', ';']
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    40
        >>> list(split('"foo"'))
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    41
        ['foo']
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    42
        >>> list(split('foo "asdf quux" bar'))
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    43
        ['foo', 'asdf quux', 'bar']
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    44
        >>> list(split('foo "asdf quux"'))
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    45
        ['foo', 'asdf quux']
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    46
        >>> list(split('# nevermind'))
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    47
        []
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    48
        >>> list(split(''))
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    49
        []
673
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
    50
        >>> list(split('next-server foo'))
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
    51
        ['next-server', 'foo']
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
    52
        >>> list(split('include "foo/bar.conf";'))
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
    53
        ['include', 'foo/bar.conf', ';']
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    54
    """
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    55
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    56
    if line is None:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    57
        raise TypeError(line)
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    58
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    59
    lexer = shlex.shlex(line, posix=True)
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    60
    lexer.commenters = '#'
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
    61
    lexer.wordchars = TOKEN_EXTRA
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    62
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    63
    while True:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    64
        item = lexer.get_token()
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    65
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    66
        if item is None:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    67
            break
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    68
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    69
        yield item
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
    70
695
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    71
class Field (object):
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    72
    """
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    73
        Pre-quoted fields for use in DHCP confs.
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    74
    """
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    75
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    76
    def __init__(self, token):
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    77
        self.token = token
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    78
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    79
    def __str__(self):
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    80
        return self.token
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
    81
699
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    82
class String (Field):
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    83
    """
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    84
        A quoted string
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    85
    """
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    86
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    87
    def __init__(self, string):
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    88
        self.string = string
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    89
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    90
    def __str__(self):
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    91
        # TODO: escape
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    92
        return '"{self.string}"'.format(self=self)
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
    93
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
    94
def quote (value, context=None):
673
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
    95
    """
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
    96
        Build a single field as part of a dhcp.conf line.
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
    97
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
    98
        >>> print quote('foo')
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
    99
        foo
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   100
        >>> print quote('foo bar')
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   101
        "foo bar"
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   102
        >>> print quote('foo/bar.conf')
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   103
        "foo/bar.conf"
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   104
        >>> print quote(5)
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   105
        5
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   106
        >>> print quote('5')
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   107
        5
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   108
        >>> print quote('foo.bar')
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   109
        "foo.bar"
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   110
        >>> print quote('foo.bar', context=('host', ))
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   111
        foo.bar
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   112
        >>> print quote('192.0.2.1', context=('fixed-address', ))
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   113
        192.0.2.1
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   114
        >>> print quote('00:11:22:33:44:55', context=('hardware', 'ethernet'))
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   115
        00:11:22:33:44:55
695
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
   116
        >>> print quote(Field('1:00:11:22:33:44:55'))
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
   117
        1:00:11:22:33:44:55
699
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
   118
        >>> print quote(String('foobar'))
d34567c1b21a pvl.dhcp.config: String() for quoted string Field
Tero Marttila <tero.marttila@aalto.fi>
parents: 695
diff changeset
   119
        "foobar"
673
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   120
    """
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   121
695
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
   122
    if isinstance(value, Field):
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
   123
        return str(value)
c60924eca185 pvl.dhcp: support config.Field for pre-quoted values
Tero Marttila <tero.marttila@aalto.fi>
parents: 685
diff changeset
   124
    elif isinstance(value, int):
673
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   125
        return str(value)
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   126
    elif context in UNQUOTED_CONTEXT:
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   127
        return str(value)
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   128
    elif value[0] in TOKEN_START and all(c in TOKEN for c in value):
673
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   129
        return str(value)
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   130
    else:
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   131
        # quoted
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   132
        return '"{value}"'.format(value=value)
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   133
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   134
class Block (object):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   135
    """
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   136
        A block in a dhcp conf includes parameters and sub-blocks.
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   137
    """
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   138
668
794f943c835d pvl.dhcp.config: Block(comment=...)
Tero Marttila <terom@paivola.fi>
parents: 666
diff changeset
   139
    def __init__ (self, key, items=None, blocks=None, comment=None):
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   140
        """
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   141
            key: tuple      - name of block
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   142
        """
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   143
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   144
        self.key = key
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   145
        self.items = items or [ ]
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   146
        self.blocks = blocks or [ ]
668
794f943c835d pvl.dhcp.config: Block(comment=...)
Tero Marttila <terom@paivola.fi>
parents: 666
diff changeset
   147
        self.comment = comment
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   148
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   149
    def __str__ (self):
707
13283078a929 pvl.dhcp.config: format pseudo-Block's as items
Tero Marttila <tero.marttila@aalto.fi>
parents: 699
diff changeset
   150
        if self.key:
13283078a929 pvl.dhcp.config: format pseudo-Block's as items
Tero Marttila <tero.marttila@aalto.fi>
parents: 699
diff changeset
   151
            return ' '.join(self.key)
13283078a929 pvl.dhcp.config: format pseudo-Block's as items
Tero Marttila <tero.marttila@aalto.fi>
parents: 699
diff changeset
   152
        else:
13283078a929 pvl.dhcp.config: format pseudo-Block's as items
Tero Marttila <tero.marttila@aalto.fi>
parents: 699
diff changeset
   153
            # XXX: Item.__str__
13283078a929 pvl.dhcp.config: format pseudo-Block's as items
Tero Marttila <tero.marttila@aalto.fi>
parents: 699
diff changeset
   154
            return '; '.join(' '.join(str(x) for x in item) for item in self.items)
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   155
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   156
    def __repr__ (self):
682
60dbd952a15e pvl.dhcp.config: fix block stack to have .load() actually return the top-level block
Tero Marttila <terom@paivola.fi>
parents: 681
diff changeset
   157
        return "Block({self.key!r}, items={self.items!r}, blocks={self.blocks!r})".format(self=self)
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   158
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   159
class DHCPConfigParser (object):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   160
    """
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   161
        Simple parser for ISC dhcpd conf files.
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   162
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   163
        Supports iterative parsing as required for following a dhcpd.leases file.
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   164
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   165
        Doesn't implement the full spec, but a useful approximation.
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   166
    """
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   167
256
63b285ceae41 pvl.dhcp.config: nested blocks
Tero Marttila <terom@paivola.fi>
parents: 255
diff changeset
   168
    @classmethod
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   169
    def load (cls, file, name=None):
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   170
        """
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   171
            Parse an complete file, returning the top-level Block.
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   172
673
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   173
            >>> DHCPConfigParser.load(['foo;', 'bar {', '\tasdf "quux";', '}'], name='test')
682
60dbd952a15e pvl.dhcp.config: fix block stack to have .load() actually return the top-level block
Tero Marttila <terom@paivola.fi>
parents: 681
diff changeset
   174
            Block(None, items=[('foo',)], blocks=[Block(('bar',), items=[('asdf', 'quux')], blocks=[])])
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   175
        """
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   176
        
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   177
        if name is None:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   178
            name = file.name
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   179
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   180
        parser = cls(name=name)
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   181
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   182
        for lineno, line in enumerate(file, 1):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   183
            try:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   184
                for item in parser.parse_line(line):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   185
                    log.debug("%s", item)
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   186
            except DHCPConfigError as error:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   187
                error.line = lineno
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   188
                raise
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   189
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   190
        if parser.token:
682
60dbd952a15e pvl.dhcp.config: fix block stack to have .load() actually return the top-level block
Tero Marttila <terom@paivola.fi>
parents: 681
diff changeset
   191
            raise DHCPConfError(parser, "Trailing data: {token}".format(token=parser.token), line=lineno)
60dbd952a15e pvl.dhcp.config: fix block stack to have .load() actually return the top-level block
Tero Marttila <terom@paivola.fi>
parents: 681
diff changeset
   192
        
60dbd952a15e pvl.dhcp.config: fix block stack to have .load() actually return the top-level block
Tero Marttila <terom@paivola.fi>
parents: 681
diff changeset
   193
        if parser.stack:
60dbd952a15e pvl.dhcp.config: fix block stack to have .load() actually return the top-level block
Tero Marttila <terom@paivola.fi>
parents: 681
diff changeset
   194
            raise DHCPConfError(parser, "Unterminated block: {stack}".format(stack=parser.stack), line=lineno)
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   195
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   196
        return parser.block 
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   197
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   198
    def __init__ (self, name=None):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   199
        self.name = name
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   200
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   201
        # lexer state
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   202
        self.token = []
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   203
        
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   204
        # parser state
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   205
        self.stack = []
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   206
        
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   207
        # top-level block
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   208
        self.block = Block(None)
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   209
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   210
    def lex (self, line):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   211
        """
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   212
            Lex one line of input into basic expressions:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   213
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   214
                open:   [...] {
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   215
                item:       [..];
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   216
                close:  [] }
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   217
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   218
            Yields (event, (...)) tokens.
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   219
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   220
            Raises DHCPConfError.
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   221
        """
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   222
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   223
        log.debug("%s", line)
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   224
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   225
        for word in split(line):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   226
            if word == '{':
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   227
                yield 'open', tuple(self.token)
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   228
            
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   229
            elif word == ';':
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   230
                yield 'item', tuple(self.token)
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   231
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   232
            elif word == '}':
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   233
                if self.token:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   234
                    raise DHCPConfError(self, "Leading data on close: {token}".format(token=self.token))
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   235
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   236
                yield 'close', None
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   237
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   238
            else:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   239
                self.token.append(word)
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   240
                continue
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   241
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   242
            self.token = [ ]
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   243
       
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   244
    def parse (self, tokens):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   245
        """
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   246
            Parse given tokens, yielding any complete Blocks.
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   247
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   248
            Note that the Blocks yielded may be within some other Block which is still incomplete.
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   249
        """
256
63b285ceae41 pvl.dhcp.config: nested blocks
Tero Marttila <terom@paivola.fi>
parents: 255
diff changeset
   250
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   251
        for token, args in tokens:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   252
            if token == 'open':
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   253
                block = Block(args)
256
63b285ceae41 pvl.dhcp.config: nested blocks
Tero Marttila <terom@paivola.fi>
parents: 255
diff changeset
   254
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   255
                log.debug("open block: %s > %s", self.block, block)
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   256
                
682
60dbd952a15e pvl.dhcp.config: fix block stack to have .load() actually return the top-level block
Tero Marttila <terom@paivola.fi>
parents: 681
diff changeset
   257
                self.stack.append(self.block)
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   258
                self.block.blocks.append(block)
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   259
                self.block = block
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   260
            
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   261
            # must be within block!
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   262
            elif token == 'item' :
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   263
                log.debug("block %s item: %s", self.block, args)
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   264
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   265
                self.block.items.append(args)
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   266
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   267
            elif token == 'close' :
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   268
                log.debug("close block: %s", self.block)
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   269
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   270
                block = self.block
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   271
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   272
                if self.stack:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   273
                    self.block = self.stack.pop()
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   274
                else:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   275
                    raise DHCPConfigError(self, "Mismatched block close: {block}".format(block=block))
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   276
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   277
                yield block
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   278
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   279
            else:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   280
                raise ValueError(token, args)
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   281
    
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   282
    def parse_line (self, line):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   283
        """
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   284
            Lex and parse line tokens.
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   285
        """
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   286
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   287
        for block in self.parse(self.lex(line)):
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   288
            yield block
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   289
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   290
    def parse_lines (self, lines) :
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   291
        """
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   292
            Trivial wrapper around parse to parse multiple lines.
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   293
        """
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   294
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   295
        for line in lines:
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   296
            for block in self.parse_line(line) :
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   297
                yield block
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   298
    
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   299
def build_line (item, end, indent=0, context=None):
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   300
    """
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   301
        Build a structured line.
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   302
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   303
        >>> print build_line(('foo', ), ';')
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   304
        foo;
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   305
        >>> print build_line(('host', 'foo'), ' {')
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   306
        host foo {
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   307
        >>> print build_line(('foo', 'bar quux'), ';', indent=1)
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   308
            foo "bar quux";
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   309
    """
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   310
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   311
    return '    '*indent + ' '.join(quote(field, context=context) for field in item) + end
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   312
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   313
def build_item (item, **opts):
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   314
    """
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   315
        Build a single parameter line.
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   316
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   317
        >>> print build_item(('foo', ))
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   318
        foo;
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   319
    """
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   320
679
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   321
    return build_line(item, end=';',
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   322
        context     = item[:-1],
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   323
        **opts
31adba0f586d pvl.dhcp.config: make quoting context-sensitive, so that only certain items get special quoting..
Tero Marttila <terom@paivola.fi>
parents: 675
diff changeset
   324
    )
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   325
668
794f943c835d pvl.dhcp.config: Block(comment=...)
Tero Marttila <terom@paivola.fi>
parents: 666
diff changeset
   326
def build_block (block, indent=0):
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   327
    """
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   328
        Build a complete Block, recursively, yielding output lines.
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   329
681
3da02c7e5781 pvl.dhcp.config: fix build_block() doctests
Tero Marttila <terom@paivola.fi>
parents: 680
diff changeset
   330
        >>> for line in build_block(Block(('host', 'foo'), [('hardware', 'ethernet', '00:11:22:33:44:55')], comment="Testing")): print line
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   331
        # Testing
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   332
        host foo {
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   333
            hardware ethernet 00:11:22:33:44:55;
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   334
        }
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   335
        >>> for line in build_block(Block(('group', ), [('next-server', 'booter')], [ \
681
3da02c7e5781 pvl.dhcp.config: fix build_block() doctests
Tero Marttila <terom@paivola.fi>
parents: 680
diff changeset
   336
                    Block(('host', 'foo'), [('hardware', 'ethernet', '00:11:22:33:44:55')]) \
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   337
                ])): print line
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   338
        group {
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   339
            next-server booter;
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   340
        <BLANKLINE>
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   341
            host foo {
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   342
                hardware ethernet 00:11:22:33:44:55;
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   343
            }
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   344
        }
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   345
    """
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   346
668
794f943c835d pvl.dhcp.config: Block(comment=...)
Tero Marttila <terom@paivola.fi>
parents: 666
diff changeset
   347
    if block.comment:
794f943c835d pvl.dhcp.config: Block(comment=...)
Tero Marttila <terom@paivola.fi>
parents: 666
diff changeset
   348
        yield build_line((), end="# {comment}".format(comment=block.comment), indent=indent)
685
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   349
    
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   350
    if block.key:
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   351
        yield build_line(block.key, end=' {', indent=indent, context=block.key[0:1])
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   352
        indent += 1
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   353
    
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   354
    for item in block.items:
685
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   355
        yield build_item(item, indent=indent)
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   356
666
a8ddcbe894ff pvl.dhcp.config: refactor DHCPConfigParser to use shlex and yield Block objects, change build_block() to use Block; tests
Tero Marttila <terom@paivola.fi>
parents: 478
diff changeset
   357
    for subblock in block.blocks:
685
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   358
        if block.items:
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   359
            yield ''
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   360
685
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   361
        for line in build_block(subblock, indent=indent):
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   362
            yield line
685
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   363
    
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   364
    if block.key:
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   365
        indent -= 1
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   366
        yield build_line((), end='}', indent=indent)