summaryrefslogtreecommitdiffhomepage
path: root/subr.ex/ex_pkg.subr
diff options
context:
space:
mode:
Diffstat (limited to 'subr.ex/ex_pkg.subr')
-rw-r--r--subr.ex/ex_pkg.subr324
1 files changed, 324 insertions, 0 deletions
diff --git a/subr.ex/ex_pkg.subr b/subr.ex/ex_pkg.subr
new file mode 100644
index 00000000..6a5670be
--- /dev/null
+++ b/subr.ex/ex_pkg.subr
@@ -0,0 +1,324 @@
+#
+# set +o errexit -o noglob -o nounset is assumed.
+#
+
+#
+# ex_pkg_check_depends() - check single named package for unsatisfied dependencies
+# @_checkfl: enable (1) or inhibit (0) dependency expansion
+# @_rpkg_disabled: reference to in variable of list of disabled packages
+# @_rpkg_finished: reference to in variable of list of finished packages
+# @_pkg_name: single package name
+# @_rpkg_names: reference to in variable of list of package names
+# @_workdir: pathname to build-specific temporary directory
+#
+# Return: zero (0) given no outstanding dependencies, non-zero (>0) otherwise
+# Side effects: ${PKG_${_PKG_NAME}_DEPENDS_FULL} may be mutated
+#
+ex_pkg_check_depends() {
+ local _epcd_checkfl="${1}" _epcd_rpkg_disabled="${2}" _epcd_rpkg_finished="${3#\$}" \
+ _epcd_pkg_name="${4}" _epcd_rpkg_names="${5#\$}" _epcd_workdir="${6}" \
+ _epcd_dependfl=0 _epcd_depends="" _epcd_pkg_name_depend="";
+
+ if [ "${_epcd_checkfl}" -eq 1 ]; then
+ if ! rtl_get_var_unsafe \$_epcd_depends -u "PKG_"${_epcd_pkg_name}"_DEPENDS_FULL"\
+ || [ "${_epcd_depends:+1}" != 1 ];
+ then
+ if rtl_get_var_unsafe \$_epcd_depends -u "PKG_"${_epcd_pkg_name}"_DEPENDS";
+ then
+ eval PKG_"${_epcd_pkg_name}"_DEPENDS_FULL='$(rtl_uniq ${_epcd_depends})';
+ else
+ return 0;
+ fi;
+ fi;
+
+ for _epcd_pkg_name_depend in ${_epcd_depends}; do
+ if ! rtl_lmatch "${_epcd_rpkg_disabled}" "${_epcd_pkg_name_depend}"\
+ && ! rtl_lmatch "${_epcd_rpkg_finished}" "${_epcd_pkg_name_depend}"\
+ && ! ex_pkg_state_test2 "${_epcd_workdir}" "${_epcd_pkg_name_depend}" finish;
+ then
+ if ! rtl_lmatch "${_epcd_rpkg_names}" "${_epcd_pkg_name_depend}"; then
+ rtl_log_msg "fatalexit" "${MSG_build_unknown_dep}" "${_epcd_pkg_name_depend}" "${_epcd_pkg_name}";
+ else
+ _epcd_dependfl=1; break;
+ fi;
+ fi;
+ done;
+ fi;
+
+ return "${_epcd_dependfl}";
+};
+
+#
+# ex_pkg_find_package() - find build group a single named package belongs to
+# @_rgroup_name: reference to out variable of build group name
+# @_group_names: build group names
+# @_pkg_name: single named package
+#
+# Return: zero (0) on success, non-zero (>0) if package not found, group name on stdout if package was found.
+#
+ex_pkg_find_package() {
+ local _epfp_rgroup_name="${1#\$}" _epfp_group_names="${2}" _epfp_pkg_name="${3}" \
+ _epfp_foundfl=0 _epfp_group_name="" _epfp_pkg_names="";
+
+ for _epfp_group_name in ${_epfp_group_names}; do
+ if rtl_get_var_unsafe \$_epfp_pkg_names -u "${_epfp_group_name}_PACKAGES"\
+ && [ "${_epfp_pkg_names:+1}" = 1 ]\
+ && rtl_lmatch \$_epfp_pkg_names "${_epfp_pkg_name}"; then
+ _epfp_foundfl=1; break;
+ fi;
+ done;
+
+ case "${_epfp_foundfl:-0}" in
+ 0) eval ${_epfp_rgroup_name}=;
+ return 1; ;;
+
+ 1) eval ${_epfp_rgroup_name}='${_epfp_group_name}';
+ return 0; ;;
+ esac;
+};
+
+#
+# ex_pkg_get_packages() - get list of packages belonging to single named build group
+# @_rpkg_names: reference to out variable of package names
+# @_group_name: build group name
+#
+# Return: zero (0) on success, non-zero (>0) on failure, list of package names on stdout on success.
+#
+ex_pkg_get_packages() {
+ local _epgp_rpkg_names="${1#\$}" _epgp_group_name="${2}" \
+ _epgp_pkg_names="";
+
+ if rtl_get_var_unsafe \$_epgp_pkg_names -u "${_epgp_group_name}_PACKAGES"\
+ && [ "${_epgp_pkg_names:+1}" = 1 ]; then
+ eval ${_epgp_rpkg_names}='${_epgp_pkg_names}';
+ return 0;
+ else
+ eval ${_epgp_rpkg_names}=;
+ return 1;
+ fi;
+};
+
+#
+# ex_pkg_load_vars() - load build variables
+# @_rstatus: out reference to status string
+#
+# Return: zero (0) on success, non-zero (>0) on failure, build variables post-return on success.
+#
+ex_pkg_load_vars() {
+ local _eplv_rstatus="${1#\$}" \
+ _eplv_rc=0 _eplv_fname="";
+
+ if ! rtl_lmatch \$ARCH "nt32 nt64"; then
+ _eplv_rc=1;
+ rtl_setrstatus "${_eplv_rstatus}" 'Error: invalid architecture \`'"${ARCH}"''\''.';
+ elif ! rtl_lmatch \$BUILD_KIND "debug release"; then
+ _eplv_rc=1;
+ rtl_setrstatus "${_eplv_rstatus}" 'Error: unknown build type \`'"${BUILD_KIND}"''\''.';
+ else
+ case "${ARCH}" in
+ nt32) DEFAULT_TARGET="i686-nt32-midipix"; ;;
+ nt64) DEFAULT_TARGET="x86_64-nt64-midipix"; ;;
+ esac;
+
+ for _eplv_fname in \
+ "${HOME}/midipix_build.vars" \
+ "${HOME}/.midipix_build.vars" \
+ ../midipix_build.vars \
+ ./midipix.env;
+ do
+ if [ -r "${_eplv_fname}" ]; then
+ rtl_fileop source "${_eplv_fname}";
+ fi;
+ done;
+
+ if [ "${PREFIX:+1}" != 1 ]; then
+ _eplv_rc=1;
+ rtl_setrstatus "${_eplv_rstatus}" 'Error: ${PREFIX} empty or unset.';
+ fi;
+ fi;
+
+ return "${_eplv_rc}";
+};
+
+#
+# ex_pkg_load_groups() - load all available build groups
+# @_rgroups: reference to out variable of build groups
+# @_rgroups_noauoto: optional reference to out variable of build groups not built automatically
+# @_rgroup_auto: reference to in variable of flag controlling whether to build group automatically
+# @_rgroup_target: reference to in variable of build group targets
+#
+# Return: zero (0) on success, non-zero (>0) on failure.
+#
+ex_pkg_load_groups() {
+ local _eplg_rgroups="${1#\$}" _eplg_rgroups_noauto="${2#\$}" \
+ _eplg_rgroup_auto="${3#\$}" _eplg_rgroup_target="${4#\$}" \
+ _eplg_build_groups="" _eplg_build_groups_noauto="" \
+ _eplg_fname="" _eplg_group="" _eplg_groups="";
+
+ for _eplg_fname in $(find ./groups -name *.group | sort); do
+ rtl_fileop source_opt "${_eplg_fname}";
+
+ if eval [ \"\${${_eplg_rgroup_target}:+1}\" = 1 ]; then
+ eval _eplg_group=\"\${${_eplg_rgroup_target}}\";
+ eval unset ${_eplg_rgroup_target};
+ else
+ _eplg_group="${_eplg_fname##*/}";
+ _eplg_group="${_eplg_group%.group}";
+ _eplg_group="${_eplg_group#*.}";
+ fi;
+
+ if ! rtl_lmatch \$_eplg_groups "${_eplg_group}"; then
+ rtl_lconcat \$_eplg_groups "${_eplg_group}";
+ if eval [ \"\${${_eplg_rgroup_auto}:+1}\" = 1 ]; then
+ if eval [ \"\${${_eplg_rgroup_auto}:-0}\" -ne 0 ]; then
+ rtl_lconcat \$_eplg_build_groups "${_eplg_group}";
+ else
+ rtl_lconcat \$_eplg_build_groups_noauto "${_eplg_group}";
+ fi;
+ eval unset ${_eplg_rgroup_auto};
+ else
+ rtl_lconcat \$_eplg_build_groups "${_eplg_group}";
+ fi;
+ fi;
+ done;
+
+ _eplg_build_groups="$(rtl_uniq "${_eplg_build_groups}")";
+ eval ${_eplg_rgroups}=\"${_eplg_build_groups}\";
+
+ if [ "${_eplg_rgroups_noauto:+1}" = 1 ]; then
+ _eplg_build_groups_noauto="$(rtl_uniq "${_eplg_build_groups_noauto}")";
+ eval ${_eplg_rgroups_noauto}=\"${_eplg_build_groups_noauto}\";
+ fi;
+
+ return 0;
+};
+
+#
+# ex_pkg_unfold_depends() - unfold list of package names into dependency-expanded set of complete, disabled, finished, and outstanding package names
+# @_rdisabled: reference to inout variable of disabled packages
+# @_rfinished: reference to inout variable of finished packages
+# @_rnames: reference to out variable of package names
+# @_checkfl: enable (1) or inhibit (0) dependency expansion
+# @_forcefl: enable (1) or inhibit (0) forcibly rebuilding finished packages
+# @_group_name: build group name
+# @_pkg_names: list of package names
+# @_restart: optional whitespace-separated list of package names to rebuild
+# @_test_finished: only exclude disabled packages (0,) split finished packages
+# @_workdir: pathname to build-specific temporary directory
+#
+# Return: zero (0) on success, non-zero (>0) on failure.
+#
+ex_pkg_unfold_depends() {
+ local _epud_rdisabled="${1#\$}" _epud_rfinished="${2#\$}" _epud_rnames="${3#\$}" \
+ _epud_checkfl="${4}" _epud_forcefl="${5}" _epud_group_name="${6}" \
+ _epud_pkg_names="${7}" _epud_restart="${8}" _epud_test_finished="${9}" \
+ _epud_workdir="${10}" \
+ _epud_pkg_disabled="" _epud_pkg_force="" _epud_pkg_name="" \
+ _epud_pkg_names_new="" _epud_restartfl=0;
+
+ if [ "${_epud_restart:+1}" = 1 ]\
+ && ! rtl_lmatch \$_epud_restart "ALL LAST"; then
+ rtl_lsearch \$_epud_pkg_names "${_epud_restart}";
+ fi;
+ if [ "${_epud_restart:+1}" = 1 ]\
+ && [ "${_epud_checkfl:-0}" -eq 1 ]; then
+ rtl_lunfold_depends 'PKG_${_rld_name}_DEPENDS' \$_epud_pkg_names ${_epud_pkg_names};
+ _epud_pkg_names="$(rtl_uniq ${_epud_pkg_names})";
+ fi;
+
+ for _epud_pkg_name in ${_epud_pkg_names}; do
+ if [ "${_epud_restart}" = "ALL" ]\
+ || rtl_lmatch \$_epud_restart "${_epud_pkg_name}"; then
+ _epud_restartfl=1;
+ else
+ _epud_restartfl=0;
+ fi;
+
+ if rtl_get_var_unsafe \$_epud_pkg_disabled -u "PKG_${_epud_pkg_name}_DISABLED"\
+ && [ "${_epud_pkg_disabled}" = 1 ];
+ then
+ rtl_lconcat "${_epud_rdisabled}" "${_epud_pkg_name}";
+
+ elif [ "${_epud_test_finished:-1}" -eq 1 ]\
+ && ex_pkg_state_test2 "${_epud_workdir}" "${_epud_pkg_name}" finish\
+ && [ "${_epud_restartfl:-0}" -eq 0 ]\
+ && [ "${_epud_forcefl:-0}" -ne 1 ]\
+ && rtl_get_var_unsafe \$_epud_pkg_force -u "${_epud_group_name}_FORCE"\
+ && [ "${_epud_pkg_force}" != 1 ];
+ then
+ rtl_lconcat "${_epud_rfinished}" "${_epud_pkg_name}";
+
+ else
+ rtl_lconcat \$_epud_pkg_names_new "${_epud_pkg_name}";
+ fi;
+ done;
+
+ eval ${_epud_rdisabled}='$(rtl_uniq2 "${_epud_rdisabled}")';
+ eval ${_epud_rfinished}='$(rtl_uniq2 "${_epud_rfinished}")';
+ eval ${_epud_rnames}='$(rtl_uniq "${_epud_pkg_names_new}")';
+
+ return 0;
+};
+
+#
+# ex_pkg_unfold_rdepends() - unfold list of package names into reverse dependency-expanded set of complete, disabled, finished, and outstanding package names
+# @_rdisabled: reference to inout variable of disabled packages
+# @_rfinished: reference to inout variable of finished packages
+# @_rnames: reference to out variable of package names
+# @_group_name: build group name
+# @_pkg_names: list of package names
+# @_restart: optional whitespace-separated list of package names to rebuild
+# @_test_finished: only exclude disabled packages (0,) split finished packages
+# @_workdir: pathname to build-specific temporary directory
+#
+# Return: zero (0) on success, non-zero (>0) on failure.
+#
+ex_pkg_unfold_rdepends() {
+ local _epur_rdisabled="${1#\$}" _epur_rfinished="${2#\$}" _epur_rnames="${3#\$}" \
+ _epur_group_name="${4}" _epur_pkg_names="${5}" _epur_restart="${6}" \
+ _epur_test_finished="${7}" _epur_workdir="${8}" \
+ _epur_depends="" _epur_disabled=0 _epur_force=0 _epur_pkg_depends="" \
+ _epur_pkg_name="" _epur_pkg_names_new="" _epur_pkg_name_depend="" \
+ _epur_pkg_rdepends="";
+
+ for _epur_pkg_name_depend in ${_epur_restart}; do
+ for _epur_pkg_name in ${_epur_pkg_names}; do
+ if [ "${_epur_pkg_name}" = "${_epur_pkg_name_depend}" ]; then
+ continue;
+
+ elif rtl_get_var_unsafe \$_epur_depends -u "PKG_"${_epur_pkg_name}"_DEPENDS"\
+ && rtl_lunfold_depends 'PKG_${_rld_name}_DEPENDS' \$_epur_pkg_depends ${_epur_depends}\
+ && [ "${_epur_pkg_depends:+1}" = 1 ]\
+ && rtl_lmatch \$_epur_pkg_depends "${_epur_pkg_name_depend}";
+ then
+ if rtl_get_var_unsafe \$_epur_disabled -u "PKG_${_epur_pkg_name}_DISABLED"\
+ && [ "${_epur_disabled}" = 1 ];
+ then
+ rtl_lconcat "${_epur_rdisabled}" "${_epur_pkg_name}";
+
+ elif [ "${_epur_test_finished}" -eq 1 ]\
+ && ex_pkg_state_test2 "${_epur_workdir}" "${_epur_pkg_name}" finish\
+ && rtl_get_var_unsafe \$_epur_force -u "${_epur_group_name}_FORCE"\
+ && [ "${_epur_force}" != 1 ];
+ then
+ rtl_lconcat "${_epur_rfinished}" "${_epur_pkg_name}";
+
+ elif [ "${_epur_test_finished:-1}" -eq 0 ]\
+ || ! ex_pkg_state_test2 "${_epur_workdir}" "${_epur_pkg_name}" finish\
+ || ( rtl_get_var_unsafe \$_epur_force -u "${_epur_group_name}_FORCE"\
+ && [ "${_epur_force}" = 1 ] );
+ then
+ rtl_lconcat \$_epur_pkg_names_new "${_epur_pkg_name}";
+ fi;
+ fi;
+ done;
+ done;
+
+ eval ${_epur_rdisabled}='$(rtl_uniq2 "${_epur_rdisabled}")';
+ eval ${_epur_rfinished}='$(rtl_uniq2 "${_epur_rfinished}")';
+ eval ${_epur_rnames}='$(rtl_uniq "${_epur_pkg_names_new}")';
+
+ return 0;
+};
+
+# vim:filetype=sh textwidth=0