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