1# Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2#  This source code is licensed under both the GPLv2 (found in the
3#  COPYING file in the root directory) and Apache 2.0 License
4#  (found in the LICENSE.Apache file in the root directory).
5
6from enum import Enum
7
8
9class IniParser:
10    class Element(Enum):
11        rule = 1
12        cond = 2
13        sugg = 3
14        key_val = 4
15        comment = 5
16
17    @staticmethod
18    def remove_trailing_comment(line):
19        line = line.strip()
20        comment_start = line.find('#')
21        if comment_start > -1:
22            return line[:comment_start]
23        return line
24
25    @staticmethod
26    def is_section_header(line):
27        # A section header looks like: [Rule "my-new-rule"]. Essentially,
28        # a line that is in square-brackets.
29        line = line.strip()
30        if line.startswith('[') and line.endswith(']'):
31            return True
32        return False
33
34    @staticmethod
35    def get_section_name(line):
36        # For a section header: [Rule "my-new-rule"], this method will return
37        # "my-new-rule".
38        token_list = line.strip()[1:-1].split('"')
39        if len(token_list) < 3:
40            error = 'needed section header: [<section_type> "<section_name>"]'
41            raise ValueError('Parsing error: ' + error + '\n' + line)
42        return token_list[1]
43
44    @staticmethod
45    def get_element(line):
46        line = IniParser.remove_trailing_comment(line)
47        if not line:
48            return IniParser.Element.comment
49        if IniParser.is_section_header(line):
50            if line.strip()[1:-1].startswith('Suggestion'):
51                return IniParser.Element.sugg
52            if line.strip()[1:-1].startswith('Rule'):
53                return IniParser.Element.rule
54            if line.strip()[1:-1].startswith('Condition'):
55                return IniParser.Element.cond
56        if '=' in line:
57            return IniParser.Element.key_val
58        error = 'not a recognizable RulesSpec element'
59        raise ValueError('Parsing error: ' + error + '\n' + line)
60
61    @staticmethod
62    def get_key_value_pair(line):
63        line = line.strip()
64        key = line.split('=')[0].strip()
65        value = "=".join(line.split('=')[1:])
66        if value == "":  # if the option has no value
67            return (key, None)
68        values = IniParser.get_list_from_value(value)
69        if len(values) == 1:
70            return (key, value)
71        return (key, values)
72
73    @staticmethod
74    def get_list_from_value(value):
75        values = value.strip().split(':')
76        return values
77