Sim2DocBuddy.hpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of OpenFLUID software
4  Copyright(c) 2007, INRA - Montpellier SupAgro
5 
6 
7  == GNU General Public License Usage ==
8 
9  OpenFLUID is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  OpenFLUID is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21 
22 
23  == Other Usage ==
24 
25  Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26  license, and requires a written agreement between You and INRA.
27  Licensees for Other Usage of OpenFLUID may use this file in accordance
28  with the terms contained in the written agreement between You and INRA.
29 
30 */
31 
32 
33 /**
34  @file Sim2DocBuddy.hpp
35 
36  @author Jean-Christophe FABRE <jean-christophe.fabre@inra.fr>
37  */
38 
39 
40 #ifndef __OPENFLUID_BUDDIES_SIM2DOCBUDDY_HPP__
41 #define __OPENFLUID_BUDDIES_SIM2DOCBUDDY_HPP__
42 
43 
44 #if OPENFLUID_SIM2DOC_ENABLED
45 
46 // Disabled for compilation errors due to boost.spirit usage under MacOSX
47 // TODO Should be re-enabled later
48 
49 
50 #include <map>
51 #include <vector>
52 
53 #include <boost/spirit/include/classic_core.hpp>
54 #include <boost/spirit/include/classic_file_iterator.hpp>
55 #include <boost/bind.hpp>
56 
57 #include <openfluid/config.hpp>
58 #include <openfluid/dllexport.hpp>
62 
63 
64 using namespace BOOST_SPIRIT_CLASSIC_NS;
65 
66 
67 namespace openfluid { namespace buddies {
68 
69 class BuddiesListener;
70 
71 
72 class OPENFLUID_API Sim2DocBuddy : public OpenFLUIDBuddy
73 {
74  private:
75  typedef std::map< std::string,std::vector<std::string> > SignatureData_t;
76 
77  std::string m_CPPFile;
78  std::string m_LatexOutFile;
79 
80  std::string m_InputDirPath;
81  std::string m_OutputDirPath;
82  std::string m_InputFilePath;
83  std::string m_OutputLatexFilePath;
84  std::string m_TplFilePath;
85  std::string m_CProcessedFilePath;
86 
87  openfluid::utils::ExternalProgram m_PDFLatexProgram;
88  openfluid::utils::ExternalProgram m_BibtexProgram;
89  openfluid::utils::ExternalProgram m_Latex2HTMLProgram;
91 
92  std::string m_ExtractedLatexDoc;
93 
94  std::string m_Title;
95  std::string m_NewCommands;
96  std::string m_SimID;
97  std::string m_SimName;
98  std::string m_SimVersion;
99  std::string m_SimStatus;
100  std::vector<std::string> m_SimAuthorsNames;
101  std::vector<std::string> m_SimAuthorsEmails;
102  std::string m_SimDomain;
103  std::string m_SimDescription;
104  std::string m_SimData;
105 
106  std::string m_BeginSignatureTag;
107  std::string m_EndSignatureTag;
108  std::string m_BeginSim2DocTag;
109  std::string m_EndSim2DocTag;
110 
111  std::string m_CurrentKeyValue;
112  std::string m_CurrentBuiltParam;
113 
114  std::string m_HTMLPackageLatexCommand;
115 
116  SignatureData_t m_InVars;
117  SignatureData_t m_OutVars;
118  SignatureData_t m_ModVars;
119  SignatureData_t m_InAttrs;
120  SignatureData_t m_OutAttrs;
121  SignatureData_t m_ParamsData;
122  SignatureData_t m_Events;
123  SignatureData_t m_ExtraFiles;
124 
127 
128  static std::string extractBetweenTags(std::string Content, const std::string& BeginTag, const std::string& EndTag);
129 
130  static std::string toLatexFriendly(std::string Content);
131 
132  static void addLatexDataCatBegin(std::string& Content, const std::string& Title, const std::string& ColsFormat);
133 
134  static void addLatexDataCatEnd(std::string& Content);
135 
136  std::string extractSignatureLines();
137 
138  void copyDocDirectory();
139 
140  void extractLatexDocFromCPP();
141 
142  void cpreprocessCPP();
143 
144  /** Methods called by simulator signature parser **/
145 
146  /**
147  Builds a signature parameter with parsed elements
148  @param[in] First, Last Pointers to the beginning and the end of the parsed element
149  */
150  void buildParsedParam(const char* First, const char* Last);
151 
152  /**
153  Clears the string containing the parameter built with parsing
154  */
155  void clearParsedParam();
156 
157  /**
158  Stores data parsed in the string parameter
159  @param[out] Str Pointer to the string receiving the value
160  */
161  void storeDataIntoString(std::string *Str);
162 
163  /**
164  Adds data parsed in the list parameter
165  @param[out] List Pointer to the vector receiving the value
166  */
167  void storeDataIntoVector(std::vector<std::string> *List);
168 
169  /**
170  Stores the new key value parsed into SignatureData parameter
171  @param[out] SignatureData Pointer to the map receiving the key value
172  @param[in] State of the attribute or variable stored into the map
173  (required, used, produced, updated)
174  */
175  void storeDataIntoKey(SignatureData_t *SignatureData, const std::string& State);
176 
177  /**
178  Adds data parsed in the SignatureData attribute received as parameter
179  @param[out] SignatureData Pointer to the map receiving the value
180  */
181  void storeDataIntoSignatureData(SignatureData_t *SignatureData);
182 
183  /**
184  Checks data parsed and stores it into status attribute
185  */
186  void storeDataIntoStatus();
187 
188  /**
189  Stores data parsed in a new UnitsClass item
190  @param[out] UpdatedUnitsClass Vector of Units class
191  @param[in] Attr Attribute of the new UnitsClass receiving the value
192  */
193  void storeDataIntoUnitsClass(std::vector<openfluid::ware::SignatureUnitsClassItem> *UpdatedUnitsClass,
194  int Attr);
195 
196  /**
197  Sets fixed scheduling of TimeScheduling attribute
198  @param[in] Val Value of scheduling
199  */
200  void setSchedulingFixed(double Val);
201 
202  /**
203  Sets range scheduling of TimeScheduling attribute
204  @param[in] Max Maximum value of the range
205  */
206  void setSchedulingRange(double Max);
207 
208  /** ********************************** **/
209 
210  /**
211  Applies latex syntax to the attributes
212  */
213  void turnIntoLatexSyntax();
214 
215  void processSignature();
216 
217  void generateLatex();
218 
219  bool isErrorInPDFLatexLog();
220 
221  void buildPDF();
222 
223  void buildHTML();
224 
225  public:
226 
227  Sim2DocBuddy(openfluid::buddies::BuddiesListener* Listener);
228 
229  ~Sim2DocBuddy();
230 
231  bool run();
232 
233 
234  /**
235  * Grammar class used to parse simulator signature
236  */
237  struct SimSignatureGrammar : public grammar<SimSignatureGrammar>
238  {
239  Sim2DocBuddy *mp_Owner; // Object of the class containing methods to be called
240  SimSignatureGrammar(Sim2DocBuddy *Owner) : mp_Owner(Owner) {}
241 
242 
243  template <typename ScannerT>
244  struct definition
245  {
246  /** List of parsing rules **/
247  rule<ScannerT> blank, linemarker, endLine, escapedQuote, string, varName, element, parameters, signature,
248  IDRule, NameRule, DescriptionRule, VersionRule, StatusRule, DomainRule, AuthorRule,
249  UsedParamRule, RequiredParamRule,
250  ProducedVarRule, UpdatedVarRule, RequiredVarRule, UsedVarRule,
251  ProducedAttributeRule, RequiredAttributeRule, UsedAttributeRule,
252  UsedEventsRule,
253  UsedExtraFilesRule, RequiredExtraFilesRule,
254  UpdatedUnitsGraphRule, UpdatedUnitsClassRule;
255 
256  /**
257  * Defines the different rules of content to parse or ignore
258  *
259  * boost::bind is used to execute a method after parsing of an element or a rule.
260  * Its parameters are the method to call, the object with which the method is executed
261  * and the different parameters of this method (_1 and _2 are used to send the parsed element).
262  *
263  * The different parsers which can be used :
264  * http://www.boost.org/doc/libs/1_39_0/libs/spirit/classic/doc/quickref.html
265  */
266  definition(SimSignatureGrammar const& self)
267  {
268  /** Initial rule **/
269 
270  signature = str_p("BEGIN_SIMULATOR_SIGNATURE") >> *blank >> '(' >> IDRule >> ')' >> endLine
271  >> *(str_p("DECLARE_NAME") >> *blank >> '(' >> NameRule >> ')' >> endLine
272  | str_p("DECLARE_DESCRIPTION") >> *blank >> '(' >> DescriptionRule >> ')' >> endLine
273  | str_p("DECLARE_VERSION") >> *blank >> '(' >> VersionRule >> ')' >> endLine
274  | str_p("DECLARE_SDKVERSION") >> endLine
275  | str_p("DECLARE_STATUS") >> *blank >> '(' >> StatusRule >> ')' >> endLine
276  | str_p("DECLARE_DOMAIN") >> *blank >> '(' >> DomainRule >> ')' >> endLine
277  | str_p("DECLARE_PROCESS") >> *blank >> '(' >> parameters >> ')' >> endLine
278  | str_p("DECLARE_METHOD") >> *blank >> '(' >> parameters >> ')' >> endLine
279  | str_p("DECLARE_AUTHOR") >> *blank >> '(' >> AuthorRule >> ')' >> endLine
280 
281  | str_p("DECLARE_REQUIRED_PARAMETER") >> *blank >> '(' >> RequiredParamRule >> ')' >> endLine
282  | str_p("DECLARE_USED_PARAMETER") >> *blank >> '(' >> UsedParamRule >> ')' >> endLine
283 
284  // for compatibility with deprecated macros
285  | str_p("DECLARE_SIMULATOR_PARAM") >> *blank >> '(' >> UsedParamRule >> ')' >> endLine
286 
287  | str_p("DECLARE_PRODUCED_VARIABLE") >> *blank >> '(' >> ProducedVarRule >> ')' >> endLine
288  | str_p("DECLARE_UPDATED_VARIABLE") >> *blank >> '(' >> UpdatedVarRule >> ')' >> endLine
289  | str_p("DECLARE_REQUIRED_VARIABLE") >> *blank >> '(' >> RequiredVarRule >> ')' >> endLine
290  | str_p("DECLARE_USED_VARIABLE") >> *blank >> '(' >> UsedVarRule >> ')' >> endLine
291 
292  // for compatibility with deprecated macros
293  | str_p("DECLARE_PRODUCED_VAR") >> *blank >> '(' >> ProducedVarRule >> ')' >> endLine
294  | str_p("DECLARE_UPDATED_VAR") >> *blank >> '(' >> UpdatedVarRule >> ')' >> endLine
295  | str_p("DECLARE_REQUIRED_VAR") >> *blank >> '(' >> RequiredVarRule >> ')' >> endLine
296  | str_p("DECLARE_USED_VAR") >> *blank >> '(' >> UsedVarRule >> ')' >> endLine
297 
298  | str_p("DECLARE_PRODUCED_ATTRIBUTE") >> *blank >> '(' >> ProducedAttributeRule >> ')' >> endLine
299  | str_p("DECLARE_REQUIRED_ATTRIBUTE") >> *blank >> '(' >> RequiredAttributeRule >> ')' >> endLine
300  | str_p("DECLARE_USED_ATTRIBUTE") >> *blank >> '(' >> UsedAttributeRule >> ')' >> endLine
301 
302  | str_p("DECLARE_USED_EVENTS") >> *blank >> '(' >> UsedEventsRule >> ')' >> endLine
303  | str_p("DECLARE_USED_EXTRAFILE") >> *blank >> '(' >> UsedExtraFilesRule >> ')' >> endLine
304  | str_p("DECLARE_REQUIRED_EXTRAFILE") >> *blank >> '(' >> RequiredExtraFilesRule >> ')' >> endLine
305 
306  | str_p("DECLARE_UPDATED_UNITSGRAPH") >> *blank >> '(' >> UpdatedUnitsGraphRule >> ')' >> endLine
307  | str_p("DECLARE_UPDATED_UNITSCLASS") >> *blank >> '(' >> UpdatedUnitsClassRule >> ')' >> endLine
308 
309  | str_p("DECLARE_SCHEDULING_UNDEFINED")[boost::bind(&ware::SignatureTimeScheduling::setAsUndefined,
310  &self.mp_Owner->m_TimeScheduling)] >> endLine
311  | str_p("DECLARE_SCHEDULING_DEFAULT")[boost::bind(
312  &ware::SignatureTimeScheduling::setAsDefaultDeltaT,
313  &self.mp_Owner->m_TimeScheduling)] >> endLine
314  | str_p("DECLARE_SCHEDULING_FIXED") >> *blank >> '(' >> *blank
315  >> real_p[boost::bind(&Sim2DocBuddy::setSchedulingFixed, self.mp_Owner, _1)]
316  >> *blank >> ')' >> endLine
317  | str_p("DECLARE_SCHEDULING_RANGE") >> *blank >> '('
318  >> *blank >> real_p[boost::bind(&Sim2DocBuddy::setSchedulingFixed, self.mp_Owner, _1)]
319  >> *blank >> ','
320  >> *blank >> real_p[boost::bind(&Sim2DocBuddy::setSchedulingRange, self.mp_Owner, _1)]
321  >> *blank >> ')' >> endLine
322 
323  | linemarker >> endLine
324  )
325  >> str_p("END_SIMULATOR_SIGNATURE") >> endLine
326  ;
327 
328  /** List of common rules **/
329 
330 
331  /* Ignoring of inserted lines by the preprocessor which mean
332  * the original position of lines in source file.
333  */
334  linemarker = '#' >> *(anychar_p - eol_p) >> eol_p;
335 
336  blank = blank_p | eol_p; // Parse all spaces, tabs and newlines
337  endLine = *(blank | ';');
338  escapedQuote = str_p("\\\"");
339 
340  string = *(escapedQuote | (anychar_p - '"')); // String content composed to all characters
341 
342  varName = *(print_p - ')');
343 
344  // Parameter of a method surrounded by quotes (string) or not (var name)
345  element = (+(*blank >> '"' >> string[boost::bind(&Sim2DocBuddy::buildParsedParam, self.mp_Owner, _1, _2)]
346  >> '"' >> *blank))
347  | (*blank >> varName[boost::bind(&Sim2DocBuddy::buildParsedParam, self.mp_Owner, _1, _2)]
348  >> *blank);
349 
350  // List of parameters of a declaration (here not stored)
351  parameters = element[boost::bind(&Sim2DocBuddy::clearParsedParam, self.mp_Owner)]
352  >> *(',' >> element[boost::bind(&Sim2DocBuddy::clearParsedParam, self.mp_Owner)]);
353 
354 
355  /** List of rules for the different lines of signature **/
356 
357  IDRule =
358  element[boost::bind(&Sim2DocBuddy::storeDataIntoString, self.mp_Owner, &self.mp_Owner->m_SimID)];
359  NameRule =
360  element[boost::bind(&Sim2DocBuddy::storeDataIntoString, self.mp_Owner, &self.mp_Owner->m_SimName)];
361  DescriptionRule =
362  element[boost::bind(&Sim2DocBuddy::storeDataIntoString, self.mp_Owner, &self.mp_Owner->m_SimDescription)];
363  VersionRule =
364  element[boost::bind(&Sim2DocBuddy::storeDataIntoString, self.mp_Owner, &self.mp_Owner->m_SimVersion)];
365 
366  StatusRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoStatus, self.mp_Owner)];
367 
368  DomainRule =
369  element[boost::bind(&Sim2DocBuddy::storeDataIntoString, self.mp_Owner, &self.mp_Owner->m_SimDomain)];
370  AuthorRule =
371  element[boost::bind(&Sim2DocBuddy::storeDataIntoVector, self.mp_Owner, &self.mp_Owner->m_SimAuthorsNames)]
372  >> ',' >>
373  element[boost::bind(&Sim2DocBuddy::storeDataIntoVector, self.mp_Owner,
374  &self.mp_Owner->m_SimAuthorsEmails)];
375 
376  UsedParamRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey,
377  self.mp_Owner, &self.mp_Owner->m_ParamsData, "used")]
378  >> *(',' >> element[boost::bind(&Sim2DocBuddy::storeDataIntoSignatureData,
379  self.mp_Owner, &self.mp_Owner->m_ParamsData)]);
380  RequiredParamRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey,
381  self.mp_Owner, &self.mp_Owner->m_ParamsData, "required")]
382  >> *(',' >> element[boost::bind(&Sim2DocBuddy::storeDataIntoSignatureData,
383  self.mp_Owner, &self.mp_Owner->m_ParamsData)]);
384 
385  ProducedVarRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey, self.mp_Owner,
386  &self.mp_Owner->m_OutVars, "produced")]
387  >> *(',' >> element[boost::bind(&Sim2DocBuddy::storeDataIntoSignatureData,
388  self.mp_Owner, &self.mp_Owner->m_OutVars)]);
389  UpdatedVarRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey, self.mp_Owner,
390  &self.mp_Owner->m_OutVars, "updated")]
391  >> *(',' >> element[boost::bind(&Sim2DocBuddy::storeDataIntoSignatureData,
392  self.mp_Owner, &self.mp_Owner->m_OutVars)]);
393  RequiredVarRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey, self.mp_Owner,
394  &self.mp_Owner->m_InVars, "required")]
395  >> *(',' >> element[boost::bind(&Sim2DocBuddy::storeDataIntoSignatureData,
396  self.mp_Owner, &self.mp_Owner->m_InVars)]);
397  UsedVarRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey, self.mp_Owner,
398  &self.mp_Owner->m_InVars, "used")]
399  >> *(',' >> element[boost::bind(&Sim2DocBuddy::storeDataIntoSignatureData,
400  self.mp_Owner, &self.mp_Owner->m_InVars)]);
401 
402  ProducedAttributeRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey, self.mp_Owner,
403  &self.mp_Owner->m_OutAttrs, "produced")]
404  >> *(',' >> element[boost::bind(&Sim2DocBuddy::storeDataIntoSignatureData, self.mp_Owner,
405  &self.mp_Owner->m_OutAttrs)]);
406  RequiredAttributeRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey, self.mp_Owner,
407  &self.mp_Owner->m_InAttrs, "required")]
408  >> *(',' >> element[boost::bind(&Sim2DocBuddy::storeDataIntoSignatureData, self.mp_Owner,
409  &self.mp_Owner->m_InAttrs)]);
410  UsedAttributeRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey, self.mp_Owner,
411  &self.mp_Owner->m_InAttrs, "used")]
412  >> *(',' >> element[boost::bind(&Sim2DocBuddy::storeDataIntoSignatureData, self.mp_Owner,
413  &self.mp_Owner->m_InAttrs)]);
414 
415  UsedEventsRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey, self.mp_Owner,
416  &self.mp_Owner->m_Events, "")];
417  UsedExtraFilesRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey, self.mp_Owner,
418  &self.mp_Owner->m_ExtraFiles, "used")];
419  RequiredExtraFilesRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoKey, self.mp_Owner,
420  &self.mp_Owner->m_ExtraFiles, "required")];
421 
422  UpdatedUnitsGraphRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoString, self.mp_Owner,
423  &self.mp_Owner->m_UnitsGraph.UpdatedUnitsGraph)];
424  UpdatedUnitsClassRule = element[boost::bind(&Sim2DocBuddy::storeDataIntoUnitsClass, self.mp_Owner,
425  &self.mp_Owner->m_UnitsGraph.UpdatedUnitsClass, 1)]
426  >> ',' >> element[boost::bind(&Sim2DocBuddy::storeDataIntoUnitsClass, self.mp_Owner,
427  &self.mp_Owner->m_UnitsGraph.UpdatedUnitsClass, 2)];
428  }
429 
430  /**
431  @return Main rule of parsing content
432  */
433  rule<ScannerT> const& start() const { return signature; }
434  };
435  };
436 
437 };
438 
439 
440 } } //namespaces
441 
442 
443 #endif /* OPENFLUID_SIM2DOC_ENABLED */
444 
445 #endif /* __OPENFLUID_BUDDIES_SIM2DOCBUDDY_HPP__ */
Definition: ExternalProgram.hpp:54
Definition: SimulatorSignature.hpp:249
Definition: BuddiesListener.hpp:54
Definition: ApplicationException.hpp:47
#define OPENFLUID_API
Definition: dllexport.hpp:86
Definition: SimulatorSignature.hpp:222