#!/bin/bash
################################################################################
#
# cygport - Cygwin packaging application
#
# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Yaakov Selkowitz
# Provided by the Cygwin Ports project <http://sourceware.org/cygwinports/>
#
# cygport is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# cygport is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with cygport.  If not, see <http://www.gnu.org/licenses/>.
#
################################################################################
set -e;


################################################################################
#
# Initialization
#
################################################################################

# for regexes, sort, etc.
export LC_COLLATE=C

declare -r  _version=0.14.0;

declare -r _privdatadir=/usr/share/cygport;
declare -r _privclassdir=/usr/share/cygport/cygclass;
declare -r _privlibdir=/usr/share/cygport/lib;
declare -r _privgnuconfigdir=/usr/share/cygport;
declare -r _sysconfdir=/etc;


### import defined, pushd, popd
source ${_privlibdir}/syntax.cygpart
###


################################################################################
#
# Command-line Help
#
################################################################################

#****** Cygport/Title
#  OVERVIEW
#  The Cygport Reference Manual documents cygport, a utility for creating and
#  building software packages for the Cygwin platform.
#
#  |html Copyright &#169; 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Yaakov Selkowitz
#
#  Permission is granted to copy, distribute and/or modify this manual
#  under the terms of the GNU Free Documentation License, Version 1.3 or
#  any later version published by the Free Software Foundation; with no
#  Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
#  You should have received a copy of the GNU Free Documentation License
#  along with this manual. If not, see http://www.gnu.org/licenses/.
#****

#****** Cygport/Introduction
#  INTRODUCTION
#  cygport is a utility for creating and building software packages for the
#  software platform.  It is designed to minimize the amount of code and
#  effort for individual packages, automating common processes while leaving
#  flexibility to deal with unusual packages while avoiding many mistakes
#  or omissions.
#
#  cygport packages are controlled by .cygport files, which define variables
#  and functions unique to that package and version.  cygport provides a
#  modular API, documented here, which covers a wide variety of packaging
#  scenarios.
#
#  The syntax of .cygport files resemble that of Gentoo Portage, but they
#  are not compatible.  Furthermore, unlike Portage, cygport is not a
#  package manager; it only creates packages which can then be used in a
#  Cygwin package repository and installed with Cygwin's setup.exe package
#  manager.
#
#  This manual is divided into the following chapters:
#  * Usage
#  * Configuration
#  * Format
#  * Information
#  * Downloading
#  * Preparation
#  * Checks
#  * Compiling
#  * Testing
#  * Installing
#  * Postinstall
#  * Packaging
#  * Cygclasses
#****

#****** Cygport/Usage
#  USAGE
#  See href:cygport.1.html for command line options.
#  REQUIRES
#  The following packages are required to build packages with cygport:
#   autoconf, automake, bash, binutils, bzip2, coreutils, diffstat, diffutils,
#   dos2unix, file, gawk, grep, gzip, libtool, lndir, make, patch, rsync, sed,
#   tar, unzip, util-linux, wget, which, xz.
#  Other software packages are required by some Cygclasses, as indicated within.
#****

### import _show_help, _show_version
source ${_privlibdir}/help.cygpart
###

# Accept --help and --version arguments without specifying a cygport file
while true
do
	case ${1} in
	--help|-h|-\?)
		__show_help;
		exit 0;
		;;
	--version|-v)
		__show_version;
		exit 0;
		;;
	--debug|-d)
		set -x;
		shift;
		;;
	--32|-4)
		if defined _host_arch && [ ${_host_arch} != i686 ]
		then
			error "Only one of --32|--64 may be specified"
		fi
		_host_arch=i686
		shift;
		;;
	--64|-8)
		if defined _host_arch && [ ${_host_arch} != x86_64 ]
		then
			error "Only one of --32|--64 may be specified"
		fi
		_host_arch=x86_64
		shift;
		;;
	-*)
		echo "${0}: unknown argument ${1}";
		__show_help;
		exit 1;
		;;
	*)	break ;;
	esac
done

declare -ar argv=(${0} ${@})
declare -ir argc=$(( $# + 1 ))

# Show help if no commands are given
if ! defined argv[1] || ! defined argv[2]
then
	__show_help;
	exit 1;
fi


################################################################################
#
# System checks
#
################################################################################

#****** Cygport/Configuration
#****

#****** Cygport/Format
#  INTRODUCTION
#  If the .cygport file defines NAME, VERSION, and RELEASE, the filename may
#  be anything, but is conventionally NAME.cygport.  Otherwise, the filename
#  must be in the form NAME-VERSION-RELEASE.cygport, and the values of NAME,
#  VERSION, and RELEASE will be determined automatically.
#
#  A .cygport file must conform to bash shell syntax.  Comments may be included,
#  beginning with '#' until end-of-line; all comments are ignored during
#  execution of cygport.
#
#  Since a .cygport file is itself not a functioning script, the she-bang
#  header (#!/bin/bash) should be omitted, and the file should not be executable.
#
#  The bare minimum for a working .cygport file includes a SRC_URI definition,
#  and src_compile and src_install functions.  Note that several Cygclasses
#  provide some or all of these, so in some cases a single line inherit
#  command will suffice.
#****

#****** Cygport/Information
#****

### import check_prog and friends
source ${_privlibdir}/check_funcs.cygpart
###

# check now for all mandatory programs
for _myprog in bzip2 cat chmod cp diff diffstat dos2unix file find gawk grep gzip \
               install ln mkdir mv patch rm rsync sed sort tar xargs which xz
do
	if ! check_prog ${_myprog}
	then
		error "${_myprog} is required to run cygport";
	fi
done

unset _myprog;

if check_prog pbzip2
then
	readonly _tar_bz2_flag="-I pbzip2 -"
else
	# bzip2 is required, no need to check
	readonly _tar_bz2_flag="-j"
fi


################################################################################
#
# Import user settings
#
################################################################################

# Values which can be overridden either system-wide or per package

declare    MAKEOPTS="-j$(($(nproc 2>/dev/null) + 1)) ";

# load configuration
for conf in ${_sysconfdir}/cygport.conf \
			"${HOME}/.cygportrc" \
			"${HOME}/.cygport.conf" \
			"${HOME}/.cygport/cygport.conf"
do
	if [ -e "${conf}" ]
	then
		source "${conf}" || error "could not read ${conf}"
	fi
done
unset conf;


################################################################################
#
# Function definitions
#
################################################################################

#****** Cygport/Downloading
#****

#****** Cygport/Preparation
#****

#****** Cygport/Checks
#****

#****** Cygport/Compiling
#****

#****** Cygport/Testing
#****

#****** Cygport/Installing
#  NOTE
#  In the context of cygport, "installing" always means into the DESTDIR $D.
#  However, the syntax of the convenience functions is as if one were
#  installing to the system.
#****

#****** Cygport/Postinstall
#****

#****** Cygport/Packaging
#  INTRODUCTION
#  In most cases, only one binary package is created from a source package,
#  including all files installed into $D.  This is the default, and if
#  this applies to your package, the rest of this section is irrelevant.
#
#  However, there are many cases -- often with library packages -- that it
#  is desirable to create multiple binary packages from one source.
#  cygport makes that very easy, by defining the variables described in this
#  section.
#****

#****** Cygport/Cygclasses
#  DESCRIPTION
#  Cygclasses serve as cygport's standard library, allowing cygport to support
#  so many different types of packaging scenarios.  They may accept variables
#  to control their behaviour, provide definitions and/or functions for use in
#  .cygport files, and some can completely control the build process without
#  further intervention.
#
#  Cygclasses are imported via the inherit command at the top of your .cygport
#  file.  Because of the predominance of GNU autotools, the autotools.cygclass
#  is automatically imported (as explained there).
#
#  These Cygclasses allow downloading from various servers and repositories:
#  * bzr.cygclass -
#    For downloading sources from Bazaar repositories.
#  * cvs.cygclass -
#    For downloading sources from CVS repositories.
#  * fossil.cygclass -
#    For downloading sources from Fossil repositories.
#  * git.cygclass -
#    For downloading sources from Git repositories.
#  * gnome.org.cygclass -
#    For downloading sources from GNOME mirrors.
#  * hg.cygclass -
#    For downloading sources from Mercurial repositories.
#  * mtn.cygclass -
#    For downloading sources from Monotone repositories.
#  * svn.cygclass -
#    For downloading sources from Subversion repositories.
#
#  These Cygclasses handle various buildsystems:
#  * ant.cygclass -
#    For Java packages which use the Ant buildsystem.
#  * autotools.cygclass -
#    For packages using the autoconf/automake/libtool buildsystem.
#  * cmake.cygclass -
#    For packages using the CMake buildsystem.
#  * nant.cygclass -
#    For Mono packages which use the NAnt buildsystem.
#  * qt3-qmake.cygclass -
#    For packages which depend on Qt 3.x and use the qmake buildsystem.
#  * qt4-cmake.cygclass -
#    For packages which depend on Qt 4.x and use the CMake buildsystem.
#  * qt4-qconf.cygclass -
#    For packages which depend on Qt 4.x and use the QConf buildsystem.
#  * qt4-qmake.cygclass -
#    For packages which depend on Qt 4.x and use the qmake buildsystem.
#  * qt5-qmake.cygclass -
#    For packages which depend on Qt 5.x and use the qmake buildsystem.
#  * waf.cygclass -
#    For packages which use the Waf buildsystem.
#
#  These Cygclasses deal with certain types of dependencies:
#  * fox.cygclass -
#    For packages which depend on the FOX Toolkit.
#  * java.cygclass -
#    For packages which depend on Java.
#  * pypy.cygclass -
#    For packages which depend on PyPy.
#  * python.cygclass -
#    For packages which depend on Python 2.x.
#  * python3.cygclass -
#    For packages which depend on Python 3.x.
#  * qt3.cygclass -
#    For packages which depend on Qt 3.x.
#  * qt4.cygclass -
#    For packages which depend on Qt 4.x.
#  * qt5.cygclass -
#    For packages which depend on Qt 5.x.
#  * tcl.cygclass -
#    For packages which depend on Tcl.
#  * wxwidgets.cygclass -
#    For packages which depend on wxWidgets.
#
#  These Cygclasses are used for packaging desktop software components:
#  * gnome2.cygclass -
#    For GNOME 2.x/3.x packages.
#  * gnustep.cygclass -
#    For GNUstep packages.
#  * kde4.cygclass -
#    For KDE 4.x packages.
#  * mate.cygclass -
#    For MATE Desktop packages.
#  * rox.cygclass -
#    For ROX Desktop packages.
#  * sugar.cygclass -
#    For Sugar Desktop packages.
#  * xfce4.cygclass -
#    For Xfce Desktop packages.
#
#  These Cygclasses are used for packaging specific groups of software:
#  * apache2.cygclass -
#    For Apache 2.x DSO packages.
#  * aspell-dict.cygclass -
#    For Aspell dictionary packages.
#  * claws-mail.cygclass -
#    For Claws Mail plugin packages.
#  * docbook.cygclass -
#    For packaging DocBook SGML/XML DTDs.
#  * ebook.cygclass -
#    For packaging HTML Help Books for viewing in DevHelp.
#  * gst-plugins.cygclass -
#    For GStreamer plugin packages.
#  * gstreamer.cygclass -
#    For GStreamer core packages.
#  * gtk2-perl.cygclass -
#    For Perl bindings of GTK+/GNOME libraries.
#  * gtkmm.cygclass -
#    For GTKmm C++ bindings of GTK+/GNOME libraries.
#  * pygtk.cygclass -
#    For Python bindings of GTK+/GNOME libraries.
#  * texlive.cygclass -
#    For TeX Live packages.
#  * xorg.cygclass -
#    For X.Org X11 components.
#
#  These Cygclasses are used for building extension modules for various subsystems:
#  * lua.cygclass -
#    For packages which depend on Lua or provide Lua modules.
#  * mono.cygclass -
#    For packages which depend on Mono or provide Mono assemblies.
#  * ocaml.cygclass -
#    For packages which depend on OCaml or provide OCaml libraries.
#  * octave.cygclass -
#    For packages which depend on Octave or provide Octave modules.
#  * perl.cygclass -
#    For packages which depend on Perl or provide Perl (CPAN) modules.
#  * php.cygclass -
#    For packages which depend on PHP or provide PHP (PEAR/PECL) modules.
#  * pypy-distutils.cygclass -
#    For PyPy packages which use the Distutils buildsystem.
#  * python-distutils.cygclass -
#    For Python 2.x packages which use the Distutils buildsystem.
#  * python3-distutils.cygclass -
#    For Python 3.x packages which use the Distutils buildsystem.
#  * R.cygclass -
#    For packages which depend on R or provide R modules.
#  * ruby.cygclass -
#    For packages which depend on Ruby or provide non-gem Ruby modules.
#  * rubygem.cygclass -
#    For Ruby modules which use the RubyGems buildsystem.
#
#  These Cygclasses deal with compiler and cross-compiler toolchains:
#  * clang.cygclass -
#    For using Clang as a compiler instead of GCC.
#  * cross.cygclass -
#    For packaging libraries to be used with cross-compiler toolchains.
#  * multilib.cygclass -
#    For packaging libraries for cross-compiler toolchains which support
#    multiple ABIs.
#  * toolchain.cygclass -
#    For creating compilers and cross-compilers (binutils, gcc, gdb, newlib).
#
#  These Cygclasses provide install commands for certain types of data:
#  * emacs.cygclass -
#    For manual installation of Emacs modes.
#  * font.cygclass -
#    For manual installation of fonts.
#  * vim.cygclass -
#    For manual installation of Vim macros.
#
#  These Cygclasses provide utility functions:
#  * utils.cygclass -
#    Assorted checking functions.
#  * xvfb.cygclass -
#    For executing commands which require a running X server.
#
#  The following Cygclasses are deprecated and should not be used in new code:
#  * apache.cygclass
#  * berkdb.cygclass
#  * distutils.cygclass
#  * distutils-multi.cygclass
#  * ggz.cygclass
#  * opensync.cygclass
#  * ruby-gnome2.cygclass
#****

### __config_get/set and friends
source ${_privlibdir}/config_registry.cygpart
###

### inherit and friends
source ${_privlibdir}/inheritance.cygpart
###

### fetch and friends
source ${_privlibdir}/src_fetch.cygpart
###

### mirrors list
source ${_privdatadir}/mirrors
###

### unpack, cygpatch, __src_prep and friends
source ${_privlibdir}/src_prep.cygpart
###

### CC/CXX, CFLAGS/CXXFLAGS, etc.
source ${_privlibdir}/compilers.cygpart
###

### lndirs, cygmake
source ${_privlibdir}/src_compile.cygpart
###

### cygtest and friends
source ${_privlibdir}/src_test.cygpart
###

### cyginstall, do*, new*, *into, and friends
source ${_privlibdir}/src_install.cygpart
###

### __src_postinst and friends
source ${_privlibdir}/src_postinst.cygpart
###

### __list_files, __show_deps, __show_info, __show_web
source ${_privlibdir}/pkg_info.cygpart
###

### __pkg_* functions
source ${_privlibdir}/pkg_pkg.cygpart
###

### __finish
source ${_privlibdir}/pkg_cleanup.cygpart
###

# Auto-inherit autotools for backwards compatibility. But we
# want to allow it to be inherited one more time in order to
# reset src_compile() when other cygclasses override it.
_autotools_CYGCLASS_stage1_=1
inherit autotools;
unset _autotools_CYGCLASS_ _autotools_CYGCLASS_stage1_


################################################################################
#
# Import the .cygport file
#
################################################################################

#****** Format/Globals
#****

#****v* Globals/NAME
#  DESCRIPTION
#  The Cygwin (primary) package name.  Generally, this is the same as the
#  upstream package name, but need not be.  A common reason for deviating from
#  the upstream name is to append a version "slot" where multiple versions of
#  a package are completely parallel installable (e.g. gtk1.2 and gtk2.0, both
#  from gtk+).  In this case, define ORIG_PN to the upstream package name.
#****
#****v* Globals/VERSION
#  DESCRIPTION
#  The upstream package version number.  PV must begin with a digit 0-9, and
#  subsequent characters can be a digit, letter, dot, hyphen, or underscore.
#****
#****v* Globals/RELEASE
#  DESCRIPTION
#  The Cygwin package release number, e.g. the "1" in foo-2.3.4-1.  The first
#  release of a new version is usually 1, and is incremented if subsequent
#  releases are made of the same version.  PR must be an integer.
#****
#****d* Globals/PN
#  DESCRIPTION
#  A read-only alias for NAME.
#****
#****d* Globals/PV
#  DESCRIPTION
#  A read-only alias for VERSION.
#****
#****d* Globals/PR
#  DESCRIPTION
#  A read-only alias for RELEASE.
#****
#****d* Globals/P
#  DESCRIPTION
#  A read-only alias for NAME-VERSION (PN-PV).
#****
#****d* Globals/PVR
#  DESCRIPTION
#  A read-only alias for VERSION-RELEASE (PV-PR).
#****
#****d* Globals/PF
#  DESCRIPTION
#  A read-only alias for NAME-VERSION-RELEASE (PN-PV-PR).
#****

unset NAME VERSION RELEASE
if [ -f ${argv[1]} ]
then
	eval $(grep '^NAME=' ${argv[1]})
	eval $(grep '^VERSION=' ${argv[1]})
	eval $(grep '^RELEASE=' ${argv[1]})
fi

if [ "${NAME+y}${VERSION+y}${RELEASE+y}" = "yyy" ]
then
declare -r  PN=${NAME}
declare     PV=${VERSION}
declare -r  PR=${RELEASE}
declare -r  PF=${PN}-${PV}-${PR}
declare -r  cygportfile=${argv[1]##*/}
else
# file must be named PN-PV-PR.cygport, but the extension is optional in argv[1]
            PF=${argv[1]##*/}
declare -r  PF=${PF%.cygport}
declare -r  PN=${PF%%-[0-9]*};
declare     NAME=${PN}
declare -r  PR=${PF##*-};
declare     RELEASE=${PR}
            PV=$(echo ${PF} | sed -e "s/${PN}\-\(.*\)\-${PR}$/\1/");
declare     VERSION=${PV}
declare -r  cygportfile=${PF}.cygport;
fi

# these must be defined now to be available in SRC_URI
declare -r  P=${PN}-${PV};
declare -r  PVR=${PV}-${PR};
declare -ar PVP=(${PV//[-\._]/ });
declare -r  PV=(${PV} ${PVP[*]});
declare -r  PV_MAJ=${PV[1]};
declare -r  PV_MAJ_MIN="${PV[1]}.${PV[2]}";

_topdir=${argv[1]%/*};

if [ "x${_topdir}" = "x${argv[1]}" ]
then
	if [ -f ./${cygportfile} ]
	then
		_topdir=.;
	else
		_topdir=/usr/src;
	fi
fi

declare -r top=$(cd ${_topdir}; pwd);
unset _topdir;

if [ ! -e ${top}/${cygportfile} ]
then
	error "${cygportfile} not found.";
fi

### load .cygport
source ${top}/${cygportfile} || error "could not read ${cygportfile}"
###

case ${ARCH} in
${CHOST%%-*}|noarch) ;;
*)  error "This package may only be built for ${ARCH}"
esac

if defined CYGPORT_DEPEND
then
	if ! __version_at_least ${CYGPORT_DEPEND} ${_version}
	then
		error "This package requires cygport ${CYGPORT_DEPEND} or newer";
	fi
fi


for restrict in ${RESTRICT//,/ }
do
	declare _CYGPORT_RESTRICT_${restrict//-/_}_=1
done
unset restrict


################################################################################
#
# Define package-dependant variables
#
################################################################################

declare -r workdir="${top}/${PF}";
declare -r srcdir="${workdir}/src";
declare -r origsrcdir="${workdir}/origsrc";
declare -r configdir="${workdir}/config";
declare -r logdir="${workdir}/log";
declare -r patchdir="${workdir}/patch";
declare -r spkgdir="${workdir}/spkg";
declare -r distdir="${workdir}/dist";

SRC_DIR=${SRC_DIR:-${ORIG_PN:-${PN}}-${PV}};
if [ "x${SRC_DIR}" = "x." ]
then
	declare -r S=${srcdir};
else
	declare -r S=${srcdir}/${SRC_DIR};
fi

#****d* Globals/S
#  DESCRIPTION
#  The source directory.  Build tool regeneration (e.g. cygautoreconf) occurs
#  in this directory, but other build steps should occur in B.
#****

#****d* Globals/B
#  DESCRIPTION
#  The build directory.  All configuring and compiling steps should occur in
#  this directory.
#****

#****d* Globals/C
#  DESCRIPTION
#  The CYGWIN-PATCHES directory where Cygwin READMEs, setup.hint files,
#  custom postinstall scripts, and other Cygwin-specific files are placed
#  before packaging.
#****

#****d* Globals/D
#  DESCRIPTION
#  The installation staging directory.  All installation and postinstall steps
#  occur in or into this directory.
#****

declare -r B="${workdir}/build";
declare -r D="${workdir}/inst";
declare -r T="${workdir}/temp";
declare -r C="${S}/CYGWIN-PATCHES";

declare -r compilelog="${logdir}/${PF}-compile.log";
declare -r checklog="${logdir}/${PF}-check.log";
declare -r installlog="${logdir}/${PF}-install.log";
declare -r pkglog="${logdir}/${PF}-pkg.log";

if ! defined SRC_URI
then
	error "SRC_URI must be defined";
fi

for _src_uri in ${SRC_URI}
do
	_src_uri="${_src_uri%\?*}"
	_src_orig_pkgs+=" ${_src_uri##*/}";
done
readonly _src_orig_pkgs;
unset _src_uri;

for _patch_uri in ${PATCH_URI}
do
	_patch_uri="${_patch_uri%\?*}"
	_src_orig_patches+=" ${_patch_uri##*/}";
done
readonly _src_orig_patches;
unset _patch_uri;

declare -r cygwin_patchfile=${PF}.cygwin.patch;
declare -r src_patchfile=${PF}.src.patch;

declare -ar pkg_name=(${PKG_NAMES:-${PN}});
declare -r  pkg_count=${#pkg_name[*]};

# this requires S and B to be already defined
if ! defined _CYGPORT_RESTRICT_debuginfo_
then
	for flags in {C,CXX,F,FC,GCJ,GO,OBJC,OBJCXX}FLAGS
	do
		for map in ${DEBUG_PREFIX_MAPS[*]}
		do
			declare ${flags}+=" -fdebug-prefix-map=${map}=/usr/src/debug/${PF}"
		done
		declare ${flags}+=" -fdebug-prefix-map=${B}=/usr/src/debug/${PF}"
		declare ${flags}+=" -fdebug-prefix-map=${S}=/usr/src/debug/${PF}"
	done
	unset flags map
fi

################################################################################
#
# Command processing
#
################################################################################

declare -i arg_n=2

# When adding commands here, also add them to cygport-bash-completion
while (( arg_n < argc ))
do
	case ${argv[${arg_n}]} in
		downloadall|fetchall|wgetall|getall)
			__src_fetch;
			_status=$?;
			;;
		download|fetch|wget|get)
			__DL_ONLY_MISSING=1 __src_fetch;
			_status=$?;
			;;
		prep|unpack)
			__stage Preparing;
			__src_prep;
			_status=$?;
			;;
		compile|build|make)
			__stage Compiling;
			__log_init ${compilelog};
			__check_depends && \
			src_compile 2>&1 | tee -a ${compilelog};
			_status=$?;
			;;
		check|test)
			__stage Testing;
			__log_init ${checklog};
			src_test 2>&1 | tee -a ${checklog};
			_status=$?;
			;;
		inst*)
			__stage Installing;
			__log_init ${installlog};
			(__prepinstalldirs && src_install && __src_postinst) 2>&1 | tee -a ${installlog};
			_status=$?;
			;;
		postinst*)
			__src_postinst;
			_status=$?;
			;;
		list)
			__list_files;
			_status=$?;
			;;
		listdebug*|listdbg*)
			__list_debug_files;
			_status=$?;
			;;
		dep*)
			__show_deps;
			_status=$?;
			;;
		info*)
			__show_info;
			_status=$?;
			;;
		homepage|web*|www*)
			__show_web;
			_status=$?;
			;;
		package|pkg)
			__stage Packaging;
			__log_init ${pkglog};
			(__pkg_binpkg && __pkg_pkgcheck && __pkg_srcpkg && __pkg_dist) 2>&1 | tee -a ${pkglog};
			_status=$?;
			;;
		diff|mkdiff|mkpatch)
			__pkg_diff;
			_status=$?;
			;;
		clean|finish)
			__finish;
			_status=$?;
			;;
		almostall|all)
			__stage Preparing && __src_prep && \
			__log_init ${compilelog} && \
			__check_depends && \
			__stage Compiling && src_compile 2>&1 | tee -a ${compilelog} && \
			__log_init ${installlog} && \
			__stage Installing && (__prepinstalldirs && src_install && __src_postinst) 2>&1 | tee -a ${installlog} && \
			__log_init ${pkglog} && \
			__stage Packaging && (__pkg_binpkg && __pkg_pkgcheck && __pkg_srcpkg && __pkg_dist) 2>&1 | tee -a ${pkglog}
			_status=$?;
			;;
		help)
			__show_help;
			exit 0;
			;;
		version)
			__show_version;
			exit 0;
			;;
		_*)
			error "unknown command ${argv[${arg_n}]}";
			exit 1;
			;;
		*)
			if __check_function ${argv[${arg_n}]} && ! __check_function_ro ${argv[${arg_n}]}
			then
				${argv[${arg_n}]};
			else
				error "unknown command ${argv[${arg_n}]}";
			fi
			_status=$?;
			;;
	esac

	if (( _status != 0 ))
	then
		break;
	fi

	arg_n+=1;
done

exit ${_status};
