libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

bash_test.sh (9312B)


      1 #!/bin/bash
      2 # Copyright (c) the JPEG XL Project Authors. All rights reserved.
      3 #
      4 # Use of this source code is governed by a BSD-style
      5 # license that can be found in the LICENSE file.
      6 
      7 # Tests implemented in bash. These typically will run checks about the source
      8 # code rather than the compiled one.
      9 
     10 MYDIR=$(dirname $(realpath "$0"))
     11 
     12 set -u
     13 
     14 test_includes() {
     15   local ret=0
     16   local f
     17   for f in $(git ls-files | grep -E '(\.cc|\.cpp|\.h)$'); do
     18     if [ ! -e "$f" ]; then
     19       continue
     20     fi
     21     # Check that the full paths to the public headers are not used, since users
     22     # of the library will include the library as: #include "jxl/foobar.h".
     23     if grep -i -H -n -E '#include\s*[<"]lib/include/jxl' "$f" >&2; then
     24       echo "Don't add \"include/\" to the include path of public headers." >&2
     25       ret=1
     26     fi
     27 
     28     if [[ "${f#third_party/}" == "$f" ]]; then
     29       # $f is not in third_party/
     30 
     31       # Check that local files don't use the full path to third_party/
     32       # directory since the installed versions will not have that path.
     33       # Add an exception for third_party/dirent.h.
     34       if grep -v -F 'third_party/dirent.h' "$f" | \
     35           grep -i -H -n -E '#include\s*[<"]third_party/' >&2 &&
     36           [[ $ret -eq 0 ]]; then
     37         cat >&2 <<EOF
     38 $f: Don't add third_party/ to the include path of third_party projects. This \
     39 makes it harder to use installed system libraries instead of the third_party/ \
     40 ones.
     41 EOF
     42         ret=1
     43       fi
     44     fi
     45 
     46   done
     47   return ${ret}
     48 }
     49 
     50 test_include_collision() {
     51   local ret=0
     52   local f
     53   for f in $(git ls-files | grep -E '^lib/include/'); do
     54     if [ ! -e "$f" ]; then
     55       continue
     56     fi
     57     local base=${f#lib/include/}
     58     if [[ -e "lib/${base}" ]]; then
     59       echo "$f: Name collision, both $f and lib/${base} exist." >&2
     60       ret=1
     61     fi
     62   done
     63   return ${ret}
     64 }
     65 
     66 test_copyright() {
     67   local ret=0
     68   local f
     69   for f in $(
     70       git ls-files | grep -E \
     71       '(Dockerfile.*|\.c|\.cc|\.cpp|\.gni|\.h|\.java|\.sh|\.m|\.py|\.ui|\.yml)$'); do
     72     if [ ! -e "$f" ]; then
     73       continue
     74     fi
     75     if [[ "${f#third_party/}" == "$f" ]]; then
     76       # $f is not in third_party/
     77       if ! head -n 10 "$f" |
     78           grep -F 'Copyright (c) the JPEG XL Project Authors.' >/dev/null ; then
     79         echo "$f: Missing Copyright blob near the top of the file." >&2
     80         ret=1
     81       fi
     82       if ! head -n 10 "$f" |
     83           grep -F 'Use of this source code is governed by a BSD-style' \
     84             >/dev/null ; then
     85         echo "$f: Missing License blob near the top of the file." >&2
     86         ret=1
     87       fi
     88     fi
     89   done
     90   return ${ret}
     91 }
     92 
     93 # Check that we don't use "%zu" or "%zd" in format string for size_t.
     94 test_printf_size_t() {
     95   local ret=0
     96   if grep -n -E '%[0-9]*z[udx]' \
     97       $(git ls-files | grep -E '(\.c|\.cc|\.cpp|\.h)$'); then
     98     echo "Don't use '%zu' or '%zd' in a format string, instead use " \
     99       "'%\" PRIuS \"' or '%\" PRIdS \"'." >&2
    100     ret=1
    101   fi
    102 
    103   if grep -n -E '[^_]gtest\.h' \
    104       $(git ls-files | grep -E '(\.c|\.cc|\.cpp|\.h)$' | grep -v -F /testing.h); then
    105     echo "Don't include gtest directly, instead include 'testing.h'. " >&2
    106     ret=1
    107   fi
    108 
    109   if grep -n -E 'gmock\.h' \
    110       $(git ls-files | grep -E '(\.c|\.cc|\.cpp|\.h)$' | grep -v -F /testing.h); then
    111     echo "Don't include gmock directly, instead include 'testing.h'. " >&2
    112     ret=1
    113   fi
    114 
    115   local f
    116   for f in $(git ls-files | grep -E "\.cc$" | xargs grep 'PRI[udx]S' |
    117       cut -f 1 -d : | uniq); do
    118     if [ ! -e "$f" ]; then
    119       continue
    120     fi
    121     if ! grep -F printf_macros.h "$f" >/dev/null; then
    122       echo "$f: Add lib/jxl/base/printf_macros.h for PRI.S, or use other " \
    123         "types for code outside lib/jxl library." >&2
    124       ret=1
    125     fi
    126   done
    127 
    128   for f in $(git ls-files | grep -E "\.h$" | grep -v -E '(printf_macros\.h|testing\.h)' |
    129       xargs grep -n 'PRI[udx]S'); do
    130     # Having PRIuS / PRIdS in a header file means that printf_macros.h may
    131     # be included before a system header, in particular before gtest headers.
    132     # those may re-define PRIuS unconditionally causing a compile error.
    133     echo "$f: Don't use PRI.S in header files. Sorry."
    134     ret=1
    135   done
    136 
    137   return ${ret}
    138 }
    139 
    140 # Check that "dec_" code doesn't depend on "enc_" headers.
    141 test_dec_enc_deps() {
    142   local ret=0
    143   local f
    144   for f in $(git ls-files | grep -E '/dec_'); do
    145     if [ ! -e "$f" ]; then
    146       continue
    147     fi
    148     if [[ "${f#third_party/}" == "$f" ]]; then
    149       # $f is not in third_party/
    150       if grep -n -H -E "#include.*/enc_" "$f" >&2; then
    151         echo "$f: Don't include \"enc_*\" files from \"dec_*\" files." >&2
    152         ret=1
    153       fi
    154     fi
    155   done
    156   return ${ret}
    157 }
    158 
    159 # Check for git merge conflict markers.
    160 test_merge_conflict() {
    161   local ret=0
    162   TEXT_FILES='(\.cc|\.cpp|\.h|\.sh|\.m|\.py|\.md|\.txt|\.cmake)$'
    163   for f in $(git ls-files | grep -E "${TEXT_FILES}"); do
    164     if [ ! -e "$f" ]; then
    165       continue
    166     fi
    167     if grep -E '^<<<<<<< ' "$f"; then
    168       echo "$f: Found git merge conflict marker. Please resolve." >&2
    169       ret=1
    170     fi
    171   done
    172   return ${ret}
    173 }
    174 
    175 # Check that the library and the package have the same version. This prevents
    176 # accidentally having them out of sync.
    177 get_version() {
    178   local varname=$1
    179   local line=$(grep -F "set(${varname} " lib/CMakeLists.txt | head -n 1)
    180   [[ -n "${line}" ]]
    181   line="${line#set(${varname} }"
    182   line="${line%)}"
    183   echo "${line}"
    184 }
    185 
    186 test_version() {
    187   local major=$(get_version JPEGXL_MAJOR_VERSION)
    188   local minor=$(get_version JPEGXL_MINOR_VERSION)
    189   local patch=$(get_version JPEGXL_PATCH_VERSION)
    190   # Check that the version is not empty
    191   if [[ -z "${major}${minor}${patch}" ]]; then
    192     echo "Couldn't parse version from CMakeLists.txt" >&2
    193     return 1
    194   fi
    195   local pkg_version=$(head -n 1 debian/changelog)
    196   # Get only the part between the first "jpeg-xl (" and the following ")".
    197   pkg_version="${pkg_version#jpeg-xl (}"
    198   pkg_version="${pkg_version%%)*}"
    199   if [[ -z "${pkg_version}" ]]; then
    200     echo "Couldn't parse version from debian package" >&2
    201     return 1
    202   fi
    203 
    204   local lib_version="${major}.${minor}.${patch}"
    205   lib_version="${lib_version%.0}"
    206   if [[ "${pkg_version}" != "${lib_version}"* ]]; then
    207     echo "Debian package version (${pkg_version}) doesn't match library" \
    208       "version (${lib_version})." >&2
    209     return 1
    210   fi
    211   return 0
    212 }
    213 
    214 # Check that the SHA versions in deps.sh matches the git submodules.
    215 test_deps_version() {
    216   while IFS= read -r line; do
    217     if [[ "${line:0:10}" != "[submodule" ]]; then
    218       continue
    219     fi
    220     line="${line#[submodule \"}"
    221     line="${line%\"]}"
    222     local varname=$(tr '[:lower:]' '[:upper:]' <<< "${line}")
    223     varname="${varname/\//_}"
    224     if ! grep -F "${varname}=" deps.sh >/dev/null; then
    225       # Ignoring submodule not in deps.sh
    226       continue
    227     fi
    228     local deps_sha=$(grep -F "${varname}=" deps.sh | cut -f 2 -d '"')
    229     [[ -n "${deps_sha}" ]]
    230     local git_sha=$(git ls-tree -r HEAD "${line}" | cut -f 1 | cut -f 3 -d ' ')
    231     if [[ "${deps_sha}" != "${git_sha}" ]]; then
    232       cat >&2 <<EOF
    233 deps.sh: SHA for project ${line} is at ${deps_sha} but the git submodule is at
    234 ${git_sha}. Please update deps.sh
    235 
    236 If you did not intend to change the submodule's SHA value, it is possible that
    237 you accidentally included this change in your commit after a rebase or checkout
    238 without running "git submodule --init". To revert the submodule change run from
    239 the top checkout directory:
    240 
    241   git -C ${line} checkout ${deps_sha}
    242   git commit --amend ${line}
    243 
    244 EOF
    245       return 1
    246     fi
    247   done < .gitmodules
    248 }
    249 
    250 # Make sure that all the Fields objects are fuzzed directly.
    251 test_fuzz_fields() {
    252   local ret=0
    253   # List all the classes of the form "ClassName : public Fields".
    254   # This doesn't catch class names that are too long to fit.
    255   local field_classes=$( git ls-files |
    256     grep -E '\.(cc|h)' | grep -v 'test\.cc$' |
    257     xargs grep -h -o -E '\b[^ ]+ : public Fields' | cut -f 1 -d ' ')
    258   local classname
    259   for classname in ${field_classes}; do
    260     if [ ! -e "$classname" ]; then
    261       continue
    262     fi
    263     if ! grep -E "\\b${classname}\\b" tools/fields_fuzzer.cc >/dev/null; then
    264       cat >&2 <<EOF
    265 tools/fields_fuzzer.cc: Class ${classname} not found in the fields_fuzzer.
    266 EOF
    267       ret=1
    268     fi
    269   done
    270   return $ret
    271 }
    272 
    273 # Test that we don't use %n in C++ code to avoid using it in printf and scanf.
    274 # This test is not very precise but in cases where "module n" is needed we would
    275 # normally have "% n" instead of "%n". Using %n is not allowed in Android 10+.
    276 test_percent_n() {
    277   local ret=0
    278   local f
    279   for f in $(git ls-files | grep -E '(\.cc|\.cpp|\.h)$'); do
    280     if [ ! -e "$f" ]; then
    281       continue
    282     fi
    283     if grep -i -H -n -E '%h*n' "$f" >&2; then
    284       echo "Don't use \"%n\"." >&2
    285       ret=1
    286     fi
    287   done
    288   return ${ret}
    289 }
    290 
    291 main() {
    292   local ret=0
    293   cd "${MYDIR}"
    294 
    295   if ! git rev-parse >/dev/null 2>/dev/null; then
    296     echo "Not a git checkout, skipping bash_test"
    297     return 0
    298   fi
    299 
    300   IFS=$'\n'
    301   for f in $(declare -F); do
    302     local test_name=$(echo "$f" | cut -f 3 -d ' ')
    303     # Runs all the local bash functions that start with "test_".
    304     if [[ "${test_name}" == test_* ]]; then
    305       echo "Test ${test_name}: Start"
    306       if ${test_name}; then
    307         echo "Test ${test_name}: PASS"
    308       else
    309         echo "Test ${test_name}: FAIL"
    310         ret=1
    311       fi
    312     fi
    313   done
    314   return ${ret}
    315 }
    316 
    317 main "$@"