diff --git a/ci/ci_lint.sh b/ci/ci_lint.sh index 163d955de..674e55f5d 100755 --- a/ci/ci_lint.sh +++ b/ci/ci_lint.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -o errexit -o pipefail -o posix -# Copyright (c) 2019-2024 Cosmin Truta. +# Copyright (c) 2019-2025 Cosmin Truta. # # Use, modification and distribution are subject to the MIT License. # Please see the accompanying file LICENSE_MIT.txt @@ -61,7 +61,7 @@ function ci_lint_ci_scripts { } ci_info "## LINTING: CI scripts ##" ci_spawn "$CI_SHELLCHECK" --version - find ./ci -maxdepth 1 -name "*.sh" | { + find ./ci -name "ci_*.sh" -not -name "ci_env.*.sh" | { local my_file while IFS="" read -r my_file do diff --git a/ci/ci_shellify.sh b/ci/ci_shellify.sh deleted file mode 100755 index e6693af97..000000000 --- a/ci/ci_shellify.sh +++ /dev/null @@ -1,92 +0,0 @@ -#!/usr/bin/env bash -set -o errexit -o pipefail -o posix - -# Copyright (c) 2019-2024 Cosmin Truta. -# -# Use, modification and distribution are subject to the MIT License. -# Please see the accompanying file LICENSE_MIT.txt -# -# SPDX-License-Identifier: MIT - -# shellcheck source=ci/lib/ci.lib.sh -source "$(dirname "$0")/lib/ci.lib.sh" -cd "$CI_TOPLEVEL_DIR" - -function ci_shellify_c { - # Convert C preprocessor text, specifically originating - # from png.h, to shell scripting text. - # Select only the easy-to-parse definitions of PNG_LIBPNG_*. - sed -n -e '/^\# *define * PNG_LIBPNG_[^ ]* * ["0-9A-Za-z_]/ p' | - sed -e 's/^\# *define * PNG\([^ ]*\) * \([^ ]*\)/PNG\1=\2/' \ - -e 's/=PNG\([0-9A-Za-z_]*\)/=\${PNG\1}/' \ - -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/' -} - -function ci_shellify_autoconf { - # Convert autoconf (M4) text, specifically originating - # from configure.ac, to shell scripting text. - # Select only the easy-to-parse definitions of PNGLIB_*. - sed -n -e '/^ *PNGLIB_[^ ]*=[$"0-9A-Za-z_]/ p' | - sed -e 's/^ *PNG\([0-9A-Za-z_]*\)=\([^# ]*\).*$/PNG\1=\2/' \ - -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/' -} - -function ci_shellify_cmake { - # Convert CMake lists text, specifically originating - # from CMakeLists.txt, to shell scripting text. - # Select only the easy-to-parse definitions of PNGLIB_*. - sed -n -e '/^ *set *(PNGLIB_[^ ]* * [$"0-9A-Za-z_].*)/ p' | - sed -e 's/^ *set *(PNG\([^ ]*\) * \([^() ]*\)).*$/PNG\1=\2/' \ - -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/' -} - -function ci_shellify { - local arg filename - for arg in "$@" - do - test -f "$arg" || ci_err "no such file: '$arg'" - filename="$(basename -- "$arg")" - case "$filename" in - ( *.[ch] ) - [[ $filename == png.h ]] || { - ci_err "unable to shellify: '$filename' (expecting: 'png.h')" - } - ci_shellify_c <"$arg" ;; - ( config* | *.ac ) - [[ $filename == configure.ac ]] || { - ci_err "unable to shellify: '$filename' (expecting: 'configure.ac')" - } - ci_shellify_autoconf <"$arg" ;; - ( *CMake* | *cmake* | *.txt ) - [[ $filename == [Cc][Mm]ake[Ll]ists.txt ]] || { - ci_err "unable to shellify: '$filename' (expecting: 'CMakeLists.txt')" - } - ci_shellify_cmake <"$arg" ;; - ( * ) - ci_err "unable to shellify: '$arg'" ;; - esac - done -} - -function usage { - echo "usage: $CI_SCRIPT_NAME [] ..." - echo "options: -?|-h|--help" - echo "files: png.h|configure.ac|CMakeLists.txt" - exit "${@:-0}" -} - -function main { - local opt - while getopts ":" opt - do - # This ain't a while-loop. It only pretends to be. - [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 - ci_err "unknown option: '$1'" - done - shift $((OPTIND - 1)) - [[ $# -eq 0 ]] && usage 2 - # And... go! - ci_shellify "$@" -} - -main "$@" diff --git a/ci/ci_verify_version.sh b/ci/ci_verify_version.sh index 3203b201f..5908724cd 100755 --- a/ci/ci_verify_version.sh +++ b/ci/ci_verify_version.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -o errexit -o pipefail -o posix -# Copyright (c) 2019-2024 Cosmin Truta. +# Copyright (c) 2019-2025 Cosmin Truta. # # Use, modification and distribution are subject to the MIT License. # Please see the accompanying file LICENSE_MIT.txt @@ -12,33 +12,43 @@ set -o errexit -o pipefail -o posix source "$(dirname "$0")/lib/ci.lib.sh" cd "$CI_TOPLEVEL_DIR" -function ci_init_shellify { - [[ -f $CI_SCRIPT_DIR/ci_shellify.sh ]] || { - ci_err_internal "missing script: '$CI_SCRIPT_DIR/ci_shellify.sh'" - } -} +# Declare the global environments collected from various sources. +declare CI_ENV_LIBPNG_VER # collected from png.h +declare CI_ENV_AUTOCONF_VER # collected from configure.ac +declare CI_ENV_CMAKE_VER # collected from CMakeLists.txt +declare CI_ENV_LIBPNGCONFIG_VER # collected from scripts/libpng-config-head.in function ci_run_shellify { + local my_script my_result + my_script="$CI_SCRIPT_DIR/libexec/ci_shellify_${1#--}.sh" + shift 1 + [[ -f $my_script ]] || { + ci_err_internal "missing script: '$my_script'" + } ci_info "shellifying:" "$@" - local my_result - "$BASH" "$CI_SCRIPT_DIR/ci_shellify.sh" "$@" + "$BASH" "$my_script" "$@" echo "$my_result" | "$BASH" --posix || ci_err "bad shellify output" echo "$my_result" } -function ci_verify_version { +function ci_init_version_verification { ci_info "## START OF VERIFICATION ##" - local my_env_libpng_ver my_env_autoconf_ver my_env_cmake_ver my_expect - ci_init_shellify - my_env_libpng_ver="$(ci_run_shellify png.h)" - echo "$my_env_libpng_ver" - my_env_autoconf_ver="$(ci_run_shellify configure.ac)" - echo "$my_env_autoconf_ver" - my_env_cmake_ver="$(ci_run_shellify CMakeLists.txt)" - echo "$my_env_cmake_ver" - ci_info "## VERIFYING: png.h version definitions ##" - eval "$my_env_libpng_ver" - local my_expect="${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}" + CI_ENV_LIBPNG_VER="$(ci_run_shellify --c png.h)" + echo "$CI_ENV_LIBPNG_VER" + CI_ENV_AUTOCONF_VER="$(ci_run_shellify --autoconf configure.ac)" + echo "$CI_ENV_AUTOCONF_VER" + CI_ENV_CMAKE_VER="$(ci_run_shellify --cmake CMakeLists.txt)" + echo "$CI_ENV_CMAKE_VER" + CI_ENV_LIBPNGCONFIG_VER="$(ci_run_shellify --shell scripts/libpng-config-head.in)" + echo "$CI_ENV_LIBPNGCONFIG_VER" +} + +# shellcheck disable=SC2154 +function ci_do_version_verification { + local my_expect + ci_info "## VERIFYING: version definitions in 'png.h' ##" + eval "$CI_ENV_LIBPNG_VER" + my_expect="${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}" if [[ "$PNG_LIBPNG_VER_STRING" == "$my_expect"* ]] then ci_info "matched: \$PNG_LIBPNG_VER_STRING == $my_expect*" @@ -77,7 +87,7 @@ function ci_verify_version { else ci_err "mismatched: \$PNG_LIBPNG_VER_BUILD != [01]" fi - ci_info "## VERIFYING: png.h build definitions ##" + ci_info "## VERIFYING: build definitions in 'png.h' ##" my_expect="${PNG_LIBPNG_VER_MAJOR}.${PNG_LIBPNG_VER_MINOR}.${PNG_LIBPNG_VER_RELEASE}" if [[ "$PNG_LIBPNG_VER_STRING" == "$my_expect" ]] then @@ -110,19 +120,19 @@ function ci_verify_version { else ci_err "unexpected: \$PNG_LIBPNG_VER_STRING == '$PNG_LIBPNG_VER_STRING'" fi - ci_info "## VERIFYING: png.h type definitions ##" + ci_info "## VERIFYING: type definitions in 'png.h' ##" my_expect="$(echo "png_libpng_version_${PNG_LIBPNG_VER_STRING}" | tr . _)" ci_spawn grep -w -e "$my_expect" png.h - ci_info "## VERIFYING: configure.ac version definitions ##" - eval "$my_env_autoconf_ver" + ci_info "## VERIFYING: version definitions in 'configure.ac' ##" + eval "$CI_ENV_AUTOCONF_VER" if [[ "$PNGLIB_VERSION" == "$PNG_LIBPNG_VER_STRING" ]] then ci_info "matched: \$PNGLIB_VERSION == \$PNG_LIBPNG_VER_STRING" else ci_err "mismatched: \$PNGLIB_VERSION != \$PNG_LIBPNG_VER_STRING" fi - ci_info "## VERIFYING: CMakeLists.txt version definitions ##" - eval "$my_env_cmake_ver" + ci_info "## VERIFYING: version definitions in 'CMakeLists.txt' ##" + eval "$CI_ENV_CMAKE_VER" if [[ "$PNGLIB_VERSION" == "$PNG_LIBPNG_VER_STRING" && "$PNGLIB_SUBREVISION" == 0 ]] then ci_info "matched: \$PNGLIB_VERSION == \$PNG_LIBPNG_VER_STRING" @@ -133,8 +143,26 @@ function ci_verify_version { else ci_err "mismatched: \$PNGLIB_VERSION != \$PNG_LIBPNG_VER_STRING" fi + ci_info "## VERIFYING: version definitions in 'scripts/libpng-config-head.in' ##" + eval "$CI_ENV_LIBPNGCONFIG_VER" + if [[ "$version" == "$PNG_LIBPNG_VER_STRING" ]] + then + ci_info "matched: \$version == \$PNG_LIBPNG_VER_STRING" + else + ci_err "mismatched: \$version != \$PNG_LIBPNG_VER_STRING" + fi +} + +function ci_finish_version_verification { ci_info "## END OF VERIFICATION ##" - ci_info "success!" + # Relying on "set -o errexit" to not reach here in case of error. + ci_info "## SUCCESS ##" +} + +function ci_verify_version { + ci_init_version_verification + ci_do_version_verification + ci_finish_version_verification } function usage { diff --git a/ci/libexec/ci_shellify_autoconf.sh b/ci/libexec/ci_shellify_autoconf.sh new file mode 100755 index 000000000..bf37f0d26 --- /dev/null +++ b/ci/libexec/ci_shellify_autoconf.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -o errexit -o pipefail -o posix + +# Copyright (c) 2019-2025 Cosmin Truta. +# +# Use, modification and distribution are subject to the MIT License. +# Please see the accompanying file LICENSE_MIT.txt +# +# SPDX-License-Identifier: MIT + +# shellcheck source=ci/lib/ci.lib.sh +source "$(dirname "$0")/../lib/ci.lib.sh" + +function ci_shellify_autoconf { + # Convert autoconf (M4) text, specifically originating + # from configure.ac, to shell scripting text. + # Select only the easy-to-parse definitions of PNGLIB_*. + sed -n -e '/^ *PNGLIB_[^ ]*=[$"0-9A-Za-z_]/ p' | + sed -e 's/^ *PNG\([0-9A-Za-z_]*\)=\([^# ]*\).*$/PNG\1=\2/' \ + -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/' +} + +function usage { + echo "usage: $CI_SCRIPT_NAME [] configure.ac" + echo "options: -?|-h|--help" + exit "${@:-0}" +} + +function main { + local opt + while getopts ":" opt + do + # This ain't a while-loop. It only pretends to be. + [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 + ci_err "unknown option: '$1'" + done + shift $((OPTIND - 1)) + [[ $# -eq 0 ]] && usage 2 + [[ $# -eq 1 ]] || ci_err "too many operands" + # And... go! + test -e "$1" || ci_err "no such file: '$1'" + [[ $(basename -- "$1") == configure.ac ]] || { + ci_err "incorrect operand: '$1' (expecting: 'configure.ac')" + } + ci_shellify_autoconf <"$1" +} + +main "$@" diff --git a/ci/libexec/ci_shellify_c.sh b/ci/libexec/ci_shellify_c.sh new file mode 100755 index 000000000..244fc2275 --- /dev/null +++ b/ci/libexec/ci_shellify_c.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +set -o errexit -o pipefail -o posix + +# Copyright (c) 2019-2025 Cosmin Truta. +# +# Use, modification and distribution are subject to the MIT License. +# Please see the accompanying file LICENSE_MIT.txt +# +# SPDX-License-Identifier: MIT + +# shellcheck source=ci/lib/ci.lib.sh +source "$(dirname "$0")/../lib/ci.lib.sh" + +function ci_shellify_c { + # Convert C preprocessor text, specifically originating + # from png.h, to shell scripting text. + # Select only the easy-to-parse definitions of PNG_LIBPNG_*. + sed -n -e '/^\# *define * PNG_LIBPNG_[^ ]* * ["0-9A-Za-z_]/ p' | + sed -e 's/^\# *define * PNG\([^ ]*\) * \([^ ]*\)/PNG\1=\2/' \ + -e 's/=PNG\([0-9A-Za-z_]*\)/=\${PNG\1}/' \ + -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/' +} + +function usage { + echo "usage: $CI_SCRIPT_NAME [] png.h" + echo "options: -?|-h|--help" + exit "${@:-0}" +} + +function main { + local opt + while getopts ":" opt + do + # This ain't a while-loop. It only pretends to be. + [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 + ci_err "unknown option: '$1'" + done + shift $((OPTIND - 1)) + [[ $# -eq 0 ]] && usage 2 + [[ $# -eq 1 ]] || ci_err "too many operands" + # And... go! + test -e "$1" || ci_err "no such file: '$1'" + [[ $(basename -- "$1") == png.h ]] || { + ci_err "incorrect operand: '$1' (expecting: 'png.h')" + } + ci_shellify_c <"$1" +} + +main "$@" diff --git a/ci/libexec/ci_shellify_cmake.sh b/ci/libexec/ci_shellify_cmake.sh new file mode 100755 index 000000000..5596241ae --- /dev/null +++ b/ci/libexec/ci_shellify_cmake.sh @@ -0,0 +1,49 @@ +#!/usr/bin/env bash +set -o errexit -o pipefail -o posix + +# Copyright (c) 2019-2025 Cosmin Truta. +# +# Use, modification and distribution are subject to the MIT License. +# Please see the accompanying file LICENSE_MIT.txt +# +# SPDX-License-Identifier: MIT + +# shellcheck source=ci/lib/ci.lib.sh +source "$(dirname "$0")/../lib/ci.lib.sh" + +function ci_shellify_cmake { + # Convert CMake lists text, specifically originating + # from CMakeLists.txt, to shell scripting text. + # Select only the easy-to-parse definitions of PNGLIB_*. + sed -n -e '/^ *set *(PNGLIB_[^ ]* * [$"0-9A-Za-z_].*)/ p' | + sed -e 's/^ *set *(PNG\([^ ]*\) * \([^() ]*\)).*$/PNG\1=\2/' \ + -e 's/^\([^ ]*=[^ ]*\).*$/export \1;/' +} + +function usage { + echo "usage: $CI_SCRIPT_NAME [] CMakeLists.txt" + echo "options: -?|-h|--help" + exit "${@:-0}" +} + +function main { + local opt + while getopts ":" opt + do + # This ain't a while-loop. It only pretends to be. + [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 + ci_err "unknown option: '$1'" + done + shift $((OPTIND - 1)) + [[ $# -eq 0 ]] && usage 2 + [[ $# -eq 1 ]] || ci_err "too many operands" + # And... go! + test -e "$1" || ci_err "no such file: '$1'" + filename="$(basename -- "$1")" + [[ $filename == [Cc][Mm]ake[Ll]ists.txt ]] || { + ci_err "incorrect operand: '$1' (expecting: 'CMakeLists.txt')" + } + ci_shellify_cmake <"$1" +} + +main "$@" diff --git a/ci/libexec/ci_shellify_shell.sh b/ci/libexec/ci_shellify_shell.sh new file mode 100755 index 000000000..417006316 --- /dev/null +++ b/ci/libexec/ci_shellify_shell.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -o errexit -o pipefail -o posix + +# Copyright (c) 2019-2025 Cosmin Truta. +# +# Use, modification and distribution are subject to the MIT License. +# Please see the accompanying file LICENSE_MIT.txt +# +# SPDX-License-Identifier: MIT + +# shellcheck source=ci/lib/ci.lib.sh +source "$(dirname "$0")/../lib/ci.lib.sh" + +function ci_shellify_shell { + # Convert shell scripting text to shell scripting text. + # Select only the easy-to-parse version definitions. + sed -n -e '/^ *[A-Za-z_][0-9A-Za-z_]*=[0-9][^ #]* *$/ p' | + sed -e 's/^ *\([^ ]*=[^ ]*\) *$/export \1;/' +} + +function usage { + echo "usage: $CI_SCRIPT_NAME [] libpng-config-head.in" + echo "options: -?|-h|--help" + exit "${@:-0}" +} + +function main { + local opt + while getopts ":" opt + do + # This ain't a while-loop. It only pretends to be. + [[ $1 == -[?h]* || $1 == --help || $1 == --help=* ]] && usage 0 + ci_err "unknown option: '$1'" + done + shift $((OPTIND - 1)) + [[ $# -eq 0 ]] && usage 2 + [[ $# -eq 1 ]] || ci_err "too many operands" + # And... go! + test -e "$1" || ci_err "no such file: '$1'" + [[ $(basename -- "$1") == libpng-config-head.in ]] || { + ci_err "incorrect operand: '$1' (expecting: 'libpng-config-head.in')" + } + ci_shellify_shell <"$1" +} + +main "$@"