Skip to content

Commit e7122ce

Browse files
committed
Introduce code formatting using Astyle 3.1
Add code style definition file for Astyle Add python script to launch Astyle on desired sources Add ignore path file http://astyle.sourceforge.net/ Signed-off-by: Frederic.Pillon <[email protected]>
1 parent 1d45db1 commit e7122ce

File tree

5 files changed

+293
-0
lines changed

5 files changed

+293
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
*.orig
22
*.swp
33
.DS_Store
4+
astyle.out
45
boards.local.txt
56
platform.local.txt

CI/astyle/.astyleignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.git
2+
CI
3+
system

CI/astyle/.astylerc

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# STM32duino code style definition file for astyle
2+
3+
# Don't create backup files, let git handle it
4+
suffix=none
5+
6+
# K&R style
7+
style=kr
8+
9+
# 1 TBS addition to k&r, add braces to one liners
10+
# Use -j as it was changed in astyle from brackets to braces, this way it is compatible with older astyle versions
11+
-j
12+
13+
# 2 spaces, convert tabs to spaces
14+
indent=spaces=2
15+
convert-tabs
16+
17+
# Indent switches and cases
18+
indent-classes
19+
indent-switches
20+
indent-cases
21+
indent-col1-comments
22+
23+
# Remove spaces in and around parentheses
24+
unpad-paren
25+
26+
# Insert a space after if, while, for, and around operators
27+
pad-header
28+
pad-oper
29+
30+
# Pointer/reference operators go next to the name (on the right)
31+
align-pointer=name
32+
align-reference=name
33+
34+
# Attach { for classes and namespaces
35+
attach-namespaces
36+
attach-classes
37+
38+
# Extend longer lines, define maximum 120 value. This results in aligned code,
39+
# otherwise the lines are broken and not consistent
40+
max-continuation-indent=120
41+
42+
# if you like one-liners, keep them
43+
keep-one-line-statements
44+
45+
#remove-comment-prefix

CI/astyle/.flake8

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[flake8]
2+
max-line-length = 88

CI/astyle/astyle.py

+242
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# File name : astyle.py
4+
# Author : Frederic PILLON <[email protected]>
5+
# Created : 11/16/2018
6+
# Python Version :
7+
# Requirements : Artistic Style Version 3.1
8+
# Description : Launch astyle on found source files
9+
10+
import argparse
11+
import os
12+
import re
13+
import subprocess
14+
import sys
15+
16+
script_path = os.path.dirname(os.path.abspath(__file__))
17+
ignore_filename = ".astyleignore"
18+
def_filename = ".astylerc"
19+
astyle_out_filename = "astyle.out"
20+
if os.getcwd() != script_path:
21+
src_path = os.getcwd()
22+
else:
23+
src_path = os.path.realpath(os.path.join("..", ".."))
24+
ignore_path = os.path.join(script_path, ignore_filename)
25+
def_path = os.path.join(script_path, def_filename)
26+
astyle_out_path = astyle_out_filename
27+
git_branch = "remotes/origin/master"
28+
29+
astyle_major = 3
30+
astyle_minor = 1
31+
astyle_path = ""
32+
if sys.platform.startswith("win32"):
33+
astyle_cmd = "astyle.exe"
34+
elif sys.platform.startswith("linux") or sys.platform.startswith("darwin"):
35+
astyle_cmd = "astyle"
36+
else:
37+
print("Platform unknown.")
38+
sys.exit(1)
39+
40+
# List
41+
source_list = []
42+
exclude_list = []
43+
44+
45+
# Check if path exists
46+
def checkPath(path, msg):
47+
if not os.path.exists(path):
48+
print(msg)
49+
sys.exit(1)
50+
51+
52+
# Check Astyle exists and version
53+
def checkAstyle():
54+
try:
55+
output = subprocess.check_output(
56+
[os.path.join(astyle_path, astyle_cmd), "--version"],
57+
stderr=subprocess.STDOUT,
58+
)
59+
60+
res = re.match("\\D*(\\d+)\\.(\\d+)\\.*(\\d*)", output.decode("utf-8"))
61+
if res:
62+
major = int(res.group(1))
63+
minor = int(res.group(2))
64+
if major >= astyle_major and minor >= astyle_minor:
65+
print(output.decode("utf-8").rstrip())
66+
else:
67+
print(
68+
"Required Astyle version {}.{} (Current: {}.{})".format(
69+
astyle_major, astyle_minor, major, minor
70+
)
71+
)
72+
sys.exit(1)
73+
else:
74+
raise subprocess.CalledProcessError(1, "No version found")
75+
except subprocess.CalledProcessError as e:
76+
print(e.output)
77+
sys.exit(1)
78+
79+
80+
# Find changes files in source root path
81+
def gitdiff_files():
82+
try:
83+
output = subprocess.check_output(
84+
["git", "rev-parse", "--show-toplevel"], stderr=subprocess.STDOUT
85+
)
86+
except subprocess.CalledProcessError as e:
87+
print(e.output)
88+
sys.exit(1)
89+
90+
gitroot = output.decode("utf-8").rstrip()
91+
rel_src = re.sub("^[/\\]+]", "", re.sub(gitroot, "", src_path))
92+
93+
cmd = []
94+
cmd.append("git")
95+
cmd.append("diff")
96+
cmd.append("--name-only")
97+
cmd.append("--diff-filter=d")
98+
cmd.append(git_branch)
99+
cmd.append("--relative=" + rel_src)
100+
101+
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
102+
while True:
103+
line = proc.stdout.readline().decode("utf-8").rstrip()
104+
if line == "" and proc.poll() is not None:
105+
break
106+
if line:
107+
if line.endswith((".h", ".c", ".hpp", ".cpp")):
108+
source_list.append(os.path.join(gitroot, line.rstrip()))
109+
if proc.poll() != 0:
110+
sys.exit(1)
111+
source_list.sort()
112+
113+
114+
# Find all files in source root path
115+
def find_files():
116+
for root, dirs, files in os.walk(src_path, followlinks=True):
117+
for f in files:
118+
if f.endswith((".h", ".c", ".hpp", ".cpp")):
119+
source_list.append(os.path.join(root, f))
120+
source_list.sort()
121+
122+
123+
# Filter source files list
124+
def manage_exclude_list():
125+
with open(ignore_path, "r") as f:
126+
for line in f.readlines():
127+
if line.rstrip():
128+
exclude_list.append(line.rstrip())
129+
if exclude_list:
130+
for pattern in exclude_list:
131+
exclude_pattern = re.compile(os.path.join(src_path, pattern) + ".*")
132+
for s in reversed(source_list):
133+
if exclude_pattern.search(s):
134+
source_list.remove(s)
135+
136+
137+
# Launch Astyle on all source files
138+
def astyle():
139+
cmd = []
140+
cmd.append(os.path.join(astyle_path, astyle_cmd))
141+
cmd.append("-n")
142+
cmd.append("--options=" + def_path)
143+
cmd.append("dummy_file")
144+
145+
stddout_name = astyle_out_path
146+
147+
for s in source_list:
148+
cmd[-1] = s
149+
with open(stddout_name, "a") as stdout:
150+
res = subprocess.Popen(cmd, stdout=stdout, stderr=subprocess.STDOUT)
151+
res.wait()
152+
# res.returncode
153+
154+
155+
# Parser
156+
parser = argparse.ArgumentParser(
157+
description="Launch astyle on source files found at specified root path."
158+
)
159+
160+
parser.add_argument(
161+
"-d",
162+
"--definition",
163+
metavar="<code style definition file>",
164+
help="Code style definition file for Astyle. Default: " + def_path,
165+
)
166+
g0 = parser.add_mutually_exclusive_group()
167+
g0.add_argument(
168+
"-g",
169+
"--gitdiff",
170+
help="Use changes files from git default branch. Default: " + git_branch,
171+
action="store_true",
172+
)
173+
g0.add_argument(
174+
"-b",
175+
"--branch",
176+
metavar="<branch name>",
177+
help="Use changes files from git specified branch.",
178+
)
179+
parser.add_argument(
180+
"-i",
181+
"--ignore",
182+
metavar="<ignore file>",
183+
help="File containing path to ignore. Default: " + ignore_path,
184+
)
185+
parser.add_argument(
186+
"-p", "--path", metavar="<astyle install path>", help="Astyle installation path"
187+
)
188+
parser.add_argument(
189+
"-r",
190+
"--root",
191+
metavar="<source root path>",
192+
help="Source root path to use. Default: " + src_path,
193+
)
194+
args = parser.parse_args()
195+
196+
197+
def main():
198+
global ignore_path
199+
global def_path
200+
global src_path
201+
global astyle_path
202+
global git_branch
203+
204+
if args.root:
205+
src_path = os.path.realpath(args.root)
206+
207+
if args.definition:
208+
def_path = os.path.realpath(args.definition)
209+
210+
if args.ignore:
211+
ignore_path = os.path.realpath(args.ignore)
212+
213+
if args.path:
214+
astyle_path = os.path.realpath(args.path)
215+
checkPath(
216+
os.path.join(astyle_path, astyle_cmd), "Could not find Astyle binary!"
217+
)
218+
219+
checkPath(src_path, "Source root path does not exist!")
220+
checkPath(def_path, "Code style definition file does not exist!")
221+
checkPath(ignore_path, "Ignore file does not exist!")
222+
checkAstyle()
223+
try:
224+
os.remove(astyle_out_path)
225+
except OSError:
226+
pass
227+
228+
if args.gitdiff or args.branch:
229+
if args.branch:
230+
git_branch = args.branch
231+
gitdiff_files()
232+
else:
233+
find_files()
234+
manage_exclude_list()
235+
if len(source_list):
236+
astyle()
237+
else:
238+
print("No file found to apply Astyle")
239+
240+
241+
if __name__ == "__main__":
242+
main()

0 commit comments

Comments
 (0)