@@ -30,7 +30,105 @@ jobs:
3030 unzip -q pmd.zip
3131 PMD_HOME="pmd-bin-${PMD_VERSION}"
3232
33+ SOURCE_DIR="${1:-src}"
34+ total_files=$(find "$SOURCE_DIR" -type f \( -name "*.f" -o -name "*.f90" -o -name "*.for" -o -name "*.fpp" -o -name "*.F" -o -name "*.F90" \) | wc -l)
35+ processed=0
36+
37+ find "$SOURCE_DIR" -type f \( -name "*.f" -o -name "*.f90" -o -name "*.for" -o -name "*.fpp" -o -name "*.F" -o -name "*.F90" \) -print0 |
38+ while IFS= read -r -d $'\0' file; do
39+ processed=$((processed + 1))
40+ echo -e "[$processed/$total_files] Processing ${file}..."
41+
42+ # Create a temporary file with same permissions as original
43+ TMP_FILE=$(mktemp)
44+ if [ $? -ne 0 ]; then
45+ echo -e "Failed to create temporary file for $file, skipping"
46+ continue
47+ fi
48+
49+ # Copy permissions from original file
50+ chmod --reference="$file" "$TMP_FILE"
51+
52+ # More comprehensive sed command to handle different Fortran comment styles:
53+ # 1. Replace lines that are entirely comments with an empty line:
54+ # - Lines starting with '!' (free form comments)
55+ # - Lines starting with 'c', 'C', '*', 'd', 'D' in column 1 (fixed form comments)
56+ # 2. Remove end-of-line comments (anything after '!' that isn't in a string)
57+ # 3. Preserve strings containing '!' characters
58+ sed -E '
59+ # First handle & continuation style (modern Fortran)
60+ :ampersand_loop
61+ /&[[:space:]]*$/ {
62+ N
63+ s/&[[:space:]]*\n[[:space:]]*(&)?/ /g
64+ tampersand_loop
65+ }
66+
67+ # Handle fixed-form continuation (column 6 indicator)
68+ :fixed_form_loop
69+ /^[[:space:]]{0,5}[^[:space:]!&]/ {
70+ N
71+ s/\n[[:space:]]{5}[^[:space:]]/ /g
72+ tfixed_form_loop
73+ }
74+
75+ # Remove any remaining continuation markers
76+ s/&//g
77+
78+ # Normalize spacing - replace multiple spaces with single space
79+ s/[[:space:]]{2,}/ /g
80+
81+ # Remove spaces around mathematical operators
82+ s/[[:space:]]*\*[[:space:]]*/*/g
83+ s/[[:space:]]*\+[[:space:]]*/+/g
84+ s/[[:space:]]*-[[:space:]]*/-/g
85+ s/[[:space:]]*\/[[:space:]]*/\//g
86+ s/[[:space:]]*\*\*[[:space:]]*/\*\*/g
87+
88+ # Remove spaces in common Fortran constructs (array indexing, function calls)
89+ s/\([[:space:]]*([^,)[:space:]]+)[[:space:]]*,/(\1,/g # First argument
90+ s/,[[:space:]]*([^,)[:space:]]+)[[:space:]]*,/,\1,/g # Middle arguments
91+ s/,[[:space:]]*([^,)[:space:]]+)[[:space:]]*\)/,\1)/g # Last argument
92+ s/\([[:space:]]*([^,)[:space:]]+)[[:space:]]*\)/(\1)/g # Single argument
93+
94+ # Remove spaces around brackets and parentheses
95+ s/\[[[:space:]]*/</g
96+ s/\[[[:space:]]*/>/g
97+ s/\[[[:space:]]*/</g
98+ s/[[:space:]]*\]/]/g
99+ s/\([[:space:]]*/(/g
100+ s/[[:space:]]*\)/)/g
101+
102+ # Remove spaces around comparison operators
103+ s/[[:space:]]*<=[[:space:]]*/</g
104+ s/[[:space:]]*>=[[:space:]]*/>/g
105+ s/[[:space:]]*<[[:space:]]*/</g
106+ s/[[:space:]]*>[[:space:]]*/>/g
107+ s/[[:space:]]*==[[:space:]]*/==/g
108+
109+ # Remove full-line comments
110+ /^\s*!/d
111+ /^[cC*dD]/d
112+ /^[ \t]*[cC*dD]/d
113+ /^[[:space:]]*$/d
114+
115+ # Remove end-of-line comments, preserving quoted strings
116+ s/([^"'\''\\]*("[^"]*")?('\''[^'\'']*'\''?)?[^"'\''\\]*)[!].*$/\1/
117+ ' "$file" > "$TMP_FILE"
118+
119+ if cmp -s "$file" "$TMP_FILE"; then
120+ echo -e "No changes needed for $file"
121+ rm "$TMP_FILE"
122+ else
123+ # Overwrite the original file with the processed content
124+ mv "$TMP_FILE" "$file"
125+ echo -e "Successfully processed $file"
126+ fi
127+ done
128+
33129 "${PMD_HOME}/bin/pmd" cpd \
34130 --dir src \
35131 --language fortran \
36- --minimum-tokens=40
132+ --minimum-tokens=20 \
133+ --no-fail-on-violation \
134+ --no-fail-on-error
0 commit comments