Compute Library
 22.05
format_doxygen.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 import os.path
3 import re
4 import sys
5 
6 def process_comment(fd, comment, first_param, last_param):
7  if first_param < 0:
8  # Nothing to do: just copy the comment
9  fd.write("".join(comment))
10  else:
11  params = list()
12 
13  # Measure the indentation of the first param and use that to create an empty comment line string:
14  m = re.match(r" */", comment[0])
15 
16  if not m:
17  raise Exception("{}: Not a comment ? '{}'".format(path,comment[first_param]))
18 
19  line_prefix = " " * len(m.group(0)) + "*"
20  empty_line = line_prefix +"\n"
21 
22  fd.write(comment[0])
23  # Copy the non param lines with the correct indentation:
24  for comment_line in range(1,first_param):
25  line = comment[comment_line]
26  m = re.match(" *\*(.*)", line)
27  if not m:
28  raise Exception("{}:{}: Not a comment line ? ".format(path, n_line - len(comment) + comment_line + 1))
29  fd.write(line_prefix+ m.group(1)+"\n")
30 
31  # For each param split the line into 3 columns: param, param_name, description
32  for param in range(first_param, last_param):
33  m = re.match(r"[^@]+(@param\[[^\]]+\]) +(\S+) +(.+)", comment[param])
34 
35  if m:
36  params.append( (" "+m.group(1), m.group(2), m.group(3)) )
37  else:
38  # If it's not a match then it must be a multi-line param description:
39 
40  m = re.match(" *\* +(.*)", comment[param])
41  if not m:
42  raise Exception("{}:{}: Not a comment line ? ".format(path, n_line - len(comment) + param + 1))
43 
44  params.append( ("", "", m.group(1)) )
45 
46  # Now that we've got a list of params, find what is the longest string for each column:
47  max_len = [0, 0]
48 
49  for p in params:
50  for l in range(len(max_len)):
51  max_len[l] = max(max_len[l], len(p[l]))
52 
53  # Insert an empty line if needed before the first param to make it easier to read:
54  m = re.match(r" *\* *$", comment[first_param - 1])
55 
56  if not m:
57  # insert empty line
58  fd.write(empty_line)
59 
60  # Write out the formatted list of params:
61  for p in params:
62  fd.write("{}{}{} {}{} {}\n".format( line_prefix,
63  p[0], " " * (max_len[0] - len(p[0])),
64  p[1], " " * (max_len[1] - len(p[1])),
65  p[2]))
66 
67  # If the next line after the list of params is a command (@return, @note, @warning, etc), insert an empty line to separate it from the list of params
68  if last_param < len(comment) - 1:
69  if re.match(r" *\* *@\w+", comment[last_param]):
70  # insert empty line
71  fd.write(empty_line)
72 
73  # Copy the remaining of the comment with the correct indentation:
74  for comment_line in range(last_param,len(comment)):
75  line = comment[comment_line]
76  m = re.match(" *\*(.*)", line)
77  if not m:
78  raise Exception("{}:{}: Not a comment line ? ".format(path, n_line - len(comment) + comment_line + 1))
79  fd.write(line_prefix+ m.group(1)+"\n")
80 
81 if __name__ == "__main__":
82  n_file=0
83 
84  if len(sys.argv) == 1:
85  paths = []
86 
87  for top_level in ["./arm_compute", "./src", "./examples", "./tests", "./utils", "./framework", "./support"]:
88  for root, _, files in os.walk(top_level):
89  paths.extend([os.path.join(root, f) for f in files])
90  else:
91  paths = sys.argv[1:]
92 
93  for path in paths:
94  if (path[-3:] not in ("cpp", "inl") and
95  path[-2:] not in ("cl") and
96  path[-2:] not in ("cs") and
97  path[-1] not in ("h")):
98  continue
99 
100  print("[{}] {}".format(n_file, path))
101 
102  n_file += 1
103 
104  with open(path,'r+', encoding="utf-8") as fd:
105  comment = list()
106  first_param = -1
107  last_param = -1
108  n_line = 0
109 
110  lines = fd.readlines()
111  fd.seek(0)
112  fd.truncate()
113 
114  for line in lines:
115  n_line += 1
116 
117  # Start comment
118  # Match C-style comment /* anywhere in the line
119  if re.search(r"/\*", line):
120  #print("Start comment {}".format(n_line))
121 
122  if len(comment) > 0:
123  raise Exception("{}:{}: Already in a comment!".format(path,n_line))
124 
125  comment.append(line)
126 
127  # Comment already started
128  elif len(comment) > 0:
129  #print("Add line to comment {}".format(n_line))
130 
131  comment.append(line)
132 
133  # Non-comment line
134  else:
135  #print("Normal line {}".format(n_line))
136 
137  fd.write(line)
138 
139  # Match param declaration in Doxygen comment
140  # @param[in] name description
141  if re.search(r"@param\[[^\]]+\] +\S+ +\S", line):
142  #print("Param {}".format(n_line))
143 
144  if first_param < 0:
145  first_param = len(comment) - 1
146 
147  last_param = len(comment)
148 
149  # Match end of C-style comment */
150  if re.search(r"\*/", line):
151  if re.search('"[^"]*\*/[^"]*"', line):
152  #print("End of comment inside a string: ignoring")
153  pass
154  else:
155  #print("End comment {}".format(n_line))
156 
157  if len(comment) < 1:
158  raise Exception("{}:{}: Was not in a comment! ".format(path, n_line))
159 
160  #print("Process comment {} {}".format(first_param, last_param))
161 
162  process_comment(fd, comment, first_param, last_param)
163 
164  comment = list()
165  first_param = -1
166  last_param = -1
std::string join(T first, T last, const std::string &separator)
Helper function to concatenate multiple strings.
Definition: Utils.h:93
SimpleTensor< T > range(SimpleTensor< T > &dst, float start, const size_t num_of_elements, float step)
Definition: Range.cpp:50
def process_comment(fd, comment, first_param, last_param)