1%%%%%%%%%%%%%%%%%%%
2% XLiFE++ is an extended library of finite elements written in C++
3%     Copyright (C) 2014  Lunéville, Eric; Kielbasiewicz, Nicolas; Lafranche, Yvon; Nguyen, Manh-Ha; Chambeyron, Colin
4%
5%     This program is free software: you can redistribute it and/or modify
6%     it under the terms of the GNU General Public License as published by
7%     the Free Software Foundation, either version 3 of the License, or
8%     (at your option) any later version.
9%     This program is distributed in the hope that it will be useful,
10%     but WITHOUT ANY WARRANTY; without even the implied warranty of
11%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12%     GNU General Public License for more details.
13%     You should have received a copy of the GNU General Public License
14%     along with this program.  If not, see <http://www.gnu.org/licenses/>.
15%%%%%%%%%%%%%%%%%%%
16
17\section{Messages management}
18
19Handling error, warning and info messages is a essential part of a code. In C++, a choice could
20be using exceptions. As \xlifepp is a very large code, with a high number of levels (routines
21called by routines themselves called by routines ...), using exceptions has a lot of constraints.
22The other way is to develop our own classes.  The message machinery works as follows:
23\begin{itemize}
24\item A message is a string of characters including free text and particular codes (as much
25as you want) of the form \%s, \%i, \%r, \%c and \%b which will be substituted respectively
26by a string, an integer, a real, a complex and a boolean.
27\item For each message is defined a unique string identifier, a type (ERROR,WARNING or INFO),
28a runtime behaviour (STOP or CONT) and an output console flag (STDOUT or NOSTDOUT).
29\item All the messages are listed in a file named \textit{messages.txt} in the directory \textit{etc/Messages/lang}
30where \textit{lang} is the language code; for instance \textit{en} for the English, \textit{fr}
31for the French, ...
32\item By translating the English reference \textsl{messages.txt} file in an other language
33it is easy to internationalize the \xlifepp code.
34\end{itemize}
35For instance, the beginning of the English \textit{messages.txt} is
36\begin{verbatim}
37   #/
38   ============================ internal messages =================================
39
40   # logon INFO CONT STDOUT Log file "%s" activated.
41   # logoff INFO CONT STDOUT Log file "%s" deactivated.
42   # errorundef ERROR STOP STDOUT Error message of type %s and id %i undefined (%s)!
43   This might occur with a double string message Id in a message.txt file
44   or the forgetting of the message type, the behaviour type or the output type
45   ...
46\end{verbatim}
47Note that a message format may be defined on several lines (the next character \# is the end
48delimiter of a message) and a comment begins by \#/. \\
49
50
51The message management is based on three classes: {\class MsgData} (storage of the values to
52be included), {\class MsgFormat} (multilingual message format) and {\class Messages}, the main
53class collecting all formats and methods to produce and output the formatted messages.
54
55\subsection{The {\classtitle MsgData} class}
56
57The aim of the {\class MsgData} class is to store in the same structure, all sorts of variables
58to use to build a message, of various types: integer, real, complex, string and bool. Thus,
59this class proposes as private members:
60\vspace{.1cm}
61\begin{lstlisting}
62class MsgData {
63  private :
64    std::vector<int> i_;         // to store int type data
65    std::vector<real_t> r_;      // to store real_t type data
66    std::vector<complex_t c_;    // to store complex_t type data
67    std::vector<String> s_;      // to store string data
68    std::vector<bool> b_;        // to store boolean data
69    bool read_;                  // flag to specify that the structure has been read
70  ...
71};
72\end{lstlisting}
73\vspace{.2cm}
74It offers:
75
76\begin{itemize}
77\item a default constructor:
78\vspace{.1cm}
79\begin{lstlisting}[]{}
80MsgData() : i_(0), r_(0), c_(0), s_(0), b_(0), read_(true) {}
81\end{lstlisting}
82\vspace{.2cm}
83\item some public access functions to data
84\begin{lstlisting}[]{}
85yyy xxxParameter(const unsigned int n);
86// where (xxx,yyy)=(int,int), (real,real_t), (complex,complex_t), (string,string), (boolean,bool)
87bool read();
88\end{lstlisting}
89\vspace{.2cm}
90\item a public method to specify data was read
91\vspace{.1cm}
92\begin{lstlisting}[]{}
93void readData();
94 \end{lstlisting}
95\vspace{.2cm}
96\item some public append methods for each managed data type or variant (unsigned int or char*
97for example)
98\vspace{.1cm}
99\begin{lstlisting}[]{}
100void push(const T t); // T is int, real_t, string, ...
101 \end{lstlisting}
102\vspace{.2cm}
103\item some public streaming operators, appending data of various types
104\vspace{.1cm}
105\begin{lstlisting}[]{}
106MsgData& operator<<(const T i) // T is int, real_t, string, ...
107\end{lstlisting}
108\vspace{.2cm}
109\item a private reset method, to reset every list of data
110\vspace{.1cm}
111\begin{lstlisting}[]{}
112void reset_();
113\end{lstlisting}
114\end{itemize}
115
116\subsection{The {\classtitle MsgFormat} class}
117
118The {\class MsgFormat} Object contains a message format for output. In addition, it contains
119information on message such as the message type, the message behaviour, the message output
120and the message id. Thus, the {\class MsgFormat} class proposes as private members:
121\vspace{.1cm}
122\begin{lstlisting}
123enum MsgType {_error=0,_warning,_info};
124
125class MsgFormat {
126  private :
127    String format_;        // format of message
128    MsgType type_;         // flag for warning/error
129    bool stop_;            // flag for stop/continue
130    bool consoleOut_;      // flag for output to console
131    String ids_;           // string id of format
132  ...
133};
134\end{lstlisting}
135
136It offers:
137
138\begin{itemize}
139\item two constructors, the default one and the full one:
140\vspace{.1cm}
141\begin{lstlisting}
142MsgFormat(const String &ms, const String &ids, MsgType t, bool s, bool c);
143\end{lstlisting}
144\vspace{.2cm}
145\item some accessors, one for each attribute:
146\vspace{.1cm}
147\begin{lstlisting}
148String format() const {return format_;}
149MsgType type() const {return type_;}
150bool stop() const {return stop_;}
151bool console() const {return consoleOut_;}
152String stringId() const {return ids_;}
153\end{lstlisting}
154\end{itemize}
155
156\subsection{The {\classtitle Messages} class}
157
158The {\class Messages} class manages the list of messages format and the display of every message.
159Thus, this class proposes as private members:
160\vspace{.1cm}
161\begin{lstlisting}[deletekeywords={[3] map}]
162class Messages {
163  private :
164    String msgType_;                          // message type
165    std::map<String,MsgFormat*> stringIndex_; // index of messages by string id
166    std::ofstream* msgStream_p;               // file stream where are sent messages
167    String msgFile_;                          // file where are sent messages
168  ...
169};
170\end{lstlisting}
171
172It offers:
173
174\begin{itemize}
175\item two constructors, the default one and the full one:
176\vspace{.1cm}
177\begin{lstlisting}[deletekeywords={[3] msgFile, msgType}]
178Messages(const std::string& file, std::ofstream& out, const std::string& msgFile, const std::string& msgType = std::string("XLiFE++"));
179\end{lstlisting}
180\vspace{.2cm}
181\item some accessors:
182\vspace{.1cm}
183\begin{lstlisting}
184String msgType() const;
185String msgFile();
186std::ofstream* msgStream() const;
187\end{lstlisting}
188\vspace{.2cm}
189\item some utilities:
190\vspace{.1cm}
191\begin{lstlisting}
192int numberOfMessages() const;
193void loadFormat(const String&);     // load format from a file
194void printList(std::ofstream&);     // print the list of all messages
195MsgFormat* find(const String&);     // find an error format
196void append(MsgFormat&);            // append a new message format in list
197void appendFromFile(const String&); // append a new message format in list
198\end{lstlisting}
199\end{itemize}
200
201\subsection{External functions}
202
203To throw messages, some external functions with useful aliases and shorcuts functions are provided.
204The general functions are:
205\vspace{.2cm}
206\begin{lstlisting}[deletekeywords={[3] msgType}]
207String message(const String& msgIds, MsgData& msgData=theMessageData,
208               Messages* msgSrc=theMessages_p);
209void msg(const String& msgIds, MsgData& msgData, MsgType& msgType, Messages* msgSrc);
210\end{lstlisting}
211\vspace{.1cm}
212The first one ({\it message}) reads the message format and replaces the strings \%i,\%r,\%c,\%s
213and \%b by their values given by the {\class MsgData} object.
214It produces a {\class String} containing the formatted message. This function is called by the
215{\it msg} function which outputs the formatted message to the console or to a print file.
216Note that this function may be also called by any function to retrieve the formatted message
217without output. \\
218The \textit{msg} function is called by the three useful functions:
219\vspace{.2cm}
220\begin{lstlisting}[frame=single]
221void error(const String& msgIds, MsgData& msgData=theMessageData,
222           Messages* msgSrc=theMessages_p);
223void info(const String& msgIds, MsgData& msgData=theMessageData,
224          Messages* msgSrc=theMessages_p);
225void warning(const String& msgIds, MsgData& msgData=theMessageData,
226             Messages* msgSrc=theMessages_p);
227\end{lstlisting}
228which are aliases for the {\it msg} function, giving the value of the {\tt msgType} argument.
229These are the functions to be used when you need to throw messages in other classes of \xlifepp
230library. \\
231
232Besides, for sake of simplicity, some shorcut functions are also provided. They avoid to manage
233explicitely the {\class MsgData} object storing the message values.These shorcut functions
234are templated functions (one, two or three templated parameters), so they only work up to three
235message values!
236\vspace{.2cm}
237\begin{lstlisting}[]
238String message(const String& msgIds, const T& v, Messages* msgSrc=theMessages_p);
239String message(const String& msgIds, const T1& v1,const T2& v2,
240               Messages* msgSrc=theMessages_p);
241String message(const String& msgIds, const T1& v1,const T2& v2, const T3& v3,
242               Messages* msgSrc=theMessages_p);
243void error(const String& msgIds, const T& v, Messages* msgSrc=theMessages_p);
244void error(const String& msgIds, const T1& v1,const T2& v2,
245           Messages* msgSrc=theMessages_p);
246void error(const String& msgIds, const T1& v1,const T2& v2,const T3& v3,
247           Messages* msgSrc=theMessages_p);
248//the same for warning and info functions
249\end{lstlisting}
250
251\subsection{Throwing messages}
252
253There is one global {\class MsgData} object: \textit{theMessageData} which is used as default
254argument of message functions. Using it, it is very easy to throw messages. For instance, these
255lines show how to throw an error message:
256\vspace{.1cm}
257\begin{lstlisting}[deletekeywords={[3] x, y}]
258 if(x.size()!=y.size())
259    {theMessageData<<name()<<x.size()<<y.size();  //store the message values
260     error("ker_bad_dim");                        //throw the error message ker_bad_dim
261    }
262\end{lstlisting}
263The message format \textit{ker\_bad\_dim} has the following definition:
264\begin{verbatim}
265  # ker_bad_dim ERROR STOP STDOUT Call of kernel \%s
266  with vectors of incompatible dimensions : (\%i,\%i)
267\end{verbatim}
268
269If you want to use international messages in your own output stream, you cannot use the function
270\textit{info} because it outputs the message on the default print stream. You have to use the
271function \textit{message} which returns the message as a {\class String} without printing output.
272For instance:
273\vspace{.1cm}
274\begin{lstlisting}
275std::ostream& operator<<(std::ostream& out,const Space & sp)
276{   theMessageData<<sp.name()<<sp.typeOfSpace()<<sp.domain().name();
277    out<<message("space_def");
278    return out;
279}
280\end{lstlisting}
281with the message format \textit{space\_def}:
282\begin{verbatim}
283  # space_def INFO CONT STDOUT space %s of type %s on the geometrical domain %s
284\end{verbatim}
285Using shortcut functions, the previous example reads:
286\vspace{.1cm}
287\begin{lstlisting}
288std::ostream& operator<<(std::ostream& out,const Space & sp)
289{   out<<message("space_def",sp.name(),sp.typeOfSpace(),sp.domain().name());
290    return out;
291}
292\end{lstlisting}
293
294\displayInfos{library=utils, header=Messages.hpp, implementation=Messages.cpp, test=test\_Messages.cpp,
295header dep={config.h, String.hpp}}
296
297