Skip to content

Commit 81f4428

Browse files
authored
Merge pull request #564 from kvedala/clang-tidy
[enhancement] Added Clang tidy based static code analysis and formatting
2 parents 9a97810 + 25ceda9 commit 81f4428

File tree

3 files changed

+144
-71
lines changed

3 files changed

+144
-71
lines changed

.clang-tidy

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
Checks: '-*,google-*,clang-diagnostic-*,clang-analyzer-*,-clang-analyzer-security.insecureAPI.*,openmp-*,performance-*,portability-*,modernize-*'
3+
WarningsAsErrors: '*,-google-readability-*,-google-explicit-constructor,-modernize-*,modernize-avoid-c-arrays,-google-explicit-constructor,-performance-move-const-arg,-performance-noexcept-move-constructor,'
4+
HeaderFilterRegex: ''
5+
AnalyzeTemporaryDtors: false
6+
FormatStyle: '{ BasedOnStyle: Google, UseTab: Never, IndentWidth: 4, TabWidth: 4, BreakBeforeBraces: Allman, AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false, ColumnLimit: 80, AccessModifierOffset: -4 }'

.github/workflows/awesome_workflow.yml

Lines changed: 110 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ jobs:
1414
- uses: actions/checkout@v1 # v2 is broken for git diff
1515
- uses: actions/setup-python@v2
1616
- name: requirements
17-
run: |
17+
run: |
1818
sudo apt -qq -y update
19-
sudo apt -qq install clang-format
19+
sudo apt -qq install clang-tidy-10
2020
- name: Setup Git Specs
2121
run: |
2222
git config --global user.name github-actions
@@ -26,7 +26,7 @@ jobs:
2626
run: |
2727
IFS=$'\n'
2828
for fname in `find . -type f -name '*.c' -o -name '*.h'`
29-
do
29+
do
3030
echo "${fname}"
3131
new_fname=`echo ${fname} | tr ' ' '_'`
3232
echo " ${new_fname}"
@@ -41,73 +41,118 @@ jobs:
4141
fi
4242
done
4343
git commit -am "formatting filenames $GITHUB_SHA" || true
44-
- name: Clang Formatter
45-
run: |
46-
for fname in $(find . -name '*.c' -o -name '*.h')
47-
do
48-
clang-format --verbose -i --style="$line1 $line2 $line3 $line4" "$fname"
49-
done
50-
git commit -am "formatting source-code for $GITHUB_SHA" || true
51-
env:
52-
line1: "{ BasedOnStyle: Google, UseTab: Never,"
53-
line2: "IndentWidth: 4, TabWidth: 4, BreakBeforeBraces: Allman,"
54-
line3: "AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false,"
55-
line4: "ColumnLimit: 80, AccessModifierOffset: -4 }"
56-
- name: Git Push
57-
run: git push --force origin HEAD:$GITHUB_REF || true
58-
5944
- name: Update DIRECTORY.md
6045
shell: python
6146
run: |
62-
import os
63-
from typing import Iterator
64-
65-
URL_BASE = "https://github.com/TheAlgorithms/C/blob/master"
66-
g_output = []
67-
68-
def good_filepaths(top_dir: str = ".") -> Iterator[str]:
69-
cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split())
70-
for dirpath, dirnames, filenames in os.walk(top_dir):
71-
dirnames[:] = [d for d in dirnames if d[0] not in "._"]
72-
for filename in filenames:
73-
if os.path.splitext(filename)[1].lower() in cpp_exts:
74-
yield os.path.join(dirpath, filename).lstrip("./")
75-
76-
def md_prefix(i):
77-
return f"{i * ' '}*" if i else "\n##"
78-
79-
def print_path(old_path: str, new_path: str) -> str:
80-
global g_output
81-
old_parts = old_path.split(os.sep)
82-
for i, new_part in enumerate(new_path.split(os.sep)):
83-
if i + 1 > len(old_parts) or old_parts[i] != new_part:
84-
if new_part:
85-
g_output.append(f"{md_prefix(i)} {new_part.replace('_', ' ').title()}")
86-
return new_path
87-
88-
def build_directory_md(top_dir: str = ".") -> str:
89-
global g_output
90-
old_path = ""
91-
for filepath in sorted(good_filepaths(), key=str.lower):
92-
filepath, filename = os.path.split(filepath)
93-
if filepath != old_path:
94-
old_path = print_path(old_path, filepath)
95-
indent = (filepath.count(os.sep) + 1) if filepath else 0
96-
url = "/".join((URL_BASE, filepath, filename)).replace(" ", "%20")
97-
filename = os.path.splitext(filename.replace("_", " ").title())[0]
98-
g_output.append(f"{md_prefix(indent)} [{filename}]({url})")
99-
return "# List of all files\n" + "\n".join(g_output)
100-
101-
with open("DIRECTORY.md", "w") as out_file:
102-
out_file.write(build_directory_md(".") + "\n")
103-
- name: Update DIRECTORY.md
47+
import os
48+
from typing import Iterator
49+
50+
URL_BASE = "https://github.com/TheAlgorithms/C/blob/master"
51+
g_output = []
52+
53+
def good_filepaths(top_dir: str = ".") -> Iterator[str]:
54+
cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split())
55+
for dirpath, dirnames, filenames in os.walk(top_dir):
56+
dirnames[:] = [d for d in dirnames if d[0] not in "._"]
57+
for filename in filenames:
58+
if os.path.splitext(filename)[1].lower() in cpp_exts:
59+
yield os.path.join(dirpath, filename).lstrip("./")
60+
61+
def md_prefix(i):
62+
return f"{i * ' '}*" if i else "\n##"
63+
64+
def print_path(old_path: str, new_path: str) -> str:
65+
global g_output
66+
old_parts = old_path.split(os.sep)
67+
for i, new_part in enumerate(new_path.split(os.sep)):
68+
if i + 1 > len(old_parts) or old_parts[i] != new_part:
69+
if new_part:
70+
g_output.append(f"{md_prefix(i)} {new_part.replace('_', ' ').title()}")
71+
return new_path
72+
73+
def build_directory_md(top_dir: str = ".") -> str:
74+
global g_output
75+
old_path = ""
76+
for filepath in sorted(good_filepaths(), key=str.lower):
77+
filepath, filename = os.path.split(filepath)
78+
if filepath != old_path:
79+
old_path = print_path(old_path, filepath)
80+
indent = (filepath.count(os.sep) + 1) if filepath else 0
81+
url = "/".join((URL_BASE, filepath, filename)).replace(" ", "%20")
82+
filename = os.path.splitext(filename.replace("_", " ").title())[0]
83+
g_output.append(f"{md_prefix(indent)} [{filename}]({url})")
84+
return "# List of all files\n" + "\n".join(g_output)
85+
86+
with open("DIRECTORY.md", "w") as out_file:
87+
out_file.write(build_directory_md(".") + "\n")
88+
- name: Commit DIRECTORY.md
10489
run: |
105-
cat DIRECTORY.md
106-
git config --global user.name github-actions
107-
git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'
108-
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
90+
git diff DIRECTORY.md
10991
git add DIRECTORY.md
110-
git commit -am "updating DIRECTORY.md" || true
92+
git commit -m "updating DIRECTORY.md" || true
93+
- name: Get file changes
94+
run: |
95+
git remote -v
96+
git branch
97+
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
98+
git diff --diff-filter=dr --name-only origin/master > git_diff.txt
99+
echo "Files changed-- `cat git_diff.txt`"
100+
- name: Configure for static lint checks
101+
# compiling first gives clang-tidy access to all the header files and settings used to compile the programs.
102+
# This will check for macros, if any, on linux and not for Windows. But the use of portability checks should
103+
# be able to catch any errors for other platforms.
104+
run: cmake -B build -S . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
105+
- name: Lint modified files
106+
shell: python
107+
run: |
108+
import os
109+
import subprocess
110+
import sys
111+
112+
print("Python {}.{}.{}".format(*sys.version_info)) # Python 3.8
113+
with open("git_diff.txt") as in_file:
114+
modified_files = sorted(in_file.read().splitlines())
115+
print("{} files were modified.".format(len(modified_files)))
116+
117+
cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split())
118+
cpp_files = [file for file in modified_files if file.lower().endswith(cpp_exts)]
119+
print(f"{len(cpp_files)} C++ files were modified.")
120+
if not cpp_files:
121+
sys.exit(0)
122+
123+
subprocess.run(["clang-tidy-10", "-p=build", "--fix", *cpp_files, "--"],
124+
check=True, text=True, stderr=subprocess.STDOUT)
125+
# for cpp_file in cpp_files:
126+
# subprocess.run(["clang-tidy-10", "-p=build", cpp_file, "--"],
127+
# check=True, text=True, stderr=subprocess.STDOUT)
128+
129+
# print("g++:")
130+
# compile_exts = tuple(".c .c++ .cc .cpp .cu .cxx".split())
131+
# compile_files = [file for file in cpp_files if file.lower().endswith(compile_exts)]
132+
# for cpp_file in cpp_files:
133+
# subprocess.run(["g++", cpp_file], check=True, text=True)
134+
135+
upper_files = [file for file in cpp_files if file != file.lower()]
136+
if upper_files:
137+
print(f"{len(upper_files)} files contain uppercase characters:")
138+
print("\n".join(upper_files) + "\n")
139+
140+
space_files = [file for file in cpp_files if " " in file or "-" in file]
141+
if space_files:
142+
print(f"{len(space_files)} files contain space or dash characters:")
143+
print("\n".join(space_files) + "\n")
144+
145+
nodir_files = [file for file in cpp_files if file.count(os.sep) != 1]
146+
if nodir_files:
147+
print(f"{len(nodir_files)} files are not in one and only one directory:")
148+
print("\n".join(nodir_files) + "\n")
149+
150+
bad_files = len(upper_files + space_files + nodir_files)
151+
if bad_files:
152+
sys.exit(bad_files)
153+
- name: Commit and push changes
154+
run: |
155+
git commit -am "clang-tidy fixes for $GITHUB_SHA" || true
111156
git push --force origin HEAD:$GITHUB_REF || true
112157
113158
build:

numerical_methods/qr_eigen_values.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,13 @@ double **mat_mul(double **A, double **B, double **OUT, int R1, int C1, int R2,
7070
#pragma omp for
7171
#endif
7272
for (i = 0; i < R1; i++)
73+
{
7374
for (int j = 0; j < C2; j++)
7475
{
7576
OUT[i][j] = 0.f;
7677
for (int k = 0; k < C1; k++) OUT[i][j] += A[i][k] * B[k][j];
7778
}
79+
}
7880
return OUT;
7981
}
8082

@@ -104,17 +106,24 @@ double **mat_mul(double **A, double **B, double **OUT, int R1, int C1, int R2,
104106
double eigen_values(double **A, double *eigen_vals, int mat_size,
105107
char debug_print)
106108
{
107-
double **R = (double **)malloc(sizeof(double *) * mat_size);
108-
double **Q = (double **)malloc(sizeof(double *) * mat_size);
109-
110109
if (!eigen_vals)
111110
{
112111
perror("Output eigen value vector cannot be NULL!");
113112
return -1;
114113
}
115-
else if (!Q || !R)
114+
double **R = (double **)malloc(sizeof(double *) * mat_size);
115+
double **Q = (double **)malloc(sizeof(double *) * mat_size);
116+
if (!Q || !R)
116117
{
117118
perror("Unable to allocate memory for Q & R!");
119+
if (Q)
120+
{
121+
free(Q);
122+
}
123+
if (R)
124+
{
125+
free(R);
126+
}
118127
return -1;
119128
}
120129

@@ -126,12 +135,21 @@ double eigen_values(double **A, double *eigen_vals, int mat_size,
126135
if (!Q[i] || !R[i])
127136
{
128137
perror("Unable to allocate memory for Q & R.");
138+
for (; i >= 0; i--)
139+
{
140+
free(R[i]);
141+
free(Q[i]);
142+
}
143+
free(Q);
144+
free(R);
129145
return -1;
130146
}
131147
}
132148

133149
if (debug_print)
150+
{
134151
print_matrix(A, mat_size, mat_size);
152+
}
135153

136154
int rows = mat_size, columns = mat_size;
137155
int counter = 0, num_eigs = rows - 1;
@@ -208,7 +226,7 @@ void test1()
208226
int mat_size = 2;
209227
double X[][2] = {{5, 7}, {7, 11}};
210228
double y[] = {15.56158, 0.384227}; // corresponding y-values
211-
double eig_vals[2];
229+
double eig_vals[2] = {0, 0};
212230

213231
// The following steps are to convert a "double[][]" to "double **"
214232
double **A = (double **)malloc(mat_size * sizeof(double *));
@@ -300,7 +318,9 @@ int main(int argc, char **argv)
300318

301319
int mat_size = 5;
302320
if (argc == 2)
321+
{
303322
mat_size = atoi(argv[1]);
323+
}
304324
else
305325
{ // if invalid input argument is given run tests
306326
test1();
@@ -315,19 +335,21 @@ int main(int argc, char **argv)
315335
return -1;
316336
}
317337

318-
int i, rows = mat_size, columns = mat_size;
338+
int i;
319339

320340
double **A = (double **)malloc(sizeof(double *) * mat_size);
321341
/* number of eigen values = matrix size */
322342
double *eigen_vals = (double *)malloc(sizeof(double) * mat_size);
323343
if (!eigen_vals)
324344
{
325345
perror("Unable to allocate memory for eigen values!");
346+
free(A);
326347
return -1;
327348
}
328349
for (i = 0; i < mat_size; i++)
329350
{
330351
A[i] = (double *)malloc(sizeof(double) * mat_size);
352+
eigen_vals[i] = 0.f;
331353
}
332354

333355
/* create a random matrix */

0 commit comments

Comments
 (0)