1import os
2
3import checksymbolslib.br as br
4
5
6def all_symbols_from(line):
7    clean_line = br.re_comments.sub('', line)
8    symbols = br.re_kconfig_symbol.findall(clean_line)
9    return symbols
10
11
12def handle_definition(db, filename, lineno, line, legacy):
13    for symbol in all_symbols_from(line):
14        if legacy:
15            db.add_symbol_legacy_definition(symbol, filename, lineno)
16        else:
17            db.add_symbol_definition(symbol, filename, lineno)
18
19
20def handle_usage(db, filename, lineno, line, legacy):
21    for symbol in all_symbols_from(line):
22        if legacy:
23            db.add_symbol_usage_in_legacy(symbol, filename, lineno)
24        else:
25            db.add_symbol_usage(symbol, filename, lineno)
26
27
28def handle_default(db, filename, lineno, line, legacy):
29    if legacy:
30        handle_usage(db, filename, lineno, line, legacy)
31        return
32    if not br.re_kconfig_default_legacy_comment.search(line):
33        handle_usage(db, filename, lineno, line, legacy)
34        return
35    after = br.re_kconfig_default_before_conditional.sub('', line)
36    for symbol in all_symbols_from(after):
37        db.add_symbol_legacy_usage(symbol, filename, lineno)
38
39
40def handle_select(db, filename, lineno, line, legacy):
41    handle_usage(db, filename, lineno, line, legacy)
42    before = br.re_kconfig_select_conditional.sub('', line)
43    for symbol in all_symbols_from(before):
44        db.add_symbol_select(symbol, filename, lineno)
45
46
47line_type_handlers = {
48    br.re_kconfig_config: handle_definition,
49    br.re_kconfig_default: handle_default,
50    br.re_kconfig_depends: handle_usage,
51    br.re_kconfig_if: handle_usage,
52    br.re_kconfig_select: handle_select,
53    br.re_kconfig_source: handle_usage,
54}
55
56
57def handle_line(db, filename, lineno, line, legacy):
58    if not br.re_kconfig_symbol.search(line):
59        return
60
61    for regexp, line_type_handler in line_type_handlers.items():
62        if regexp.search(line):
63            line_type_handler(db, filename, lineno, line, legacy)
64
65
66def handle_config_helper(db, filename, file_content):
67    symbol = None
68    lineno = None
69    state = 'none'
70    for cur_lineno, line in file_content:
71        if state == 'none':
72            m = br.re_kconfig_config.search(line)
73            if m is not None:
74                symbol = m.group(2)
75                lineno = cur_lineno
76                state = 'config'
77            continue
78        if state == 'config':
79            if br.re_kconfig_select.search(line):
80                db.add_symbol_helper(symbol, filename, lineno)
81                state = 'none'
82                continue
83            m = br.re_kconfig_config.search(line)
84            if m is not None:
85                symbol = m.group(2)
86                lineno = cur_lineno
87            continue
88
89
90def handle_config_choice(db, filename, file_content):
91    state = 'none'
92    for lineno, line in file_content:
93        if state == 'none':
94            if br.re_kconfig_choice.search(line):
95                state = 'choice'
96                continue
97        if state == 'choice':
98            if br.re_kconfig_endchoice.search(line):
99                state = 'none'
100                continue
101            m = br.re_kconfig_config.search(line)
102            if m is not None:
103                symbol = m.group(2)
104                db.add_symbol_choice(symbol, filename, lineno)
105                continue
106
107
108def handle_note(db, filename, file_content):
109    state = 'none'
110    for lineno, line in file_content:
111        if state == 'none':
112            if br.re_menu.search(line):
113                state = 'menu'
114                continue
115        if state == 'menu':
116            if br.re_endmenu.search(line):
117                state = 'none'
118                continue
119            m = br.re_legacy_special_comment.search(line)
120            if m is not None:
121                symbol = m.group(1)
122                db.add_symbol_legacy_note(symbol, filename, lineno)
123                continue
124
125
126def populate_db(db, filename, file_content):
127    legacy = filename.endswith('.legacy')
128    for lineno, line in file_content:
129        handle_line(db, filename, lineno, line, legacy)
130    handle_config_helper(db, filename, file_content)
131    handle_config_choice(db, filename, file_content)
132    if legacy:
133        handle_note(db, filename, file_content)
134
135
136def check_filename(filename):
137    if os.path.basename(filename).startswith('Config.'):
138        return True
139    return False
140