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, List
19from log_tools import warning_log
20from text_tools import find_first_of_characters, find_scope_borders
21
22
23def remove_comments(data: str) -> str:
24    """
25    Returns data without c++ comments.
26    """
27    # Remove one-line comment
28    double_slash_pos = data.find("//")
29
30    while double_slash_pos != -1:
31        end_of_line = data.find("\n", double_slash_pos)
32
33        if end_of_line == -1:
34            end_of_line = len(data)
35            warning_log(f"Removing single-line comment at end of file:\n'{data[double_slash_pos:end_of_line]}'")
36
37        data = data[:double_slash_pos] + data[end_of_line:]
38        double_slash_pos = data.find("//")
39
40    # Remove multi-line comment
41    multiline_comment_start = data.find("/*")
42
43    while multiline_comment_start != -1:
44        multiline_comment_end = data.find("*/", multiline_comment_start)
45
46        if multiline_comment_end == -1:
47            raise RuntimeError("Error find end of multiline-comment")
48
49        data = data.replace(data[multiline_comment_start : multiline_comment_end + 2], "")
50        multiline_comment_start = data.find("/*")
51
52    return data.strip(" \n")
53
54
55def extract_and_remove_includes(data: str) -> Tuple[str, List[str]]:
56    """
57    Returns data without includes and list of includes in file in format like:
58    [ '<ir/expression.h>', '"es2panda.h"' ]
59    """
60    current_pos = data.find("#include")
61    res = []
62
63    while current_pos != -1:
64        include_start = find_first_of_characters('"<', data, current_pos)
65
66        if data[include_start] == '"':
67            include_end = data.find('"', include_start + 1)
68
69        else:
70            include_start, include_end = find_scope_borders(data, current_pos, "<")
71
72        if include_start != -1 and include_end != -1:
73            include = data[include_start : include_end + 1]
74            res.append(include)
75            data = data[:current_pos] + data[include_end + 1 :]
76
77            current_pos = data.find("#include", current_pos)
78
79        else:
80            raise RuntimeError("Error while parsing includes")
81
82    return data.strip(" \n"), res
83