13af6ab5fSopenharmony_ci#!/usr/bin/env python3
23af6ab5fSopenharmony_ci# coding=utf-8
33af6ab5fSopenharmony_ci#
43af6ab5fSopenharmony_ci# Copyright (c) 2024 Huawei Device Co., Ltd.
53af6ab5fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
63af6ab5fSopenharmony_ci# you may not use this file except in compliance with the License.
73af6ab5fSopenharmony_ci# You may obtain a copy of the License at
83af6ab5fSopenharmony_ci#
93af6ab5fSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0
103af6ab5fSopenharmony_ci#
113af6ab5fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
123af6ab5fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
133af6ab5fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143af6ab5fSopenharmony_ci# See the License for the specific language governing permissions and
153af6ab5fSopenharmony_ci# limitations under the License.
163af6ab5fSopenharmony_ci
173af6ab5fSopenharmony_ci
183af6ab5fSopenharmony_cifrom typing import Tuple, Dict, Any
193af6ab5fSopenharmony_cifrom text_tools import find_first_not_restricted_character, find_scope_borders, find_first_of_characters, smart_split_by
203af6ab5fSopenharmony_cifrom line_iterator import LineIterator
213af6ab5fSopenharmony_ci
223af6ab5fSopenharmony_ci# Weakness: define define !endif! endif
233af6ab5fSopenharmony_ci
243af6ab5fSopenharmony_ci
253af6ab5fSopenharmony_cidef parse_define_macros(data: str, start: int = 0) -> Tuple[int, Dict]:
263af6ab5fSopenharmony_ci    res: Dict[str, Any] = {}
273af6ab5fSopenharmony_ci
283af6ab5fSopenharmony_ci    pos, res["name"] = parse_define_macros_name(data, start)
293af6ab5fSopenharmony_ci    end_of_line = find_first_of_characters("\n", data, start)
303af6ab5fSopenharmony_ci
313af6ab5fSopenharmony_ci    if data[pos] == "(":
323af6ab5fSopenharmony_ci        open_parenthesis, close_parenthesis = find_scope_borders(data, pos, "(")
333af6ab5fSopenharmony_ci        res["arguments"] = data[open_parenthesis + 1 : close_parenthesis]
343af6ab5fSopenharmony_ci        pos = close_parenthesis + 1
353af6ab5fSopenharmony_ci
363af6ab5fSopenharmony_ci    backslash_pos = find_first_of_characters("\\", data, pos)
373af6ab5fSopenharmony_ci    if backslash_pos + 1 != end_of_line:
383af6ab5fSopenharmony_ci        if data[pos:end_of_line].strip(" ") != "":
393af6ab5fSopenharmony_ci            res["body"] = data[pos:end_of_line].strip(" ")
403af6ab5fSopenharmony_ci        return end_of_line, res
413af6ab5fSopenharmony_ci
423af6ab5fSopenharmony_ci    it = LineIterator(data, end_of_line + 1)
433af6ab5fSopenharmony_ci    need_to_parse = it.current_line.strip(" ").startswith("_(")
443af6ab5fSopenharmony_ci
453af6ab5fSopenharmony_ci    if need_to_parse:
463af6ab5fSopenharmony_ci        res["values"] = []
473af6ab5fSopenharmony_ci
483af6ab5fSopenharmony_ci        while it.next_line() and it.data[it.end - 1] == "\\":
493af6ab5fSopenharmony_ci            res["values"].append(parse_mapping_value(it.current_line))
503af6ab5fSopenharmony_ci        res["values"].append(parse_mapping_value(it.current_line))
513af6ab5fSopenharmony_ci        res["values"] = list(filter(None, res["values"]))
523af6ab5fSopenharmony_ci    else:
533af6ab5fSopenharmony_ci        while it.next_line():
543af6ab5fSopenharmony_ci            if it.data[it.end - 1] != "\\":
553af6ab5fSopenharmony_ci                break
563af6ab5fSopenharmony_ci
573af6ab5fSopenharmony_ci    return it.end, res
583af6ab5fSopenharmony_ci
593af6ab5fSopenharmony_ci
603af6ab5fSopenharmony_cidef parse_mapping_value(data: str) -> list:
613af6ab5fSopenharmony_ci    data = data.strip(" _()\\")
623af6ab5fSopenharmony_ci    return smart_split_by(data)
633af6ab5fSopenharmony_ci
643af6ab5fSopenharmony_ci
653af6ab5fSopenharmony_cidef parse_define_macros_name(data: str, start: int) -> Tuple[int, str]:
663af6ab5fSopenharmony_ci    start_of_name = find_first_not_restricted_character(" \n", data, data.find("#define", start) + len("#define"))
673af6ab5fSopenharmony_ci    end_of_name = find_first_of_characters(" \n({[", data, start_of_name)
683af6ab5fSopenharmony_ci
693af6ab5fSopenharmony_ci    if end_of_name == len(data) or start_of_name == 0:
703af6ab5fSopenharmony_ci        raise RuntimeError("Can't find macros name.")
713af6ab5fSopenharmony_ci
723af6ab5fSopenharmony_ci    return end_of_name, data[start_of_name:end_of_name].strip(" \n")
73