]> git.ipfire.org Git - thirdparty/squid.git/blame - scripts/source-maintenance.sh
Simplify appending SBuf to String (#2108)
[thirdparty/squid.git] / scripts / source-maintenance.sh
CommitLineData
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_().
17KeepGoing="no"
18# the actual name of the directive that enabled keep-going mode
19KeepGoingDirective=""
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 28TargetAstyleVersion="3.1"
12e6d55e 29ASTYLE='astyle'
1d2ed53d 30
e73ef62a
AR
31# whether to check and, if necessary, update boilerplate copyright years
32CheckAndUpdateCopyright=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.
38UpdateContributorsSince=auto
39
c18dbaf9 40# --only-changed-since point
41OnlyChangedSince=""
42
e73ef62a 43printUsage () {
c18dbaf9 44cat <<USAGE_
45Usage: $0 [option...]
46options:
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
54USAGE_
55}
56
57printHelp () {
58
59cat <<HELP_INTRO_
60This script applies Squid mandatory code style guidelines and generates
61various files derived from Squid sources.
62HELP_INTRO_
63
64printUsage
65
66cat <<HELP_MAIN_
67--help, -h
68
69Print this information and exit.
70
71--only-changed-since <"fork"|commit>
72
73When specifieid, the script only examines for formatting changes those
74files that have changed since the specified git reference point. The
75argument 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
77branch the current one was forked off. When "fork" is specified, the
78script will look for files changed since the current branch was forked off
79upstream/master (according to "git merge-base --fork-point").
80
81This option does not disable some repository-wide file generation and
82repository-wide non-formatting checks/adjustments.
83
84--update-contributors-since <never|auto|revision>
85
86Configures 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
93Squid code style guidelines require astyle version $TargetAstyleVersion.
94The path to the astyle binary can be specified using this command line
95option or by exporting the ASTYLE environment variable. If both are
96specified, the command-line option wins.
97
98External dependencies:
99
100* Astyle. See the --with-astyle command line option above.
101* gperf (if you modify certain source files)
102
103HELP_MAIN_
e73ef62a
AR
104}
105
1d2ed53d
AJ
106# command-line options
107while [ $# -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
152done
153
154# an error code seen by a KeepGoing-aware command (or zero)
155SeenErrors=0
156
1d2ed53d
AJ
157if ! 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
161fi
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:
166FoundProgram=""
167findProgram ()
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
189made="generated" # a hack: prevents $GeneratedByMe searches matching this file
190GeneratedByMe="This file is $made by scripts/source-maintenance.sh."
191
c18dbaf9 192if [ "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
197else
198 findProgram astyle --version astyle-${TargetAstyleVersion} astyle || exit $?
199 ASTYLE=$FoundProgram
12e6d55e 200fi
c18dbaf9 201
202ASVER=`"${ASTYLE}" --version 2>&1 | grep -o -E "[0-9.]+"`
12e6d55e
FC
203if 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 212else
c18dbaf9 213 echo "Detected expected astyle version: ${ASVER}"
f77fbf5b 214fi
761dced3
AR
215CppFormatter=''
216if test "${ASVER}"; then
217 CppFormatter="./scripts/format-cpp.pl --with-astyle ${ASTYLE}"
218fi
f77fbf5b 219
c18dbaf9 220if 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"
228fi
229
e73ef62a
AR
230if test $CheckAndUpdateCopyright = yes
231then
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
234fi
e819858c 235
1d2ed53d
AJ
236# executes the specified command
237# in KeepGoing mode, remembers errors and hides them from callers
238run_ ()
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
252updateIfChanged ()
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
267applyPlugin ()
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)
278applyPluginsTo ()
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
289checkMakeNamedErrorDetails ()
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
314collectDebugMessagesFrom ()
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
365processDebugMessages ()
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
410processDebugSections ()
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 428srcFormat ()
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 437git 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
471for 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 606done
c59baaa8
EB
607
608 run_ processDebugSections || return
609 run_ processDebugMessages || return
e555fec8
AJ
610}
611
52d824b5 612printRawAmFile ()
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
628generateAmFile ()
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 644generateAmFile icons/icon.am ICONS "icons/" "silk/*"
d78c092d 645
46002cc1 646# Build templates install include from current templates available
52d824b5 647generateAmFile errors/template.am ERROR_TEMPLATES "errors/" "templates/ERR_*"
46002cc1
AJ
648
649# Build errors translation install include from current .PO available
d146da3b 650generateAmFile errors/language.am LANGUAGE_FILES "errors/" "*.po"
46002cc1
AJ
651
652# Build manuals translation install include from current .PO available
d146da3b 653generateAmFile doc/manuals/language.am LANGUAGE_FILES "doc/manuals/" "*.po"
46002cc1 654
ee4478ed 655# Build STUB framework include from current stub_* available
52d824b5 656generateAmFile src/tests/Stub.am STUB_SOURCE "src/" "tests/stub_*.cc"
ee4478ed 657
761dced3
AR
658generateRawGperfFile ()
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
676generateGperfFile ()
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
700run_ generateGperfFile src/http/RegisteredHeadersHash.gperf || exit 1
3d50beac 701
83b053a0
CT
702run_ 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.
717collectAuthors ()
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
778run_ collectAuthors || exit 1
779
2f8abb64 780# Run formatting
1d2ed53d 781srcFormat || exit 1
c59baaa8 782
c18dbaf9 783test -e boilerplate_fix.sed && rm -f boilerplate_fix.sed
1d2ed53d
AJ
784
785exit $SeenErrors