/* ********************************************************************* 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];;