/* *********************************************************************
This source file is a part of the standard library of Scol
For the latest info, see http://www.scolring.org
Copyright (c) 2013 Stephane Bisaro aka Iri.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
This program 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt
********************************************************************* */
/*
* Functions for packages
* See http://redmine.scolring.org/projects/tutorials/wiki/Scol_usage
* for more informations
*/
/*! \file pkg.pkg
* \author Scol team
* \version 0.1
* \copyright GNU Lesser General Public License 2.0 or later
* \brief Scol Packages Library - Packages in package API
*
**/
/*! \brief Remove the N last loaded packages in a given channel.
*
* \remark These packages are not released in memory.
*
* \ingroup pkgs_pkg
* Prototype : fun [Chn I] I
*
* \param Chn : a channel (like _channel)
* \param I : the number of packages to remove
* \return I : 0 if success, other thing if an error occurs
**/
fun pkgs_pkgRemoveNLast (chn, n)=
if chn == nil then nil
else
let _envchannel chn -> env in
(
while n > 0 do
(//_fooId n;
set env = _removepkg env;
if env != nil then
set n = n-1
else
set n = 0
);
_setenv chn env
);;
fun pkgs_pkgRemoveRecursive2 (env, cbfun)=
if env == nil then
exec cbfun with [env nil]
else
if 0 == exec cbfun with [env _envfirstname env] then
0
else
pkgs_pkgRemoveRecursive2 _removepkg env cbfun;;
/*! \brief Remove some last packages in a given channel to apply a callback.
*
* Only if the callback returns 0, the recursion stops. Else, the recursion
* continues until all packages are removed.
*
* \ingroup pkgs_pkg
* Prototype : fun [Chn fun [Env S] I] I
*
* \param Chn : a channel (like _channel)
* \param fun [Env S] I : the callback. It must return an integer (I).
* Its arguments are :
* - Env : the new environment (so, without the laready removed packages)
* - S : the last package name still loaded in this environment. If the
* environment is nil (all packages has been removed), this argument is nil too.
* \return I : always the return of the callback.
**/
fun pkgs_pkgRemoveRecursive (chn, cbfun)=
if chn == nil then nil
else pkgs_pkgRemoveRecursive2 _envchannel chn cbfun;;
/*! \brief Test a package in the current channel next call a function.
*
* \ingroup pkgs_pkg
* Prototype : fun [P fun [I P S] u0] u0
*
* \param P : a read-file reference
* \param fun [I P S] u0 : the function to call.
* Its arguments are :
* - I : 0 if no error, 2 if the file is invalid, incorrect or corrupted, else 1
* - P : the given read-file reference
* - S : the returned error or nil if no error
* \return u0 : always the return of the called function.
**/
fun pkgs_pkgTest (pPkgName, cbfun)=
if pPkgName == nil then
exec cbfun with [2 nil nil]
else
let _PtoScol pPkgName -> pkgName in
let _testpak pkgName -> s in
let if s == nil then 0 else 1 -> err in
exec cbfun with [err pPkgName s];;
/*! \brief Test a Scol code in the current channel next call a function.
*
* \ingroup pkgs_pkg
* Prototype : fun [S fun [I S S] u0] u0
*
* \param S : a code string
* \param fun [I S S] u0 : the function to call.
* Its arguments are :
* - I : 0 if no error, else 1
* - S : the given code
* - S : the returned error or nil if no error
* \return u0 : always the return of the called function.
**/
fun pkgs_pkgTestS (szCode, cbfun)=
let _testpakS szCode -> s in
let if s == nil then 0 else 1 -> err in
exec cbfun with [err szCode s];;
var PKGS_PKG_SAFE = 1;;
var PKGS_PKG_UNSAFE = 0;;
/*! \brief Load a package in the current channel.
*
* The loading can be safe : in this case, the package is checked
* before to be loaded.
*
* \ingroup pkgs_pkg
* Prototype : fun [S I] [I S]
*
* \param S : a filename of a package
* \param I : a flag : PKGS_PKG_SAFE to have a safe loading, PKGS_PKG_UNSAFE
* (or any other value) to have an unsafe loading.
* \return [I S] : a tuple :
* - I : 0 if success, other value else
* - S : always nil if success, the string error if error (only with PKGS_PKG_SAFE flag)
**/
fun pkgs_pkgLoadSafe (fPkg, iFlag)=
if iFlag == PKGS_PKG_SAFE then
let _testpak fPkg -> szRes in
if szRes == nil then
[_load fPkg nil]
else
[nil szRes]
else
[_load fPkg nil];;
/*! \brief Load a package in the current channel.
*
* The loading can be safe : in this case, the package is checked
* before to be loaded.
*
* \ingroup pkgs_pkg
* Prototype : fun [P I] [I S]
*
* \param P : a read package reference
* \param I : a flag : PKGS_PKG_SAFE to have a safe loading, PKGS_PKG_UNSAFE
* (or any other value) to have an unsafe loading.
* \return [I S] : a tuple :
* - I : 0 if success, other value else
* - S : always nil if success, the string error if error (only with PKGS_PKG_SAFE flag)
**/
fun pkgs_pkgLoadSafeP (pPkg, iFlag)=
if pPkg == nil then
[nil nil]
else
let _PtoScol pPkg -> fPkg in
if iFlag == PKGS_PKG_SAFE then
let _testpak fPkg -> szRes in
if szRes == nil then
[_load fPkg nil]
else
[nil szRes]
else
[_load fPkg nil];;
/*! \brief Load a Scol code string in the current channel.
*
* The loading can be safe : in this case, the code is checked
* before to be loaded.
*
* \ingroup pkgs_pkg
* Prototype : fun [S I] [I S]
*
* \param S : a Scol code
* \param I : a flag : PKGS_PKG_SAFE to have a safe loading, PKGS_PKG_UNSAFE
* (or any other value) to have an unsafe loading.
* \return [I S] : a tuple :
* - I : 0 if success, other value else
* - S : always nil if success, the string error if error (only with PKGS_PKG_SAFE flag)
**/
fun pkgs_pkgLoadCode (szCode, iFlag)=
if iFlag == PKGS_PKG_SAFE then
let _testpakS szCode -> szRes in
if szRes == nil then
[_loadS szCode nil]
else
[nil szRes]
else
[_loadS szCode nil];;