pvl/dhcp/config.py
author Tero Marttila <tero.marttila@aalto.fi>
Mon, 02 Mar 2015 19:58:12 +0200
changeset 699 d34567c1b21a
parent 695 c60924eca185
child 707 13283078a929
permissions -rw-r--r--
pvl.dhcp.config: String() for quoted string Field
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):
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
   150
        return ' '.join(self.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
   151
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
   152
    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
   153
        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
   154
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
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
   156
    """
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
   157
        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
   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
        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
   160
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   161
        Doesn't implement the full spec, but a useful approximation.
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   162
    """
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   163
256
63b285ceae41 pvl.dhcp.config: nested blocks
Tero Marttila <terom@paivola.fi>
parents: 255
diff changeset
   164
    @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
   165
    def load (cls, file, name=None):
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   166
        """
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
   167
            Parse an complete file, returning the top-level Block.
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   168
673
0eda16e29613 pvl.dhcp.config: stricter quoting of e.g. include file paths
Tero Marttila <terom@paivola.fi>
parents: 668
diff changeset
   169
            >>> 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
   170
            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
   171
        """
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
   172
        
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
   173
        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
   174
            name = file.name
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
        parser = cls(name=name)
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   177
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
   178
        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
   179
            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
   180
                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
   181
                    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
   182
            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
   183
                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
   184
                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
   185
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
        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
   187
            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
   188
        
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
   189
        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
   190
            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
   191
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
   192
        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
   193
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
   194
    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
   195
        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
   196
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
        # 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
   198
        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
   199
        
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
        # 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
   201
        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
   202
        
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
        # 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
   204
        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
   205
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
    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
   207
        """
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
            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
   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
                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
   211
                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
   212
                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
   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
            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
   215
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
            Raises DHCPConfError.
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   217
        """
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   218
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   219
        log.debug("%s", line)
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   220
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
   221
        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
   222
            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
   223
                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
   224
            
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
            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
   226
                yield 'item', tuple(self.token)
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   227
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
   228
            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
   229
                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
   230
                    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
   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
                yield 'close', None
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   233
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
   234
            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
   235
                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
   236
                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
   237
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
            self.token = [ ]
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   239
       
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
   240
    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
   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
            Parse given tokens, yielding any complete Blocks.
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
            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
   245
        """
256
63b285ceae41 pvl.dhcp.config: nested blocks
Tero Marttila <terom@paivola.fi>
parents: 255
diff changeset
   246
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
   247
        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
   248
            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
   249
                block = Block(args)
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
                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
   252
                
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
   253
                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
   254
                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
   255
                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
            
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
   257
            # 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
   258
            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
   259
                log.debug("block %s item: %s", self.block, args)
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   260
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
   261
                self.block.items.append(args)
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   262
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   263
            elif token == 'close' :
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   264
                log.debug("close block: %s", self.block)
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   265
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
   266
                block = self.block
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   267
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
   268
                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
   269
                    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
   270
                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
   271
                    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
   272
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
   273
                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
   274
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
            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
   276
                raise ValueError(token, args)
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   277
    
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
   278
    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
   279
        """
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
            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
   281
        """
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
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
        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
   284
            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
   285
255
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   286
    def parse_lines (self, lines) :
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   287
        """
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   288
            Trivial wrapper around parse to parse multiple lines.
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   289
        """
d14eda12d966 split pvl.dhcp.config.DHCPConfigParser
Tero Marttila <terom@paivola.fi>
parents:
diff changeset
   290
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
   291
        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
   292
            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
   293
                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
   294
    
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
   295
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
   296
    """
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   297
        Build a structured line.
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
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
        >>> print build_line(('foo', ), ';')
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   300
        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
   301
        >>> print build_line(('host', 'foo'), ' {')
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   302
        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
   303
        >>> 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
   304
            foo "bar quux";
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   305
    """
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   306
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
    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
   308
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   309
def build_item (item, **opts):
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   310
    """
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   311
        Build a single parameter line.
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   312
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
   313
        >>> print build_item(('foo', ))
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   314
        foo;
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   315
    """
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
    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
   318
        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
   319
        **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
   320
    )
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   321
668
794f943c835d pvl.dhcp.config: Block(comment=...)
Tero Marttila <terom@paivola.fi>
parents: 666
diff changeset
   322
def build_block (block, indent=0):
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   323
    """
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
   324
        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
   325
681
3da02c7e5781 pvl.dhcp.config: fix build_block() doctests
Tero Marttila <terom@paivola.fi>
parents: 680
diff changeset
   326
        >>> 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
   327
        # Testing
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   328
        host foo {
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   329
            hardware ethernet 00:11:22:33:44:55;
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   330
        }
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
   331
        >>> 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
   332
                    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
   333
                ])): print line
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   334
        group {
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   335
            next-server booter;
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   336
        <BLANKLINE>
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   337
            host foo {
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   338
                hardware ethernet 00:11:22:33:44:55;
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   339
            }
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   340
        }
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   341
    """
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   342
668
794f943c835d pvl.dhcp.config: Block(comment=...)
Tero Marttila <terom@paivola.fi>
parents: 666
diff changeset
   343
    if block.comment:
794f943c835d pvl.dhcp.config: Block(comment=...)
Tero Marttila <terom@paivola.fi>
parents: 666
diff changeset
   344
        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
   345
    
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   346
    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
   347
        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
   348
        indent += 1
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   349
    
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
   350
    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
   351
        yield build_item(item, indent=indent)
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   352
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
   353
    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
   354
        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
   355
            yield ''
476
4b792c44cf05 pvl.dhcp.config: build configs
Tero Marttila <tero.marttila@aalto.fi>
parents: 256
diff changeset
   356
685
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   357
        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
   358
            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
   359
    
668f934bb958 pvl.dhcp.config: fix build_block() to handle top-level config Blocks
Tero Marttila <tero.marttila@aalto.fi>
parents: 682
diff changeset
   360
    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
   361
        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
   362
        yield build_line((), end='}', indent=indent)