xref: /aosp_15_r20/external/grpc-grpc/src/objective-c/change-comments.py (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1#!/usr/bin/env python2.7
2# Copyright 2015 gRPC authors.
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15"""Change comments style of source files from // to /** */"""
16
17import re
18import sys
19
20if len(sys.argv) < 2:
21    print("Please provide at least one source file name as argument.")
22    sys.exit()
23
24for file_name in sys.argv[1:]:
25    print(
26        "Modifying format of {file} comments in place...".format(
27            file=file_name,
28        )
29    )
30
31    # Input
32
33    with open(file_name, "r") as input_file:
34        lines = input_file.readlines()
35
36    def peek():
37        return lines[0]
38
39    def read_line():
40        return lines.pop(0)
41
42    def more_input_available():
43        return lines
44
45    # Output
46
47    output_lines = []
48
49    def write(line):
50        output_lines.append(line)
51
52    def flush_output():
53        with open(file_name, "w") as output_file:
54            for line in output_lines:
55                output_file.write(line)
56
57    # Pattern matching
58
59    comment_regex = r"^(\s*)//\s(.*)$"
60
61    def is_comment(line):
62        return re.search(comment_regex, line)
63
64    def isnt_comment(line):
65        return not is_comment(line)
66
67    def next_line(predicate):
68        return more_input_available() and predicate(peek())
69
70    # Transformation
71
72    def indentation_of(line):
73        match = re.search(comment_regex, line)
74        return match.group(1)
75
76    def content(line):
77        match = re.search(comment_regex, line)
78        return match.group(2)
79
80    def format_as_block(comment_block):
81        if len(comment_block) == 0:
82            return []
83
84        indent = indentation_of(comment_block[0])
85
86        if len(comment_block) == 1:
87            return [indent + "/** " + content(comment_block[0]) + " */\n"]
88
89        block = (
90            ["/**"]
91            + [" * " + content(line) for line in comment_block]
92            + [" */"]
93        )
94        return [indent + line.rstrip() + "\n" for line in block]
95
96    # Main algorithm
97
98    while more_input_available():
99        while next_line(isnt_comment):
100            write(read_line())
101
102        comment_block = []
103        # Get all lines in the same comment block. We could restrict the indentation
104        # to be the same as the first line of the block, but it's probably ok.
105        while next_line(is_comment):
106            comment_block.append(read_line())
107
108        for line in format_as_block(comment_block):
109            write(line)
110
111    flush_output()
112