• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# coding=utf-8
3#
4# Copyright (c) 2024 Huawei Device Co., Ltd.
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17
18from typing import Tuple, Dict, Any
19from text_tools import find_first_not_restricted_character, find_scope_borders, find_first_of_characters, smart_split_by
20from line_iterator import LineIterator
21from cpp_keywords import known_macroses
22
23# Weakness: define define !endif! endif
24
25
26def parse_define_macros(data: str, start: int = 0) -> Tuple[int, Dict]:
27    res: Dict[str, Any] = {}
28
29    pos, res["name"] = parse_define_macros_name(data, start)
30    end_of_line = find_first_of_characters("\n", data, start)
31
32    if data[pos] == "(":
33        open_parenthesis, close_parenthesis = find_scope_borders(data, pos, "(")
34        res["arguments"] = data[open_parenthesis + 1 : close_parenthesis]
35        pos = close_parenthesis + 1
36
37    backslash_pos = find_first_of_characters("\\", data, pos)
38    if backslash_pos + 1 != end_of_line:
39        if data[pos:end_of_line].strip(" ") != "":
40            res["body"] = data[pos:end_of_line].strip(" ")
41        return end_of_line, res
42
43    it = LineIterator(data, end_of_line + 1)
44    need_to_parse = it.current_line.strip(" ").startswith("_(")
45
46    if need_to_parse:
47        res["values"] = []
48
49        while it.next_line() and it.data[it.end - 1] == "\\":
50            res["values"].append(parse_mapping_value(it.current_line))
51        res["values"].append(parse_mapping_value(it.current_line))
52        res["values"] = list(filter(None, res["values"]))
53    else:
54        while it.next_line():
55            if it.data[it.end - 1] != "\\":
56                break
57
58    return it.end, res
59
60
61def parse_mapping_value(data: str) -> list:
62    data = data.strip(" _()\\")
63    return smart_split_by(data)
64
65
66def parse_define_macros_name(data: str, start: int) -> Tuple[int, str]:
67    start_of_name = find_first_not_restricted_character(" \n", data, data.find("#define", start) + len("#define"))
68    end_of_name = find_first_of_characters(" \n({[", data, start_of_name)
69
70    if end_of_name == len(data) or start_of_name == 0:
71        raise RuntimeError("Can't find macros name.")
72
73    return end_of_name, data[start_of_name:end_of_name].strip(" \n")
74
75
76def is_known_macros(data: str) -> bool:
77    for name in known_macroses:
78        if data.find(name) != -1:
79            return True
80    return False
81