]>
Commit | Line | Data |
---|---|---|
d743fb5d | 1 | #!/bin/sh |
a151895d | 2 | # |
1f7b830e | 3 | ## Copyright (C) 1996-2025 The Squid Software Foundation and contributors |
a151895d AJ |
4 | ## |
5 | ## Squid software is distributed under GPLv2+ license and includes | |
6 | ## contributions from numerous individuals and organizations. | |
7 | ## Please see the COPYING and CONTRIBUTORS files for details. | |
8 | ## | |
9 | ||
6f98e675 | 10 | # |
b510f3a1 | 11 | # This script contains the code run to perform automatic source maintenance |
a151895d | 12 | # on Squid |
b510f3a1 AJ |
13 | # |
14 | ||
1d2ed53d AJ |
15 | # whether to continue execution after a failure |
16 | # TODO: Expand the subset of failures covered by this feature; see run_(). | |
17 | KeepGoing="no" | |
18 | # the actual name of the directive that enabled keep-going mode | |
19 | KeepGoingDirective="" | |
c18dbaf9 | 20 | |
12e6d55e FC |
21 | # |
22 | # The script checks that the version of astyle is TargetAstyleVersion. | |
23 | # if it isn't, the default behaviour is to not perform the formatting stage | |
24 | # in order to avoid unexpected massive changes if the behaviour of astyle | |
25 | # has changed in different releases. | |
26 | # if --with-astyle /path/to/astyle is used, the check is still performed | |
27 | # and a warning is printed, but the sources are reformatted | |
b6388dfd | 28 | TargetAstyleVersion="3.1" |
12e6d55e | 29 | ASTYLE='astyle' |
1d2ed53d | 30 | |
e73ef62a AR |
31 | # whether to check and, if necessary, update boilerplate copyright years |
32 | CheckAndUpdateCopyright=yes | |
33 | ||
6e541c01 AJ |
34 | # How to sync CONTRIBUTORS with the current git branch commits: |
35 | # * never: Do not update CONTRIBUTORS at all. | |
36 | # * auto: Check commits added since the last similar update. | |
37 | # * SHA1/etc: Check commits added after the specified git commit. | |
38 | UpdateContributorsSince=auto | |
39 | ||
c18dbaf9 | 40 | # --only-changed-since point |
41 | OnlyChangedSince="" | |
42 | ||
e73ef62a | 43 | printUsage () { |
c18dbaf9 | 44 | cat <<USAGE_ |
45 | Usage: $0 [option...] | |
46 | options: | |
47 | --check-and-update-copyright <yes|no> (default: yes) | |
48 | --help|-h | |
49 | --keep-going|-k (default: stop on error) | |
50 | --only-changed-since <fork|commit> (default: apply to all files) | |
51 | --update-contributors-since <never|auto|revision> (default: auto) | |
52 | --with-astyle </path/to/astyle/executable> (default: astyle-${TargetAstyleVersion} or astyle) | |
53 | ||
54 | USAGE_ | |
55 | } | |
56 | ||
57 | printHelp () { | |
58 | ||
59 | cat <<HELP_INTRO_ | |
60 | This script applies Squid mandatory code style guidelines and generates | |
61 | various files derived from Squid sources. | |
62 | HELP_INTRO_ | |
63 | ||
64 | printUsage | |
65 | ||
66 | cat <<HELP_MAIN_ | |
67 | --help, -h | |
68 | ||
69 | Print this information and exit. | |
70 | ||
71 | --only-changed-since <"fork"|commit> | |
72 | ||
73 | When specifieid, the script only examines for formatting changes those | |
74 | files that have changed since the specified git reference point. The | |
75 | argument is either a git commit (fed to "git diff") or a special keyword | |
76 | "fork". Common commit values include HEAD^, master, origin/master, and the | |
77 | branch the current one was forked off. When "fork" is specified, the | |
78 | script will look for files changed since the current branch was forked off | |
79 | upstream/master (according to "git merge-base --fork-point"). | |
80 | ||
81 | This option does not disable some repository-wide file generation and | |
82 | repository-wide non-formatting checks/adjustments. | |
83 | ||
84 | --update-contributors-since <never|auto|revision> | |
85 | ||
86 | Configures how to sync CONTRIBUTORS with the current git branch commits: | |
87 | * never: Do not update CONTRIBUTORS at all. | |
88 | * auto: Check commits added since the last similar update. | |
89 | * SHA1/etc: Check commits added after the specified git commit. | |
90 | ||
91 | --with-astyle </path/to/astyle/executable> | |
92 | ||
93 | Squid code style guidelines require astyle version $TargetAstyleVersion. | |
94 | The path to the astyle binary can be specified using this command line | |
95 | option or by exporting the ASTYLE environment variable. If both are | |
96 | specified, the command-line option wins. | |
97 | ||
98 | External dependencies: | |
99 | ||
100 | * Astyle. See the --with-astyle command line option above. | |
101 | * gperf (if you modify certain source files) | |
102 | ||
103 | HELP_MAIN_ | |
e73ef62a AR |
104 | } |
105 | ||
1d2ed53d AJ |
106 | # command-line options |
107 | while [ $# -ge 1 ]; do | |
108 | case "$1" in | |
109 | --keep-going|-k) | |
110 | KeepGoing=yes | |
111 | KeepGoingDirective=$1 | |
112 | shift | |
113 | ;; | |
e73ef62a AR |
114 | --check-and-update-copyright) |
115 | if test "x$2" != xyes -a "x$2" != xno | |
116 | then | |
117 | printUsage | |
118 | echo "Error: Option $1 expects a yes or no argument but got $2" | |
c18dbaf9 | 119 | exit 1 |
e73ef62a AR |
120 | fi |
121 | CheckAndUpdateCopyright=$2 | |
122 | shift 2 | |
123 | ;; | |
6e541c01 AJ |
124 | --update-contributors-since) |
125 | if test "x$2" = x | |
126 | then | |
127 | printUsage | |
128 | echo "Error: Option $1 expects an argument." | |
c18dbaf9 | 129 | exit 1 |
6e541c01 AJ |
130 | fi |
131 | UpdateContributorsSince="$2" | |
c18dbaf9 | 132 | shift 2 |
6e541c01 | 133 | ;; |
e73ef62a | 134 | --help|-h) |
c18dbaf9 | 135 | printHelp |
136 | exit 0 | |
e73ef62a | 137 | ;; |
12e6d55e FC |
138 | --with-astyle) |
139 | ASTYLE=$2 | |
12e6d55e FC |
140 | shift 2 |
141 | ;; | |
c18dbaf9 | 142 | --only-changed-since) |
143 | OnlyChangedSince="$2" | |
144 | shift 2 | |
145 | ;; | |
1d2ed53d | 146 | *) |
e73ef62a | 147 | printUsage |
1d2ed53d | 148 | echo "Unsupported command-line option: $1" |
c18dbaf9 | 149 | exit 1 |
1d2ed53d AJ |
150 | ;; |
151 | esac | |
152 | done | |
153 | ||
154 | # an error code seen by a KeepGoing-aware command (or zero) | |
155 | SeenErrors=0 | |
156 | ||
1d2ed53d AJ |
157 | if ! git diff --quiet; then |
158 | echo "There are unstaged changes. This script may modify sources." | |
159 | echo "Stage changes to avoid permanent losses when things go bad." | |
160 | exit 1 | |
161 | fi | |
162 | ||
c18dbaf9 | 163 | # usage: <well-known program name> <program argument(s)> <candidate name>... |
164 | # Finds the first working program among the given candidate program names. | |
165 | # The found program name is returned via the $FoundProgram global: | |
166 | FoundProgram="" | |
167 | findProgram () | |
168 | { | |
169 | wellKnown="$1" | |
170 | shift | |
171 | options="$1" | |
172 | shift | |
173 | ||
174 | for candidate in $* | |
175 | do | |
176 | if "$candidate" $options < /dev/null > /dev/null 2> /dev/null | |
177 | then | |
178 | echo "Found ${wellKnown}-like program: $candidate" | |
179 | FoundProgram="$candidate" | |
180 | return 0 | |
181 | fi | |
182 | done | |
183 | ||
184 | echo "ERROR: Failed to find a ${wellKnown}-like program; tried: $*" | |
185 | FoundProgram="" | |
186 | return 1 | |
187 | } | |
188 | ||
52d824b5 AR |
189 | made="generated" # a hack: prevents $GeneratedByMe searches matching this file |
190 | GeneratedByMe="This file is $made by scripts/source-maintenance.sh." | |
191 | ||
c18dbaf9 | 192 | if [ "x$ASTYLE" != "x" ] ; then |
193 | if ! "${ASTYLE}" --version > /dev/null 2> /dev/null ; then | |
194 | echo "ERROR: Cannot run user-supplied astyle: ${ASTYLE}" | |
195 | exit 1 | |
196 | fi | |
197 | else | |
198 | findProgram astyle --version astyle-${TargetAstyleVersion} astyle || exit $? | |
199 | ASTYLE=$FoundProgram | |
12e6d55e | 200 | fi |
c18dbaf9 | 201 | |
202 | ASVER=`"${ASTYLE}" --version 2>&1 | grep -o -E "[0-9.]+"` | |
12e6d55e FC |
203 | if test "${ASVER}" != "${TargetAstyleVersion}" ; then |
204 | if test "${ASTYLE}" = "astyle" ; then | |
205 | echo "Astyle version problem. You have ${ASVER} instead of ${TargetAstyleVersion}" | |
206 | echo "Formatting step skipped due to version mismatch" | |
207 | ASVER="" | |
208 | else | |
209 | echo "WARNING: ${ASTYLE} is version ${ASVER} instead of ${TargetAstyleVersion}" | |
210 | echo "Formatting anyway, please double check output before submitting" | |
211 | fi | |
f77fbf5b | 212 | else |
c18dbaf9 | 213 | echo "Detected expected astyle version: ${ASVER}" |
f77fbf5b | 214 | fi |
761dced3 AR |
215 | CppFormatter='' |
216 | if test "${ASVER}"; then | |
217 | CppFormatter="./scripts/format-cpp.pl --with-astyle ${ASTYLE}" | |
218 | fi | |
f77fbf5b | 219 | |
c18dbaf9 | 220 | if test "x$OnlyChangedSince" = "xfork" ; then |
221 | ForkPoint=`git merge-base --fork-point upstream/master` | |
222 | if test "x$ForkPoint" = "x" ; then | |
223 | echo "Could not identify fork point - sometimes it happens" | |
224 | echo "Please specify commit-id explicitly" | |
225 | exit 1 | |
226 | fi | |
227 | OnlyChangedSince="$ForkPoint" | |
228 | fi | |
229 | ||
e73ef62a AR |
230 | if test $CheckAndUpdateCopyright = yes |
231 | then | |
232 | COPYRIGHT_YEARS=`date +"1996-%Y"` | |
233 | echo "s/1996-2[0-9]+ The Squid Software Foundation and contributors/${COPYRIGHT_YEARS} The Squid Software Foundation and contributors/g" >> boilerplate_fix.sed | |
234 | fi | |
e819858c | 235 | |
1d2ed53d AJ |
236 | # executes the specified command |
237 | # in KeepGoing mode, remembers errors and hides them from callers | |
238 | run_ () | |
239 | { | |
c18dbaf9 | 240 | "$@" && return 0 # return on success |
1d2ed53d AJ |
241 | error=$? |
242 | ||
243 | if test $KeepGoing = no; then | |
244 | return $error | |
245 | fi | |
246 | ||
247 | echo "ERROR: Continuing after a failure ($error) due to $KeepGoingDirective" | |
248 | SeenErrors=$error # TODO: Remember the _first_ error instead | |
249 | return 0 # hide error from the caller | |
250 | } | |
251 | ||
252 | updateIfChanged () | |
253 | { | |
254 | original="$1" | |
255 | updated="$2" | |
256 | message="$3" | |
257 | ||
258 | if ! cmp -s "${original}" "${updated}"; then | |
259 | echo "NOTICE: File ${original} changed: ${message}" | |
260 | run_ mv "${updated}" "${original}" || return | |
261 | else | |
262 | run_ rm -f "${updated}" || exit $? | |
263 | fi | |
264 | } | |
265 | ||
266 | # uses the given script to update the given source file | |
267 | applyPlugin () | |
268 | { | |
269 | script="$1" | |
270 | source="$2" | |
271 | ||
272 | new="$source.new" | |
273 | $script "$source" > "$new" && | |
274 | updateIfChanged "$source" "$new" "by $script" | |
275 | } | |
276 | ||
2a06115d FC |
277 | # updates the given source file using the given script(s) |
278 | applyPluginsTo () | |
279 | { | |
280 | source="$1" | |
281 | shift | |
282 | ||
283 | for script in `git ls-files "$@"`; do | |
284 | run_ applyPlugin $script $source || return | |
285 | done | |
286 | } | |
287 | ||
83b053a0 CT |
288 | # succeeds if all MakeNamedErrorDetail() names are unique |
289 | checkMakeNamedErrorDetails () | |
290 | { | |
291 | problems=1 # assume there are problems until proven otherwise | |
292 | ||
293 | options='-h --only-matching --extended-regexp' | |
e0f03049 | 294 | git grep $options 'MakeNamedErrorDetail[(]"[^"]*"[)]' src | |
83b053a0 CT |
295 | sort | |
296 | uniq --count > \ | |
297 | MakeNamedErrorDetail.tmp | |
298 | ||
299 | if grep --quiet --word-regexp 1 MakeNamedErrorDetail.tmp; then | |
300 | if grep --invert-match --word-regexp 1 MakeNamedErrorDetail.tmp; then | |
301 | echo "ERROR: Duplicated MakeNamedErrorDetail names (see above)." | |
302 | else | |
303 | problems=0 | |
304 | fi | |
305 | else | |
306 | echo "ERROR: Cannot find or process MakeNamedErrorDetail calls." | |
307 | fi | |
308 | ||
309 | rm MakeNamedErrorDetail.tmp # ignore (unexpected) cleanup failures | |
310 | return $problems | |
311 | } | |
312 | ||
c59baaa8 EB |
313 | # extract IDs and gists of cache_log_message debugs() in the given source file |
314 | collectDebugMessagesFrom () | |
315 | { | |
316 | source="$1" | |
317 | destination="doc/debug-messages.tmp" | |
318 | ||
c18dbaf9 | 319 | if test "x$OnlyChangedSince" != "x"; then |
320 | # Skipping collection due to --only-changed-since. | |
321 | # processDebugMessages() will warn. | |
322 | return 0 | |
323 | fi | |
324 | ||
c59baaa8 EB |
325 | # Merge multi-line debugs() into one-liners and remove '//...' comments. |
326 | awk 'BEGIN { found=0; dbgLine=""; } { | |
327 | if ($0 ~ /[ \t]debugs[ \t]*\(/) | |
328 | found = 1; | |
329 | if (found) { | |
330 | commented = match($0, /\);[ \t]*\/\//); | |
331 | if (commented) | |
332 | $0 = substr($0, 1, RSTART+1); | |
333 | dbgLine = dbgLine $0; | |
334 | } | |
335 | if ($0 ~ /\);/) { | |
336 | if (found) { | |
337 | found = 0; | |
338 | print dbgLine; | |
339 | dbgLine = ""; | |
340 | } | |
341 | } | |
342 | }' $source > doc/debug-messages.tmp2 | |
343 | ||
344 | # sed expressions: | |
345 | # - replace debugs() prefix with the message ID contained in it | |
346 | # - remove simple parenthesized non-"string" items like (a ? b : c) | |
347 | # - replace any remaining non-"string" items with ... | |
348 | # - remove quotes around "strings" | |
349 | # - remove excessive whitespace | |
350 | # - remove debugs() statement termination sugar | |
a80e3b44 | 351 | grep -o -E '\bdebugs[^,]*,[^,]*(Critical|Important)[(][0-9]+.*' doc/debug-messages.tmp2 | \ |
c59baaa8 | 352 | sed -r \ |
a80e3b44 | 353 | -e 's/.*(Critical|Important)[(]([0-9]+)[)][^,]*,\s*/\2 /' \ |
c59baaa8 EB |
354 | -e 's/<<\s*[(].*[)]\s*(<<|[)];)/<< ... \1/g' \ |
355 | -e 's/<<\s*[^"]*/.../g' \ | |
356 | -e 's@([^\\])"@\1@g' \ | |
357 | -e 's/\s\s*/ /g' \ | |
358 | -e 's/[)];$//g' \ | |
359 | >> $destination | |
360 | ||
361 | rm -f doc/debug-messages.tmp2 | |
362 | } | |
363 | ||
364 | # make doc/debug-messages.dox from aggregate collectDebugMessagesFrom results | |
365 | processDebugMessages () | |
366 | { | |
367 | source="doc/debug-messages.tmp" | |
368 | destination="doc/debug-messages.dox" | |
369 | ||
c18dbaf9 | 370 | if test "x$OnlyChangedSince" != "x"; then |
371 | echo "WARNING: Skipping update of $destination due to --only-changed-since" | |
372 | return 0 | |
373 | fi | |
374 | ||
c59baaa8 EB |
375 | if test '!' -s "$source"; then |
376 | echo "ERROR: Failed to find debugs() message IDs" | |
c18dbaf9 | 377 | return 1 |
c59baaa8 EB |
378 | fi |
379 | ||
380 | repeatedIds=`awk '{print $1}' $source | sort -n | uniq -d` | |
381 | if test "x$repeatedIds" != "x"; then | |
382 | echo "ERROR: Repeated debugs() message IDs:" | |
383 | echo "$repeatedIds" | |
384 | echo "" | |
c18dbaf9 | 385 | return 1 |
c59baaa8 EB |
386 | fi |
387 | ||
388 | repeatedGists=`awk '{$1=""; print substr($0,2)}' $source | sort | uniq -d` | |
389 | if test "x$repeatedGists" != "x"; then | |
390 | echo "ERROR: Repeated debugs() message gists:" | |
391 | echo "$repeatedGists" | |
392 | echo "" | |
c18dbaf9 | 393 | return 1 |
c59baaa8 EB |
394 | fi |
395 | ||
396 | cat scripts/boilerplate.h > $destination | |
397 | printf '/**\n' >> $destination | |
398 | printf '\\page ControlledCacheLogMessages Message IDs and gists for cache_log_message\n' >> $destination | |
399 | printf '\\verbatim\n' >> $destination | |
400 | printf 'ID Message gist\n' >> $destination | |
401 | printf '== ============\n' >> $destination | |
402 | sort -n < $source >> $destination | |
403 | printf '\\endverbatim\n' >> $destination | |
404 | printf '*/\n' >> $destination | |
405 | ||
406 | rm -f $source | |
407 | } | |
408 | ||
409 | # make doc/debug-sections.txt from aggregated by srcFormat extracts | |
410 | processDebugSections () | |
411 | { | |
412 | destination="doc/debug-sections.txt" | |
413 | ||
c18dbaf9 | 414 | if test "x$OnlyChangedSince" != "x"; then |
415 | echo "WARNING: Skipping update of $destination due to --only-changed-since" | |
416 | return 0 | |
417 | fi | |
418 | ||
efdbb07d | 419 | LC_ALL=C sort -u < doc/debug-sections.tmp > doc/debug-sections.tmp2 |
c18dbaf9 | 420 | |
c59baaa8 EB |
421 | cat scripts/boilerplate.h > $destination |
422 | echo "" >> $destination | |
423 | cat doc/debug-sections.tmp2 >> $destination | |
424 | ||
425 | rm -f doc/debug-sections.tmp* | |
426 | } | |
427 | ||
1d2ed53d | 428 | srcFormat () |
e555fec8 | 429 | { |
c59baaa8 EB |
430 | # remove stale temporary files that accumulate info extracted below |
431 | rm -f doc/debug-messages.tmp* | |
432 | rm -f doc/debug-sections.tmp* | |
433 | ||
605f2c3e AJ |
434 | # |
435 | # Scan for incorrect use of #ifdef/#ifndef | |
436 | # | |
114c8217 | 437 | git grep "ifn?def .*_SQUID_" | |
1a8e2e1c | 438 | grep -v -E "_H$" | |
114c8217 AJ |
439 | grep -v "scripts/source-maintenance.sh" | |
440 | while read f; do echo "PROBLEM?: ${f}"; done | |
605f2c3e AJ |
441 | |
442 | # | |
443 | # Scan for file-specific actions | |
444 | # | |
c18dbaf9 | 445 | |
446 | # The two git commands below will also list any files modified during the | |
447 | # current run (e.g., src/http/RegisteredHeadersHash.cci or icons/icon.am). | |
448 | FilesToOperateOn="" | |
449 | if test "x$OnlyChangedSince" != "x" ; then | |
450 | FilesToOperateOn=`git diff --name-only $OnlyChangedSince` | |
451 | gitResult=$? | |
452 | if test $gitResult -ne 0 ; then | |
453 | echo "ERROR: Cannot use --only-changed-since reference point: $OnlyChangedSince" | |
454 | echo "Consider using a git commit SHA (from git log) instead" | |
455 | return $gitResult | |
456 | fi | |
457 | else | |
458 | FilesToOperateOn=`git ls-files` | |
459 | gitResult=$? | |
460 | # a bit paranoid but protects the empty $FilesToOperateOn check below | |
461 | if test $gitResult -ne 0 ; then | |
462 | echo "ERROR: Cannot find source code file names" | |
463 | return $gitResult | |
464 | fi | |
465 | fi | |
466 | if test "x$FilesToOperateOn" = "x"; then | |
467 | echo "WARNING: No files to scan and format" | |
468 | return 0 | |
469 | fi | |
470 | ||
471 | for FILENAME in $FilesToOperateOn; do | |
e9549c27 | 472 | skip_copyright_check="" |
6f98e675 | 473 | |
114c8217 AJ |
474 | # skip subdirectories, git ls-files is recursive |
475 | test -d $FILENAME && continue | |
476 | ||
761dced3 AR |
477 | # generated files are formatted during their generation |
478 | if grep -q -F "$GeneratedByMe" ${FILENAME}; then | |
479 | continue | |
480 | fi | |
481 | ||
d743fb5d AJ |
482 | case ${FILENAME} in |
483 | ||
484 | *.h|*.c|*.cc|*.cci) | |
485 | ||
d090e020 AJ |
486 | # |
487 | # Code Style formatting maintenance | |
488 | # | |
2a06115d | 489 | applyPluginsTo ${FILENAME} scripts/maintenance/ || return |
761dced3 AR |
490 | if test "$CppFormatter"; then |
491 | if $CppFormatter $FILENAME > $FILENAME.new; then | |
492 | updateIfChanged $FILENAME $FILENAME.new 'by astyle' | |
493 | else | |
494 | rm $FILENAME.new | |
495 | fi | |
f77fbf5b | 496 | fi |
d090e020 | 497 | |
536e999d | 498 | # |
582c2af2 | 499 | # REQUIRE squid.h first #include |
536e999d AJ |
500 | # |
501 | case ${FILENAME} in | |
114c8217 AJ |
502 | src/cf_gen.cc) |
503 | # ignore, this is a build tool. | |
504 | ;; | |
536e999d AJ |
505 | *.c|*.cc) |
506 | FI=`grep "#include" ${FILENAME} | head -1`; | |
582c2af2 | 507 | if test "${FI}" != "#include \"squid.h\"" -a "${FILENAME}" != "cf_gen.cc"; then |
114c8217 | 508 | echo "ERROR: ${FILENAME} does not include squid.h first!" |
536e999d AJ |
509 | fi |
510 | ;; | |
511 | *.h|*.cci) | |
f7f3304a | 512 | FI=`grep "#include \"squid.h\"" ${FILENAME}`; |
582c2af2 | 513 | if test "x${FI}" != "x" ; then |
114c8217 | 514 | echo "ERROR: ${FILENAME} duplicate include of squid.h" |
536e999d AJ |
515 | fi |
516 | ;; | |
517 | esac | |
518 | ||
24b30fdc EQ |
519 | # |
520 | # If a file includes openssl headers, then it must include compat/openssl.h | |
521 | # | |
14bf2426 AJ |
522 | if test "${FILENAME}" != "compat/openssl.h"; then |
523 | FA=`grep "#include.*openssl/" "${FILENAME}" 2>/dev/null | head -1`; | |
524 | FB=`grep '#include.*compat/openssl[.]h' "${FILENAME}" 2>/dev/null | head -1`; | |
525 | if test "x${FA}" != "x" -a "x${FB}" = "x"; then | |
526 | echo "ERROR: ${FILENAME} includes openssl headers without including \"compat/openssl.h\"" | |
527 | fi | |
24b30fdc EQ |
528 | fi |
529 | ||
eb13c21e AJ |
530 | # |
531 | # forward.h means different things to Squid code depending on the path | |
532 | # require the full path is explicit for every include | |
533 | # | |
534 | FI=`grep "#include \"forward.h\"" ${FILENAME}`; | |
535 | if test "x${FI}" != "x" ; then | |
114c8217 | 536 | echo "ERROR: ${FILENAME} contains reference to forward.h without path" |
eb13c21e AJ |
537 | fi |
538 | ||
b8889258 AJ |
539 | # |
540 | # detect functions unsafe for use within Squid. | |
86c63190 AJ |
541 | # strdup() - only allowed in compat/xstring.h which defines a safe replacement. |
542 | # sprintf() - not allowed anywhere. | |
b8889258 | 543 | # |
86c63190 | 544 | STRDUP=`grep -e "[^x]strdup(" ${FILENAME}`; |
14bf2426 | 545 | if test "x${STRDUP}" != "x" -a "${FILENAME}" != "compat/xstring.h"; then |
114c8217 | 546 | echo "ERROR: ${FILENAME} contains unprotected use of strdup()" |
b8889258 | 547 | fi |
86c63190 | 548 | SPRINTF=`grep -e "[^v]sprintf(" ${FILENAME}`; |
b8889258 | 549 | if test "x${SPRINTF}" != "x" ; then |
114c8217 | 550 | echo "ERROR: ${FILENAME} contains unsafe use of sprintf()" |
b8889258 AJ |
551 | fi |
552 | ||
c59baaa8 EB |
553 | collectDebugMessagesFrom ${FILENAME} |
554 | ||
d090e020 AJ |
555 | # |
556 | # DEBUG Section list maintenance | |
557 | # | |
efdbb07d | 558 | grep " DEBUG: section" <${FILENAME} | sed -e 's/ \* DEBUG: //' -e 's%/\* DEBUG: %%' -e 's% \*/%%' >> doc/debug-sections.tmp |
d090e020 AJ |
559 | |
560 | # | |
561 | # File permissions maintenance. | |
562 | # | |
563 | chmod 644 ${FILENAME} | |
564 | ;; | |
565 | ||
566 | *.pl|*.sh) | |
567 | # | |
568 | # File permissions maintenance. | |
569 | # | |
570 | chmod 755 ${FILENAME} | |
8cd09bae HN |
571 | ;; |
572 | ||
2a06115d | 573 | *.am) |
761dced3 | 574 | applyPluginsTo ${FILENAME} scripts/format-makefile-am.pl || return |
52d824b5 | 575 | ;; |
8cd09bae | 576 | |
2b5ebbe3 | 577 | ChangeLog|CREDITS|CONTRIBUTORS|COPYING|*.png|*.po|*.pot|rfcs/|*.txt|test-suite/squidconf/empty|.bzrignore) |
e9549c27 AJ |
578 | # we do not enforce copyright blurbs in: |
579 | # | |
e758499d AJ |
580 | # Squid Project contributor attribution file |
581 | # third-party copyright attribution file | |
e9549c27 AJ |
582 | # images, |
583 | # translation PO/POT | |
e758499d | 584 | # license documentation files |
e9549c27 | 585 | # (imported) plain-text documentation files and ChangeLogs |
e758499d | 586 | # VCS internal files |
e9549c27 AJ |
587 | # |
588 | skip_copyright_check=1 | |
589 | ;; | |
d743fb5d | 590 | esac |
6f98e675 | 591 | |
5fbc3e1d | 592 | # check for Foundation copyright blurb |
e73ef62a | 593 | if test $CheckAndUpdateCopyright = yes -a -f ${FILENAME} -a "x$skip_copyright_check" = "x"; then |
e819858c | 594 | BLURB=`grep -o "${COPYRIGHT_YEARS} The Squid Software Foundation and contributors" ${FILENAME}`; |
5fbc3e1d | 595 | if test "x${BLURB}" = "x"; then |
e819858c SM |
596 | BOILER=`grep -o -E "1996-2[0-9]+ The Squid Software Foundation and contributors" ${FILENAME}`; |
597 | if test "x${BOILER}" != "x"; then | |
114c8217 AJ |
598 | echo "UPDATE COPYRIGHT for ${FILENAME}" |
599 | sed --in-place -r -f boilerplate_fix.sed ${FILENAME} | |
e819858c | 600 | else |
114c8217 | 601 | echo "CHECK COPYRIGHT for ${FILENAME}" |
e819858c | 602 | fi |
5fbc3e1d AJ |
603 | fi |
604 | fi | |
605 | ||
6f98e675 | 606 | done |
c59baaa8 EB |
607 | |
608 | run_ processDebugSections || return | |
609 | run_ processDebugMessages || return | |
e555fec8 AJ |
610 | } |
611 | ||
52d824b5 | 612 | printRawAmFile () |
2b5ebbe3 AJ |
613 | { |
614 | sed -e 's%\ \*%##%; s%/\*%##%; s%##/%##%' < scripts/boilerplate.h | |
52d824b5 AR |
615 | |
616 | echo "## $GeneratedByMe" | |
617 | echo | |
618 | ||
97323125 | 619 | printf "%s =" "$1" |
52d824b5 AR |
620 | # Only some files are formed from *.po filenames, but all such files |
621 | # should list *.lang filenames instead. | |
622 | git ls-files $2$3 | sed -e s%$2%%g -e 's%\.po%\.lang%g' | while read f; do | |
97323125 | 623 | printf ' \\\n\t%s' "${f}" |
2b5ebbe3 | 624 | done |
97323125 | 625 | printf '\n' |
2b5ebbe3 AJ |
626 | } |
627 | ||
52d824b5 AR |
628 | generateAmFile () |
629 | { | |
630 | amFile="$1" | |
631 | shift | |
632 | ||
633 | # format immediately/here instead of in srcFormat to avoid misleading | |
634 | # "NOTICE: File ... changed by scripts/format-makefile-am.pl" in srcFormat | |
635 | printRawAmFile "$@" | scripts/format-makefile-am.pl > $amFile.new | |
636 | ||
637 | # Distinguishing generation-only changes from formatting-only changes is | |
638 | # difficult, so we only check/report cumulative changes. Most interesting | |
639 | # changes are triggered by printRawAmFile() finding new entries. | |
640 | updateIfChanged $amFile $amFile.new 'by generateAmFile()' | |
641 | } | |
642 | ||
46002cc1 | 643 | # Build icons install include from current icons available |
52d824b5 | 644 | generateAmFile icons/icon.am ICONS "icons/" "silk/*" |
d78c092d | 645 | |
46002cc1 | 646 | # Build templates install include from current templates available |
52d824b5 | 647 | generateAmFile errors/template.am ERROR_TEMPLATES "errors/" "templates/ERR_*" |
46002cc1 AJ |
648 | |
649 | # Build errors translation install include from current .PO available | |
d146da3b | 650 | generateAmFile errors/language.am LANGUAGE_FILES "errors/" "*.po" |
46002cc1 AJ |
651 | |
652 | # Build manuals translation install include from current .PO available | |
d146da3b | 653 | generateAmFile doc/manuals/language.am LANGUAGE_FILES "doc/manuals/" "*.po" |
46002cc1 | 654 | |
ee4478ed | 655 | # Build STUB framework include from current stub_* available |
52d824b5 | 656 | generateAmFile src/tests/Stub.am STUB_SOURCE "src/" "tests/stub_*.cc" |
ee4478ed | 657 | |
761dced3 AR |
658 | generateRawGperfFile () |
659 | { | |
660 | gperfFile="$1" | |
661 | ||
662 | echo "/* $GeneratedByMe */" | |
663 | echo | |
664 | ||
cacc683d AJ |
665 | if test `gperf --version | head -1 | cut -d ' ' -f 3 | cut -d. -f '-2' | sed -e 's/\.//'` -lt 32 ; then |
666 | # We configure C++ compilers to complain about missing '[[fallthrough]]' attribute | |
667 | # where old gperf versions use a '/*FALLTHROUGH*/' code comment. | |
668 | (cd `dirname $gperfFile` && gperf -m 100000 `basename $gperfFile`) | \ | |
669 | sed -e 's@/[*]FALLTHROUGH[*]/@[[fallthrough]];@g' | |
670 | else | |
671 | # gperf 3.2+ provide fallthrough attributes | |
672 | (cd `dirname $gperfFile` && gperf -m 100000 `basename $gperfFile`) | |
673 | fi | |
761dced3 AR |
674 | } |
675 | ||
676 | generateGperfFile () | |
677 | { | |
678 | gperfFile="$1" | |
679 | cciFile=`echo $gperfFile | sed 's/[.]gperf$/.cci/'` | |
680 | ||
681 | if test $gperfFile -ot $cciFile; then | |
c18dbaf9 | 682 | return 0 |
761dced3 AR |
683 | fi |
684 | ||
685 | generateRawGperfFile $gperfFile > $cciFile.unformatted || return | |
686 | ||
687 | if test "$CppFormatter"; then | |
688 | # generateAmFile() explains why we format immediately/here | |
689 | $CppFormatter $cciFile.unformatted > $cciFile.new || return | |
690 | rm $cciFile.unformatted | |
691 | else | |
692 | echo "ERROR: Source code formatting disabled, but regenerated $cciFile needs formatting" | |
693 | mv $cciFile.unformatted $cciFile.new || return | |
694 | fi | |
695 | ||
696 | # generateAmFile() explains why we only check/report cumulative changes | |
697 | updateIfChanged $cciFile $cciFile.new 'by generateGperfFile()' | |
698 | } | |
699 | ||
700 | run_ generateGperfFile src/http/RegisteredHeadersHash.gperf || exit 1 | |
3d50beac | 701 | |
83b053a0 CT |
702 | run_ checkMakeNamedErrorDetails || exit 1 |
703 | ||
6e541c01 AJ |
704 | # This function updates CONTRIBUTORS based on the recent[1] branch commit log. |
705 | # Fresh contributor entries are filtered using the latest vetted CONTRIBOTORS | |
706 | # file on the current branch. The following CONTRIBUTORS commits are | |
707 | # considered vetted: | |
708 | # | |
709 | # * authored (in "git log --author" sense) by squidadm, | |
710 | # * matching (in "git log --grep" sense) $vettedCommitPhraseRegex set below. | |
711 | # | |
712 | # A human authoring an official GitHub pull request containing a new | |
713 | # CONTRIBUTORS version (that they want to be used as a new vetting point) | |
714 | # should add a phrase matching $vettedCommitPhraseRegex to the PR description. | |
715 | # | |
716 | # [1] As defined by the --update-contributors-since script parameter. | |
717 | collectAuthors () | |
718 | { | |
719 | if test "x$UpdateContributorsSince" = xnever | |
720 | then | |
c18dbaf9 | 721 | return 0 # successfully did nothing, as requested |
6e541c01 AJ |
722 | fi |
723 | ||
724 | vettedCommitPhraseRegex='[Rr]eference point for automated CONTRIBUTORS updates' | |
725 | ||
726 | since="$UpdateContributorsSince" | |
727 | if test "x$UpdateContributorsSince" = xauto | |
728 | then | |
729 | # find the last CONTRIBUTORS commit vetted by a human | |
730 | humanSha=`git log -n1 --format='%H' --grep="$vettedCommitPhraseRegex" CONTRIBUTORS` | |
731 | # find the last CONTRIBUTORS commit attributed to this script | |
732 | botSha=`git log -n1 --format='%H' --author=squidadm CONTRIBUTORS` | |
733 | if test "x$humanSha" = x && test "x$botSha" = x | |
734 | then | |
735 | echo "ERROR: Unable to determine the commit to start contributors extraction from" | |
c18dbaf9 | 736 | return 1 |
6e541c01 AJ |
737 | fi |
738 | ||
739 | # find the latest commit among the above one or two commits | |
740 | if test "x$humanSha" = x | |
741 | then | |
742 | since=$botSha | |
743 | elif test "x$botSha" = x | |
744 | then | |
745 | since=$humanSha | |
746 | elif git merge-base --is-ancestor $humanSha $botSha | |
747 | then | |
748 | since=$botSha | |
749 | else | |
750 | since=$humanSha | |
751 | fi | |
752 | echo "Collecting contributors since $since" | |
753 | fi | |
754 | range="$since..HEAD" | |
755 | ||
756 | # We add four leading spaces below to mimic CONTRIBUTORS entry style. | |
757 | # add commit authors: | |
758 | git log --format=' %an <%ae>' $range > authors.tmp | |
759 | # add commit co-authors: | |
760 | git log $range | \ | |
761 | grep -Ei '^[[:space:]]*Co-authored-by:' | \ | |
762 | sed -r 's/^\s*Co-authored-by:\s*/ /i' >> authors.tmp | |
763 | # but do not add committers (--format=' %cn <%ce>'). | |
764 | ||
765 | # add collected new (co-)authors, if any, to CONTRIBUTORS | |
ea262b27 | 766 | if ./scripts/update-contributors.pl --quiet < authors.tmp > CONTRIBUTORS.new |
6e541c01 AJ |
767 | then |
768 | updateIfChanged CONTRIBUTORS CONTRIBUTORS.new \ | |
769 | "A human PR description should match: $vettedCommitPhraseRegex" | |
770 | fi | |
771 | result=$? | |
772 | ||
773 | rm -f authors.tmp | |
774 | return $result | |
775 | } | |
776 | ||
777 | # Update CONTRIBUTORS content | |
778 | run_ collectAuthors || exit 1 | |
779 | ||
2f8abb64 | 780 | # Run formatting |
1d2ed53d | 781 | srcFormat || exit 1 |
c59baaa8 | 782 | |
c18dbaf9 | 783 | test -e boilerplate_fix.sed && rm -f boilerplate_fix.sed |
1d2ed53d AJ |
784 | |
785 | exit $SeenErrors |