File indexing completed on 2024-05-12 04:44:28
0001 #!/bin/bash 0002 0003 # SPDX-FileCopyrightText: Lukas Sommer <sommerluk@gmail.com> 0004 # SPDX-License-Identifier: BSD-2-Clause OR MIT 0005 0006 0007 0008 0009 0010 ################# Configure ################# 0011 # The “.” command will execute the given script within the context of 0012 # the current script, which is necessary in order to preserve the 0013 # environment variables that are set by the given script. 0014 . scripts/export-environment.sh 0015 0016 0017 0018 0019 0020 ################# Static code check ################# 0021 # NOTE Keep the following list synchronized 0022 # between scripts/static-codecheck.sh and src/CMakeLists.txt 0023 PUBLIC_HEADERS=" 0024 src/abstractdiagram.h 0025 src/chromahuediagram.h 0026 src/colordialog.h 0027 src/colorpatch.h 0028 src/colorwheel.h 0029 src/constpropagatinguniquepointer.h 0030 src/gradientslider.h 0031 src/importexport.h 0032 src/lchadouble.h 0033 src/lchdouble.h 0034 src/multispinbox.h 0035 src/multispinboxsection.h 0036 src/rgbcolorspacefactory.h 0037 src/settranslation.h 0038 src/wheelcolorpicker.h 0039 src/version.in.hpp 0040 " 0041 CODE_WITHOUT_UNIT_TESTS="src/* tests utils examples" 0042 UNIT_TESTS="autotests/*" 0043 ALL_CODE="$CODE_WITHOUT_UNIT_TESTS $UNIT_TESTS" 0044 0045 EXCLUDE_PUBLIC_HEADER_FROM_GREP="--exclude=$(echo $PUBLIC_HEADERS | sed 's/ / --exclude=/g')" 0046 0047 # TODO Test for qDebug() which should not be used never in production 0048 # code. Exception: Unit tests. 0049 0050 # Search for files that do not start with a byte-order-mark (BOM). 0051 # We do this because Microsoft’s compiler does require a BOM at the start 0052 # of the file in order to interpret it as UTF-8. 0053 grep \ 0054 --recursive --exclude-dir=testbed \ 0055 --files-without-match $'\xEF\xBB\xBF' \ 0056 $ALL_CODE \ 0057 | grep \ 0058 --perl-regexp "\.(license|txt|icc|qrc|qph|ts|cmake\.in|sh)$" \ 0059 --invert-match \ 0060 | sed 's/^/Missing byte-order-mark: /' 0061 0062 # All header files in src/ should have an “@internal” in 0063 # the Doxygen documentation, because when it would be public, 0064 # the header file would not be in src/ 0065 grep \ 0066 --recursive --exclude-dir=testbed \ 0067 $EXCLUDE_PUBLIC_HEADER_FROM_GREP \ 0068 --files-without-match $'@internal' \ 0069 src/*.h \ 0070 | sed 's/^/Missing “@internal” statement in non-public header: /' 0071 0072 # The public header files should not use “final” because it cannot be removed 0073 # without breaking binary compatibility. 0074 grep \ 0075 --recursive --exclude-dir=testbed \ 0076 --files-with-matches $'final' \ 0077 $PUBLIC_HEADERS \ 0078 | sed 's/^/“final” should not show up in public headers: /' 0079 0080 # All public header files should use 0081 # the PERCEPTUALCOLOR_IMPORTEXPORT macro. 0082 grep \ 0083 --recursive --exclude-dir=testbed \ 0084 --files-without-match $'PERCEPTUALCOLOR_IMPORTEXPORT' \ 0085 $PUBLIC_HEADERS \ 0086 | sed 's/^/Missing PERCEPTUALCOLOR_IMPORTEXPORT macro in public header: /' 0087 0088 # All non-public code should not use the PERCEPTUALCOLOR_IMPORTEXPORT macro. 0089 grep \ 0090 --recursive --exclude-dir={testbed,include} \ 0091 $EXCLUDE_PUBLIC_HEADER_FROM_GREP \ 0092 --files-with-matches $'PERCEPTUALCOLOR_IMPORTEXPORT' \ 0093 $CODE_WITHOUT_UNIT_TESTS \ 0094 | sed 's/^/Internal files may not use PERCEPTUALCOLOR_IMPORTEXPORT macro: /' 0095 0096 # Do not use constexpr in public headers as when we change the value 0097 # later, compile time value and run time value might be different, and 0098 # that might be dangerous. 0099 grep \ 0100 --recursive --exclude-dir=testbed \ 0101 --fixed-strings "constexpr" \ 0102 $PUBLIC_HEADERS \ 0103 | sed 's/^/Public headers may not use constexpr: /' 0104 0105 # Search for some patterns that should not be used in the source code. If 0106 # these patterns are found, a message is displayed. Otherwise, nothing is 0107 # displayed. 0108 0109 # We do not include LittleCMS headers like lcms2.h in the public API of our 0110 # library. But it is only be an internal dependency; library users should 0111 # not need to care about that. Therefore, we grab all lines that contain 0112 # identifiers starting with “cms” (except when in lines starting with 0113 # “using”). This search is not done for all code directories, but only 0114 # for files within the include directory (public API). 0115 grep \ 0116 --recursive --exclude-dir=testbed \ 0117 --perl-regexp "^cms" \ 0118 $PUBLIC_HEADERS \ 0119 | sed 's/^/Do not expose LittleCMS’ API in our public API: /' 0120 grep \ 0121 --recursive --exclude-dir=testbed \ 0122 --perl-regexp "[^a-zA-Z]cms[a-zA-Z0-9]" \ 0123 $PUBLIC_HEADERS \ 0124 | grep \ 0125 --perl-regexp "\<tt\>cms" \ 0126 --invert-match \ 0127 | sed 's/^/Do not expose LittleCMS’ API in our public API: /' 0128 grep \ 0129 --recursive --exclude-dir=testbed \ 0130 --fixed-strings "lcms2.h" \ 0131 $PUBLIC_HEADERS \ 0132 | sed 's/^/Do not expose LittleCMS’ API in our public API: /' 0133 0134 # -> Do not use the “code” and “endcode” tags for Doxygen documentation. Use 0135 # @snippet instead! That allows that the example code is actually compiled 0136 # and that helps detecting errors. 0137 grep \ 0138 --recursive --exclude-dir=testbed \ 0139 --perl-regexp "(@|\\\\)code(?!\{\.unparsed\})" \ 0140 $ALL_CODE \ 0141 | sed 's/^/Use snippets instead of “code” or “endcode”. (Exception: @code{.unparsed} is allowed.): /' 0142 0143 # -> Doxygen style: Do not use “@em xyz”. Prefer instead “<em>xyz</em>” which 0144 # might be longer, but has a clearer start point and end point, which is 0145 # better when non-letter characters are involved. The @ is reserved 0146 # for @ref with semantically tested references. 0147 # -> Same thing for “@c xyz”: Prefer instead “<tt>xyz</tt>”. 0148 grep \ 0149 --recursive --exclude-dir=testbed \ 0150 --fixed-strings "\\em" \ 0151 $ALL_CODE \ 0152 | sed 's/^/Use HTML tags instead of Doxygen commands for “em”: /' 0153 grep \ 0154 --recursive --exclude-dir=testbed \ 0155 --fixed-strings "@em" \ 0156 $ALL_CODE \ 0157 | sed 's/^/Use HTML tags instead of Doxygen commands for “em”: /' 0158 grep \ 0159 --recursive --exclude-dir=testbed \ 0160 --fixed-strings "\\c" \ 0161 $ALL_CODE \ 0162 | sed 's/^/Use HTML tags instead of Doxygen commands for “em”: /' 0163 grep \ 0164 --recursive --exclude-dir=testbed \ 0165 --perl-regexp "@c(?=([^a-zA-Z]|$))" \ 0166 $ALL_CODE \ 0167 | sed 's/^/Use HTML tags instead of Doxygen commands for “em”: /' 0168 0169 # -> Coding style: Do not use the “NULL” macro, but its counterpart “nullptr” 0170 # which is more type save. 0171 grep \ 0172 --recursive --exclude-dir=testbed \ 0173 --fixed-strings "NULL" \ 0174 $ALL_CODE \ 0175 | sed 's/^/Do not use the NULL macro: /' 0176 0177 # -> Coding style: Do not use inline functions. If used in a header, 0178 # once exposed, they cannot be changed without breaking binary 0179 # compatibility, because applications linking against the library 0180 # will always execute the inline function version against they where 0181 # compiled, and never the inline function of the library version 0182 # against they are linking at run-time. This make maintaining binary 0183 # compatibility much harder, for little benefit. 0184 # 0185 # However, “static inline” variables are good for the headers or 0186 # private PIMPL classes, because differently to “simple” “static” 0187 # variables they allow the definition within the very same header, 0188 # which is not only easier to read, but also protects against 0189 # a double definition in different compiler units. 0190 grep \ 0191 --recursive --exclude-dir=testbed \ 0192 --perl-regexp "(^|[^a-zA-Z0-9\-])inline(?![^()\/;]*=.*;)" \ 0193 $ALL_CODE \ 0194 | sed 's/^/Do not use inline functions respectively define inline variables at the same line.: /' 0195 0196 # -> In some Qt classes, devicePixelRatio() returns in integer. 0197 # Don’t do that and use floating point precision instead. Often, 0198 # devicePixelRatioF() is an alternative that provides 0199 # a qreal return value. 0200 grep \ 0201 --recursive --exclude-dir=testbed \ 0202 --perl-regexp "devicePixelRatio(?!F)" \ 0203 $CODE_WITHOUT_UNIT_TESTS \ 0204 | sed 's/^/Use devicePixelRatioF instead of devicePixelRatio: /' 0205 0206 # Qt’s documentation about QImage::Format says: For optimal performance only 0207 # use the format types QImage::Format_ARGB32_Premultiplied, 0208 # QImage::Format_RGB32 or QImage::Format_RGB16. Any other format, including 0209 # QImage::Format_ARGB32, has significantly worse performance. 0210 grep \ 0211 --recursive --exclude-dir=testbed \ 0212 --perl-regexp "QImage::Format_(?!(ARGB32_Premultiplied|RGB32|RGB16))" \ 0213 $ALL_CODE \ 0214 | sed 's/^/Use exclusively ARGB32_Premultiplied or RGB32 or RGB16 as QImage formats: /' 0215 0216 # -> QLatin1String and QLatin1Char dates from the pre-Unicode epoch. It should 0217 # not be used anymore at all, yet to avoid confusion. Though the Clazy 0218 # codecheck suggests to use QLatin1String() instead of an empty 0219 # QStringLiteral because of a slight performance gain, this might not 0220 # compensate for the less readable code. Alternatively, QString() might be 0221 # used to avoid Clazy warnings. 0222 grep \ 0223 --recursive --exclude-dir=testbed \ 0224 --fixed-strings "QLatin1" \ 0225 $ALL_CODE \ 0226 | sed 's/^/QLatin1String or QLatin1Char: If emtpy, use substitute by QString(), otherwise by QStringLiteral.: /' 0227 0228 # When using Doxygen snippets, don’t do this within a namespace. As they are 0229 # meant for documentation, they should always contain fully-qualified 0230 # names to make sure that they always work. 0231 # 0232 # As it is complicate to know if the snippet is actually within a namespace 0233 # (namespaces can be opened, but also be closed again), instead we do a 0234 # simplified check: We simply check if there are Doxygen snippets after the 0235 # very first usage of the “namespace” keyword. 0236 # 0237 # 1) Display all the files that are unit tests (adding “/*” to the UNIT_TESTS 0238 # variable to make sure to get a file list that “cat” will understand. 0239 # 2) For each file, get all lines starting from the first occurrence 0240 # of “namespace”, using sed. 0241 # 3) Now, filter only those who actually contain snippet definitions 0242 # starting with “//!”, using grep. 0243 for FILE in $UNIT_TESTS 0244 do 0245 cat $FILE 2>/dev/null \ 0246 | sed -n -e '/\([^a-zA-Z]namespace\)\|\(^namespace\)/,$p' \ 0247 | grep --fixed-strings "//!" \ 0248 | sed 's/^/When using snippets, don’t do this after having used the “namespace” keyword: /' 0249 done