/* *********************************************************************
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
********************************************************************* */
/*
* Standard functions for errors and customized log files
* See http://redmine.scolring.org/projects/tutorials/wiki/Scol_usage
* for more informations
*/
/*! \file error.pkg
* \author Scol team
* \version 0.2
* \warning This API requires sprintf, currently in Syspack Scol library.
* \warning To use it with the Console library (lib/console), this API requires
* too the lib/console/console.pkg package.
* \copyright GNU Lesser General Public License 2.0 or later
* \brief Scol Standard Library - Error API
*
* \details This API provides an high level method to easily include a customized error manager
*
* You can :
* - define your masks yourself
* - enabled / disabled this manager
* - define your code numbers and messages error
* - write - or not - in the Scol console
* - use a hard file log or a temporary file log
* - and more things yet
*
* It is NOT recommanded to use the internal STD_ERROR structure to any application.
* Use this API instead.
*
**/
/*! \struct STD_ERROR
*
* \brief Opaque internal structure. You should not call it directly, use
* API instead !
*
**/
struct STD_ERROR = [
StdErrMask : I, /*!< current mask. If this mask and the message mask are OK, the message will be written */
StdErrMaskLast : I, /*!< last mask set, to allow an 'undo' */
StdErrPeriod : I, /*!< not used */
StdErrEnabled : I, /*!< object is enabled (1) or disabled (0) */
StdErrTmp : I, /*!< 1 for a temporary log file else 0 (regular file) */
StdErrTmpFile : FileTemp, /*!< if Temporary file asked (1) */
StdErrFilename : W, /*!< Physical file of Logfile object */
StdErrLast : [I S], /*!< Last message printed (number and string) */
StdErrFoo : I, /*!< Write (1) or no (0) the message in the Scol console (_fooXXX functions) */
StdErrConsole : I, /*!< Show (1) or hide (0) the console */
StdErrTypes : [[I S] r1]/*!< list of customized errors (code error and string) */
] mkSTD_ERROR;;
/*! \var StdErrList
* List of all managers created. No use directly **/
typeof StdErrList = [STD_ERROR r1];;
/* set the cursor to the end of the file */
fun std_errsettemptoend (err)=
_FILESeekTemp err.StdErrTmpFile 0 SEEK_END;;
/* fun [S] W */
fun std_errcheckfilename (filename)=
// _getmodifypack if std_szCheckLastChar filename "/" then filename else strcat filename "/";;
_getmodifypack filename;;
/*! \brief Open a new manager
* By default, the manager is ENABLED, the console message and the console are disabled.
* Other parameters are at nil
*
* \ingroup std_error
*
* Prototype: fun [I] STD_ERROR
*
* \param I : a mask
*
* \return STD_ERROR : the new manager object
**/
fun std_errOpen (mask)=
let mkSTD_ERROR [nil nil nil nil nil nil nil nil nil nil nil] -> s in
(
set s.StdErrMask = mask;
set s.StdErrEnabled = 1; // enabled by default
set s.StdErrFoo = 0; // console message disabled by default
set s.StdErrConsole = 0; // hide the console by default
set s.StdErrTmp = 0; // hard log file
set StdErrList = s :: StdErrList;
s
);;
/* create a new temporary log file and write into a first string.
* The cursor is set to the end */
fun std_errnewtemp (err, str)=
if nil == set err.StdErrTmpFile = _FILEOpenTemp _channel then
nil
else
(
_FILEWriteTemp err.StdErrTmpFile str;
std_errsettemptoend err;
err
);;
/*! \brief Open a new log file
* The current date is written.
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR S] STD_ERROR
*
* \param STD_ERROR : a manager object
* \param S : a filename for the log file if the TMPFILE is disabled
* if TMPFILE is enabled, this argument is ignored and could be nil.
*
* \remark if any, the current file is overwritten.
*
* \return STD_ERROR : the same manager object or nil if error
**/
fun std_errOpenLog (err, filename)=
if err == nil then
nil
else
let gmtime time -> [sec mn h d m y _ _] in
let sprintf "Date : %i %i, %i - %ih %imn %isec\n" [y m d h mn sec] -> str in
(
if 1 == err.StdErrTmp then
std_errnewtemp err str
else
if filename == nil then
nil
else
(
// set filename = _getmodifypack if std_szCheckLastChar filename "/" then filename else strcat filename "/";
let std_errcheckfilename filename -> w in
if !_createpack str w then
(
set err.StdErrFilename = w;
err
)
else
nil
)
);;
// _createpack sprintf "Date : %i %i, %i% - %ih %imn %isec\n" [y m d h mn sec] filename;
// _openlog filename err.StdErrMask period;
/*! \brief Open a new log file. The filename is the current date and time
* with a prefix : my_folder/the_prefix_2013_12_14-17_25_21.log
* The current date is written.
* The TMPFILE must be disabled.
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR S] STD_ERROR
*
* \param STD_ERROR : a manager object
* \param S : a filename for the log file such as "my_folder/the_prefix"
*
* Note : if any, the current file is overwritten.
*
* \return STD_ERROR : the same manager object or nil if error (manager
* is nil or TMPFILE enabled)
**/
fun std_errOpenLogNow (err, name)=
if ((err == nil) || (err.StdErrTmp)) then
nil
else
(
// set name = if name == nil then "Logs/noname" else if std_szCheckLastChar name "/" then name else strcat name "/";
set name = if name == nil then
"Logs/noname"
else
let strfindi ".log" name 0 -> pos in
if pos == nil then name else substr name 0 pos;
let gmtime time -> [sec mn h d m y _ _] in
let sprintf "Date : %i %i, %i - %ih %imn %isec\n" [y m d h mn sec] -> msg in
let sprintf "%s_%i_%i_%i-%i_%i_%i.log" [name y m d h mn sec] -> filename in
std_errOpenLog err filename
);;
/*! \brief Close a manager. If TMPFILE is enabled, the temporary file is
* closed and its content is lost.
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] I
*
* \param STD_ERROR : a manager object
* \param S : a filename for the log file
*
* \return I : 0 if success, 1 if the manager is already closed (or not created),
* 2 if the temporary file can not be closed correctly
**/
fun std_errClose (err)=
if err == nil then
1
else
let 0 -> r in
(
if err.StdErrTmp then
if !_FILECloseTemp err.StdErrTmpFile then
set r = r+2
else
0
else
0;
set StdErrList = std_lRemoveElt StdErrList err;
set err = nil;
r
);;
/*! \brief Open a new manager in copying the configuration of another one.
*
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR S] STD_ERROR
*
* \param STD_ERROR : a manager object
* \param S : a filename for the log file or nil if a temporary file is prefered
*
* Note : if any, the current file is overwritten.
*
* \return STD_ERROR : the new manager object or nil if error
**/
fun std_errCopy (err, filename)=
if err == nil then
nil
else if ((!err.StdErrTmp) && (filename == nil)) then
nil
else
let mkSTD_ERROR [nil nil nil nil nil nil nil nil nil nil nil] -> s in
(
set s.StdErrMask = err.StdErrMask;
set s.StdErrMaskLast = err.StdErrMaskLast;
set s.StdErrPeriod = err.StdErrPeriod;
set s.StdErrEnabled = err.StdErrEnabled;
set s.StdErrTmp = err.StdErrTmp;
set s.StdErrFoo = err.StdErrFoo;
set s.StdErrTypes = err.StdErrTypes;
// set filename = _getmodifypack if std_szCheckLastChar filename "/" then filename else strcat filename "/";
let std_errcheckfilename filename -> w in
let gmtime time -> [sec mn h d m y _ _] in
let sprintf "Date : %i %i, %i% - %ih %imn %isec\n" [y m d h mn sec] -> str in
if 1 == err.StdErrTmp then
std_errnewtemp s str
else
if !_createpack str w then
(
set s.StdErrFilename = w;
s
)
else
nil
);;
/*! \brief Returns the current mask of a manager
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] I
*
* \param STD_ERROR : a manager object
*
* \return I : the current mask or nil if error
**/
fun std_errGetMask (err)=
err.StdErrMask;;
/*! \brief Set the current mask of a manager
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR I] STD_ERROR
*
* \param STD_ERROR : a manager object
* \param I : the new mask to set
*
* \return STD_ERROR : the current manager or nil if error
**/
fun std_errSetMask (err, mask)=
set err.StdErrMaskLast = err.StdErrMask;
set err.StdErrMask = mask;
err;;
/*! \brief Perform an 'undo' to the mask of a manager
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] I
*
* \param STD_ERROR : a manager object
*
* \return STD_ERROR : the same manager or nil if error
**/
fun std_errUndoMask (err)=
if err == nil then
nil
else
let err.StdErrMask -> mask in
(
set err.StdErrMask = err.StdErrMaskLast;
set err.StdErrMaskLast = mask;
err
);;
/*! \brief Get the period. Period is unused, so this function is unused too !
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] I
*
* \param STD_ERROR : a manager object
*
* \return I : the manager period or nil if error
**/
fun std_errGetPeriod (err)=
err.StdErrPeriod;;
/*! \brief Returns the path of the log file of a manager
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] S
*
* \param STD_ERROR : a manager object
*
* \return S : the path or nil if error (by example, a temporary file is used)
**/
fun std_errGetFilename (err)=
_PtoScol _WtoP err.StdErrFilename;;
/*! \brief Returns the current state of a manager
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] I
*
* \param STD_ERROR : a manager object
*
* \return I : 1 if this manager is enabled, 0 if disabled or nil if error
**/
fun std_errGetEnabled (err)=
err.StdErrEnabled;;
/*! \brief Set the current state of a manager
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR I] STD_ERROR
*
* \param STD_ERROR : a manager object
* \param I : the new state : 1 -> enabled, 0 to disable. Another value is ignored.
*
* \return STD_ERROR : the same manager or nil if error (manager is nil or bad value)
**/
fun std_errSetEnabled (err, state)=
if ((state) || (state == 0)) then
(
set err.StdErrEnabled = state;
err
)
else
nil;;
/*! \brief Returns if, for a manager, the message are displayed in the
* Scol console.
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] I
*
* \param STD_ERROR : a manager object
*
* \return I : 1, yes, 0, no or nil if error
**/
fun std_errGetFoo (err)=
err.StdErrFoo;;
/*! \brief Set if error message are displayed in the Scol console
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR I] STD_ERROR
*
* \param STD_ERROR : a manager object
* \param I : the new state : 1 -> enabled, 0 to disable. Another value is ignored.
*
* \return STD_ERROR : the same manager or nil if error (manager is nil or bad value)
**/
fun std_errSetFoo (err, state)=
if ((state) || (state == 0)) then
(
set err.StdErrFoo = state;
err
)
else
nil;;
/*! \brief Returns the last written message
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] [I S]
*
* \param STD_ERROR : a manager object
*
* \return [I S] : a tuple with the last code number and the last string
* or nil if error
**/
fun std_errGetLast (err)=
err.StdErrLast;;
/*! \brief Returns the content of the log file (for a manager)
* This can be a hard file or a temporary file.
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] S
*
* \param STD_ERROR : a manager object
*
* \return S : the content or nil if error
**/
fun std_errGetContent (err)=
if err == nil then
nil
else if err.StdErrTmp then
let (
_FILESeekTemp err.StdErrTmpFile SEEK_SET 0;
_FILEReadTemp err.StdErrTmpFile _FILESizeTemp err.StdErrTmpFile
) -> str in
(
std_errsettemptoend err;
str
)
else
_getpack _WtoP err.StdErrFilename;;
/*! \brief A conivience function.
* Save the content of the temporary file in a hard file
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR W] I
*
* \param STD_ERROR : a manager object
* \param W : a write reference path name to save the current datas
*
* \return I : 0 if success or nil or another value not null if error
**/
fun std_errSaveTemp (err, filename)=
if ((err != nil) || (err.StdErrTmp)) then
let (
_FILESeekTemp err.StdErrTmpFile SEEK_SET 0;
_FILEReadTemp err.StdErrTmpFile _FILESizeTemp err.StdErrTmpFile
) -> str in
_createpack str _getmodifypack filename
else
nil;;
/*! \brief Returns the list of defined eror types for a manager
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] [[I S] r1]
*
* \param STD_ERROR : a manager object
*
* \return [[I S] r1] : the list or nil if error
**/
fun std_errGetTypes (err)=
if err == nil then
nil
else
err.StdErrTypes;;
/*! \brief Returns the string error message for a given number code error
* (for a manager)
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR I] S
*
* \param STD_ERROR : a manager object
* \param I : an error code number
*
* \return S : this error message or nil if error
**/
fun std_errGetTypeFromNumber (err, number)=
switch err.StdErrTypes number;;
fun std_errgettypefromstring (list, str)=
if list == nil then
nil
else
let hd list -> [i s] in
if !strcmpi s str then
i
else
std_errgettypefromstring tl list str;;
/*! \brief Returns the number code error from a given string error message
* (for a manager)
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR S] I
*
* \param STD_ERRO] : a manager object
* \param S : a string error (case-insensitive)
*
* \return I : the error number or nil if error
**/
fun std_errGetTypeFromString (err, str)=
std_errgettypefromstring err.StdErrTypes str;;
/*! \brief Add a new predefined error in a manager
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR I S] STD_ERROR
*
* \param STD_ERROR : a manager object
* \param I : a new number error
* \param S : the appropriate message string
*
* \return STD_ERROR : the same manager or nil if error (manager is nil or number already existing)
**/
fun std_errAddType (err, num, str)=
if nil == std_errGetTypeFromNumber err num then
(
set str = if str == nil then "" else str;
set err.StdErrTypes = [num str] :: err.StdErrTypes;
err
)
else
nil;;
/*! \brief Reset all predefined error in a manager
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] STD_ERROR
*
* \param STD_ERROR : a manager object
*
* \return STD_ERROR : the same manager
**/
fun std_errClearTypes (err)=
set err.StdErrTypes = nil;
err;;
fun std_errremovetype (tuple, e)=
let tuple -> [n _] in
n == e;;
/*! \brief Remove a predefined error in a manager
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR I] STD_ERROR
*
* \param STD_ERROR : a manager object
* \param I : a number error to remove
*
* \return STD_ERROR : the same manager or nil if error
**/
fun std_errRemoveType (err, num)=
set err.StdErrTypes = std_lRemoveFunc err.StdErrTypes @std_errremovetype num;
err;;
/*! \brief Returns if a temporary file is used (for a manager)
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] I
*
* \param STD_ERROR : a manager object
*
* \return I : yes (1) or no (0) or nil if error
**/
fun std_errGetIsTemp (err)=
err.StdErrTmp;;
/*! \brief Set if a manager uses (or not) a temporary file.
* If the old and the new value are the same, no change is done.
* If the new value is 1 and the old value was 0, a new temporary file is
* created and the content of the old 'hard' file is copied in the new
* temporary file. The old 'hard' file is unchanged and no new message
* will be written.
* If the new file is 0 and the 'hard' file name is not nil, the file is
* created and the content of the old temporary file is copied. This last
* one is closed (and destroyed).
* All other configuration or an invalid argument will return a nil value.
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR I] STD_ERROR
*
* \param STD_ERROR : a manager object
* \param I : 1 to use a temporary file, else 0
* \param S : a filename (should be nil if the temporay file will be used)
*
* \return STD_ERROR : the same manager or nil if error
**/
fun std_errSetIsTemp (err, isTmp, filename)=
if isTmp == err.StdErrTmp then // no change to do
err
else if ((isTmp) && (!err.StdErrTmp)) then
(
set err.StdErrTmp = isTmp;
std_errnewtemp err _getpack _WtoP err.StdErrFilename
)
else if ((!isTmp) && (filename != nil)) then
(
// set filename = _getmodifypack if std_szCheckLastChar filename "/" then filename else strcat filename "/";
let std_errcheckfilename filename -> w in
let (
_FILESeekTemp err.StdErrTmpFile SEEK_SET 0;
_FILEReadTemp err.StdErrTmpFile _FILESizeTemp err.StdErrTmpFile
) -> str in
if !_createpack str w then
(
set err.StdErrFilename = w;
_FILECloseTemp err.StdErrTmpFile;
err
)
else
nil
)
else
nil;;
/*! \brief Returns if the Scol console is shown (for this manager)
* Only if this API manages the Scol console, if another code show
* or hide it, this return can be wrong.
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR] I
*
* \param STD_ERROR : a manager object
*
* \return I : show (1) or hide (0) or nil if error
**/
fun std_errGetConsole (err)=
err.StdErrConsole;;
/*! \brief Set the state of the Scol console
* if another code show or hide it, the effect can be different.
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR I] STD_ERROR
*
* \param STD_ERROR : a manager object
* \param I : 1 to show the Scol console, 0 to hide it.
*
* \return STD_ERROR : the same manager
**/
fun std_errSetConsole (err, state)=
if (state == err.StdErrConsole) then
err
else
(
if (set err.StdErrConsole = state) then
_showconsole
else
_hideconsole;
err
);;
fun std_errprint (err, num, str, mask)=
if err == nil then
1
else if !err.StdErrEnabled then
2
else if ((err.StdErrMask & mask)) then
3
else
let gmtime time -> [sec mn h d m y _ _] in
let sprintf "Date : %i %i, %i - %ih %imn %isec :\n" [y m d h mn sec] -> d in
//let strcatn d :: (itoa num) :: " " :: str :: "\n" :: nil -> s in
let sprintf "%s %i %s\n" [d num str] -> s in
(_fooS s;
if err.StdErrFoo then
_fooS s
else
nil;
if err.StdErrTmp then
if !_FILEWriteTemp err.StdErrTmpFile s then
(
std_errsettemptoend err;
set err.StdErrLast = [num str];
0
)
else
4
else
if !_appendpack s err.StdErrFilename then
(
set err.StdErrLast = [num str];
0
)
else
5
);;
/*! \brief Send a new string message error to a manager.
* According the manager settings, the string can be written in the Scol
* console, in the application log file if the client set it, in the
* customized log file, ...
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR S I] I
*
* \param STD_ERROR : a manager object
* \param S : the string message error
* \param I : a mask for this message. It is tested with the mask of the
* manager to determine wether the message should be written. If the test
* is positive, the message is immediatly written.
* Thus, the logical 'mask_of_manager & mask_of_this_message' must be not null
* to write the message.
*
* \return I : 0 if success, 1 if the manager is nil, 2 if the manager
* is disabled, 3 if the test is negative, 4 if the message can not be
* written in the temporary file, 5 if the message cannot be written in
* the 'hard' file.
**/
fun std_errString (err, str, mask)=
std_errprint err nil str mask;;
/*! \brief Send a predefined error to a manager.
* According the manager settings, the string can be written in the Scol
* console, in the application log file if the client set it, in the
* customized log file, ...
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR I I] I
*
* \param STD_ERROR : a manager object
* \param I : a predefined number error
* \param I : a mask for this message. It is tested with the mask of the
* manager to determine wether the message should be written. If the test
* is positive, the message is immediatly written.
* Thus, the logical 'mask_of_manager & mask_of_this_message' must be at not null
* to write the message.
*
* \return I : 0 if success, 1 if the manager is nil, 2 if the manager
* is disabled, 3 if the test is negative, 4 if the message can not be
* written in the temporary file, 5 if the message cannot be written in
* the 'hard' file or 6 if the number is not a predefined error.
**/
fun std_errNumber (err, num, mask)= _fooId num;
let std_errGetTypeFromNumber err num -> str in
if (str == nil) then
6
else
std_errprint err num str mask;;
/*! \brief Return the number of opened managers
*
* \ingroup std_error
*
* Prototype: fun [ ] I
*
* \return I : the number
**/
fun std_errObjNumbers ()=
sizelist StdErrList;;
/*! \brief Returns the last created(opened) manager
*
* \ingroup std_error
*
* Prototype: fun [] STD_ERROR
*
* \return STD_ERROR : this last (can be nil if no manager open)
**/
fun std_errObjLast ()=
hd StdErrList;;
fun std_errgetobjenabled (list, a)=
if list == nil then
nil
else
let hd list -> err in
if a == err.StdErrEnabled then
err :: std_errgetobjenabled tl list a
else
std_errgetobjenabled tl list a;;
fun std_errgetobjenabled2 (a)= /* not used */
let StdErrList -> list in
let nil -> out in
(
while list != nil do
let hd list -> err in
(
if a == err.StdErrEnabled then
set out = err :: out
else
nil;
set list = tl list
);
out
);;
/*! \brief Returns a list of all manager enabled
*
* \ingroup std_error
*
* Prototype: fun [] [STD_ERROR r1]
*
* \return [STD_ERROR r1] : this list (can be nil if no manager enabled)
**/
fun std_errGetObjEnabled ()=
std_errgetobjenabled StdErrList 1;;
/*! \brief Returns a list of all manager disabled
*
* \ingroup std_error
*
* Prototype: fun [] [STD_ERROR r1]
*
* \return [STD_ERROR r1] : this list (can be nil if no manager disabled)
**/
fun std_errGetObjDisabled ()=
std_errgetobjenabled StdErrList 0;;
proto console_print = fun [CONSOLE S] I;;
/*! \brief Same thing than std_errString.
* In addition, you can print the string message error in a EasyConsole
* (see in lib/console directory)
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR CONSOLE S I] I
*
* \param STD_ERROR : a manager object
* \param CONSOLE : an EasyConsole already created.
* \param S : the string message error
* \param I : a mask for this message. It is tested with the mask of the
* manager to determine wether the message should be written. If the test
* is positive, the message is immediatly written.
* Thus, the logical 'mask_of_manager & mask_of_this_message' must be at not null
* to write the message.
* \remark : The mask is always ignored to writing in the EsayConsole.
*
* \return I : 0 if success, 1 if the manager is nil, 2 if the manager
* is disabled, 3 if the test is negative, 4 if the message can not be
* written in the temporary file, 5 if the message cannot be written in
* the 'hard' file.
**/
fun std_errStringAndInConsole (err, csl, str, mask)=
let gmtime time -> [sec mn h d m y _ _] in
let sprintf "Date : %i %i, %i% - %ih %imn %isec :\n" [y m d h mn sec] -> d in
let strcatn d :: str :: "\n" :: nil -> s in
(
console_print csl s;
std_errprint err nil str mask
);;
/*! \brief Same thing than std_errNumber.
* In addition, you can print the message error in a EasyConsole
* (see in lib/console directory)
*
* \ingroup std_error
*
* Prototype: fun [STD_ERROR CONSOLE I I] I
*
* \param STD_ERROR : a manager object
* \param CONSOLE : an EasyConsole object
* \param I : a predefined number error
* \param I : a mask for this message. It is tested with the mask of the
* manager to determine wether the message should be written. If the test
* is positive, the message is immediatly written.
* Thus, the logical 'mask_of_manager & mask_of_this_message' must be at not null
* to write the message.
* \remark : The mask is always ignored to writing in the EsayConsole.
*
* \return I : 0 if success, 1 if the manager is nil, 2 if the manager
* is disabled, 3 if the test is negative, 4 if the message can not be
* written in the temporary file, 5 if the message cannot be written in
* the 'hard' file or 6 if the number is not a predefined error.
**/
fun std_errNumberAndInConsole (err, csl, num, mask)=
let std_errGetTypeFromNumber err num -> str in
let gmtime time -> [sec mn h d m y _ _] in
let sprintf "Date : %i %i, %i% - %ih %imn %isec :\n" [y m d h mn sec] -> d in
let strcatn d :: (itoa num) :: " " :: str :: "\n" :: nil -> s in
(
console_print csl s;
std_errprint err num str mask
);;