aboutsummaryrefslogtreecommitdiff
blob: e1963f71a16448c01515a3135133787a4739cad0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import re

from catalyst import log
from catalyst.support import CatalystError


class ParserBase():

    filename = ""
    lines = None
    values = None
    key_value_separator = "="
    multiple_values = False
    empty_values = True
    eval_none = False

    def __getitem__(self, key):
        return self.values[key]

    def get_values(self):
        return self.values

    def dump(self):
        dump = ""
        for x in self.values:
            dump += x + " = " + repr(self.values[x]) + "\n"
        return dump

    def parse_file(self, filename):
        try:
            with open(filename, "r") as myf:
                self.lines = myf.readlines()
        except:
            raise CatalystError("Could not open file " + filename,
                                print_traceback=True)
        self.filename = filename
        self.parse()

    def parse_lines(self, lines):
        self.lines = lines
        self.parse()

    def parse(self):
        values = {}
        cur_array = []

        trailing_comment = re.compile(r'\s*#.*$')

        for x, myline in enumerate(self.lines):
            myline = myline.strip()

            # Force the line to be clean
            # Remove Comments ( anything following # )
            myline = trailing_comment.sub("", myline)

            # Skip any blank lines
            if not myline:
                continue

            if self.key_value_separator in myline:
                # Split on the first occurence of the separator creating two strings in the array mobjs
                mobjs = myline.split(self.key_value_separator, 1)
                mobjs[1] = mobjs[1].strip().strip('"')

                # Start a new array using the first element of mobjs
                cur_array = [mobjs[0]]
                if mobjs[1]:
                    # do any variable substitiution embeded in it with
                    # the values already obtained
                    mobjs[1] = mobjs[1] % values
                    if self.multiple_values:
                        # split on white space creating additional array elements
                        subarray = mobjs[1].split()
                        cur_array += subarray
                    else:
                        cur_array += [mobjs[1]]

            # Else add on to the last key we were working on
            else:
                if self.multiple_values:
                    cur_array += myline.split()
                else:
                    raise CatalystError("Syntax error: %s" %
                                        x, print_traceback=True)

            # XXX: Do we really still need this "single value is a string" behavior?
            if len(cur_array) == 2:
                values[cur_array[0]] = cur_array[1]
            else:
                values[cur_array[0]] = cur_array[1:]

        if not self.empty_values:
            # Make sure the list of keys is static since we modify inside the loop.
            for x in list(values.keys()):
                # Delete empty key pairs
                if not values[x]:
                    log.warning('No value set for key "%s"; deleting', x)
                    del values[x]

        if self.eval_none:
            # Make sure the list of keys is static since we modify inside the loop.
            for x in list(values.keys()):
                # reset None values
                if isinstance(values[x], str) and values[x].lower() in ['none']:
                    log.info('None value found for key "%s"; reseting', x)
                    values[x] = None
        self.values = values


class SpecParser(ParserBase):

    key_value_separator = ':'
    multiple_values = True
    empty_values = False
    eval_none = True

    def __init__(self, filename=""):
        if filename:
            self.parse_file(filename)