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 /**
35  @file Sim2DocBuddy.hpp
36 
37  @author Jean-Christophe FABRE <jean-christophe.fabre@supagro.inra.fr>
38  */
39 
40 
41 #ifndef __OPENFLUID_BUDDIES_SIM2DOCBUDDY_HPP__
42 #define __OPENFLUID_BUDDIES_SIM2DOCBUDDY_HPP__
43 
44 
45 #if !defined(OPENFLUID_OS_MAC)
46 
47 // Disabled for compilation errors due to boost.spirit usage under MacOSX
48 // TODO Should be re-enabled later
49 
50 
51 #include <map>
52 #include <vector>
53 
54 #include <openfluid/dllexport.hpp>
58 
59 #include <boost/spirit/include/classic_core.hpp>
60 #include <boost/spirit/include/classic_file_iterator.hpp>
61 #include <boost/bind.hpp>
62 
63 
64 using namespace BOOST_SPIRIT_CLASSIC_NS;
65 
66 namespace openfluid { namespace buddies {
67 
68 class BuddiesListener;
69 
70 
72 {
73  private:
74  typedef std::map< std::string,std::vector<std::string> > SignatureData_t;
75 
76  std::string m_CPPFile;
77  std::string m_LatexOutFile;
78 
79  std::string m_InputDirPath;
80  std::string m_OutputDirPath;
81  std::string m_InputFilePath;
82  std::string m_OutputLatexFilePath;
83  std::string m_TplFilePath;
84  std::string m_CProcessedFilePath;
85 
86  openfluid::utils::ExternalProgram m_PDFLatexProgram;
87  openfluid::utils::ExternalProgram m_BibtexProgram;
88  openfluid::utils::ExternalProgram m_Latex2HTMLProgram;
90 
91  std::string m_ExtractedLatexDoc;
92 
93  std::string m_Title;
94  std::string m_NewCommands;
95  std::string m_SimID;
96  std::string m_SimName;
97  std::string m_SimVersion;
98  std::string m_SimStatus;
99  std::vector<std::string> m_SimAuthorsNames;
100  std::vector<std::string> m_SimAuthorsEmails;
101  std::string m_SimDomain;
102  std::string m_SimDescription;
103  std::string m_SimData;
104 
105  std::string m_BeginSignatureTag;
106  std::string m_EndSignatureTag;
107  std::string m_BeginSim2DocTag;
108  std::string m_EndSim2DocTag;
109 
110  std::string m_CurrentKeyValue;
111  std::string m_CurrentBuiltParam;
112 
113  std::string m_HTMLPackageLatexCommand;
114 
115  SignatureData_t m_InVars;
116  SignatureData_t m_OutVars;
117  SignatureData_t m_ModVars;
118  SignatureData_t m_InAttrs;
119  SignatureData_t m_OutAttrs;
120  SignatureData_t m_ParamsData;
121  SignatureData_t m_Events;
122  SignatureData_t m_ExtraFiles;
123 
126 
127  static std::string extractBetweenTags(std::string Content, const std::string& BeginTag, const std::string& EndTag);
128 
129  static std::string toLatexFriendly(std::string Content);
130 
131  static void addLatexDataCatBegin(std::string& Content, const std::string& Title, const std::string& ColsFormat);
132 
133  static void addLatexDataCatEnd(std::string& Content);
134 
135  std::string extractSignatureLines();
136 
137  void copyDocDirectory();
138 
139  void extractLatexDocFromCPP();
140 
141  void cpreprocessCPP();
142 
143  /** Methods called by simulator signature parser **/
144 
145  /**
146  Builds a signature parameter with parsed elements
147  @param[in] First, Last Pointers to the beginning and the end of the parsed element
148  */
149  void buildParsedParam(const char* First, const char* Last);
150 
151  /**
152  Clears the string containing the parameter built with parsing
153  */
154  void clearParsedParam();
155 
156  /**
157  Stores data parsed in the string parameter
158  @param[out] Str Pointer to the string receiving the value
159  */
160  void storeDataIntoString(std::string *Str);
161 
162  /**
163  Adds data parsed in the list parameter
164  @param[out] List Pointer to the vector receiving the value
165  */
166  void storeDataIntoVector(std::vector<std::string> *List);
167 
168  /**
169  Stores the new key value parsed into SignatureData parameter
170  @param[out] SignatureData Pointer to the map receiving the key value
171  @param[in] State of the attribute or variable stored into the map
172  (required, used, produced, updated)
173  */
174  void storeDataIntoKey(SignatureData_t *SignatureData, const std::string& State);
175 
176  /**
177  Adds data parsed in the SignatureData attribute received as parameter
178  @param[out] SignatureData Pointer to the map receiving the value
179  */
180  void storeDataIntoSignatureData(SignatureData_t *SignatureData);
181 
182  /**
183  Checks data parsed and stores it into status attribute
184  */
185  void storeDataIntoStatus();
186 
187  /**
188  Stores data parsed in a new UnitsClass item
189  @param[out] UpdatedUnitsClass Vector of Units class
190  @param[in] Attr Attribute of the new UnitsClass receiving the value
191  */
192  void storeDataIntoUnitsClass(std::vector<openfluid::ware::SignatureUnitsClassItem> *UpdatedUnitsClass,
193  int Attr);
194 
195  /**
196  Sets fixed scheduling of TimeScheduling attribute
197  @param[in] Val Value of scheduling
198  */
199  void setSchedulingFixed(double Val);
200 
201  /**
202  Sets range scheduling of TimeScheduling attribute
203  @param[in] Max Maximum value of the range
204  */
205  void setSchedulingRange(double Max);
206 
207  /** ********************************** **/
208 
209  /**
210  Applies latex syntax to the attributes
211  */
212  void turnIntoLatexSyntax();
213 
214  void processSignature();
215 
216  void generateLatex();
217 
218  bool isErrorInPDFLatexLog();
219 
220  void buildPDF();
221 
222  void buildHTML();
223 
224  public:
225 
227 
228  ~Sim2DocBuddy();
229 
230  bool run();
231 
232 
233  /**
234  * Grammar class used to parse simulator signature
235  */
236  struct SimSignatureGrammar : public grammar<SimSignatureGrammar>
237  {
238  Sim2DocBuddy *mp_Owner; // Object of the class containing methods to be called
239  SimSignatureGrammar(Sim2DocBuddy *Owner) : mp_Owner(Owner) {}
240 
241 
242  template <typename ScannerT>
243  struct definition
244  {
245  /** List of parsing rules **/
246  rule<ScannerT> blank, linemarker, endLine, escapedQuote, string, varName, element, parameters, signature,
247  IDRule, NameRule, DescriptionRule, VersionRule, StatusRule, DomainRule, AuthorRule,
248  UsedParamRule, RequiredParamRule,
249  ProducedVarRule, UpdatedVarRule, RequiredVarRule, UsedVarRule,
250  ProducedAttributeRule, RequiredAttributeRule, UsedAttributeRule,
251  UsedEventsRule,
252  UsedExtraFilesRule, RequiredExtraFilesRule,
253  UpdatedUnitsGraphRule, UpdatedUnitsClassRule;
254 
255  /**
256  * Defines the different rules of content to parse or ignore
257  *
258  * boost::bind is used to execute a method after parsing of an element or a rule.
259  * Its parameters are the method to call, the object with which the method is executed
260  * and the different parameters of this method (_1 and _2 are used to send the parsed element).
261  *
262  * The different parsers which can be used :
263  * http://www.boost.org/doc/libs/1_39_0/libs/spirit/classic/doc/quickref.html
264  */
266  {
267  /** Initial rule **/
268 
269  signature = str_p("BEGIN_SIMULATOR_SIGNATURE") >> *blank >> '(' >> IDRule >> ')' >> endLine
270  >> *(str_p("DECLARE_NAME") >> *blank >> '(' >> NameRule >> ')' >> endLine
271  | str_p("DECLARE_DESCRIPTION") >> *blank >> '(' >> DescriptionRule >> ')' >> endLine
272  | str_p("DECLARE_VERSION") >> *blank >> '(' >> VersionRule >> ')' >> endLine
273  | str_p("DECLARE_SDKVERSION") >> endLine
274  | str_p("DECLARE_STATUS") >> *blank >> '(' >> StatusRule >> ')' >> endLine
275  | str_p("DECLARE_DOMAIN") >> *blank >> '(' >> DomainRule >> ')' >> endLine
276  | str_p("DECLARE_PROCESS") >> *blank >> '(' >> parameters >> ')' >> endLine
277  | str_p("DECLARE_METHOD") >> *blank >> '(' >> parameters >> ')' >> endLine
278  | str_p("DECLARE_AUTHOR") >> *blank >> '(' >> AuthorRule >> ')' >> endLine
279 
280  | str_p("DECLARE_REQUIRED_PARAMETER") >> *blank >> '(' >> RequiredParamRule >> ')' >> endLine
281  | str_p("DECLARE_USED_PARAMETER") >> *blank >> '(' >> UsedParamRule >> ')' >> endLine
282 
283  // for compatibility with deprecated macros
284  | str_p("DECLARE_SIMULATOR_PARAM") >> *blank >> '(' >> UsedParamRule >> ')' >> endLine
285 
286  | str_p("DECLARE_PRODUCED_VARIABLE") >> *blank >> '(' >> ProducedVarRule >> ')' >> endLine
287  | str_p("DECLARE_UPDATED_VARIABLE") >> *blank >> '(' >> UpdatedVarRule >> ')' >> endLine
288  | str_p("DECLARE_REQUIRED_VARIABLE") >> *blank >> '(' >> RequiredVarRule >> ')' >> endLine
289  | str_p("DECLARE_USED_VARIABLE") >> *blank >> '(' >> UsedVarRule >> ')' >> endLine
290 
291  // for compatibility with deprecated macros
292  | str_p("DECLARE_PRODUCED_VAR") >> *blank >> '(' >> ProducedVarRule >> ')' >> endLine
293  | str_p("DECLARE_UPDATED_VAR") >> *blank >> '(' >> UpdatedVarRule >> ')' >> endLine
294  | str_p("DECLARE_REQUIRED_VAR") >> *blank >> '(' >> RequiredVarRule >> ')' >> endLine
295  | str_p("DECLARE_USED_VAR") >> *blank >> '(' >> UsedVarRule >> ')' >> endLine
296 
297  | str_p("DECLARE_PRODUCED_ATTRIBUTE") >> *blank >> '(' >> ProducedAttributeRule >> ')' >> endLine
298  | str_p("DECLARE_REQUIRED_ATTRIBUTE") >> *blank >> '(' >> RequiredAttributeRule >> ')' >> endLine
299  | str_p("DECLARE_USED_ATTRIBUTE") >> *blank >> '(' >> UsedAttributeRule >> ')' >> endLine
300 
301  | str_p("DECLARE_USED_EVENTS") >> *blank >> '(' >> UsedEventsRule >> ')' >> endLine
302  | str_p("DECLARE_USED_EXTRAFILE") >> *blank >> '(' >> UsedExtraFilesRule >> ')' >> endLine
303  | str_p("DECLARE_REQUIRED_EXTRAFILE") >> *blank >> '(' >> RequiredExtraFilesRule >> ')' >> endLine
304 
305  | str_p("DECLARE_UPDATED_UNITSGRAPH") >> *blank >> '(' >> UpdatedUnitsGraphRule >> ')' >> endLine
306  | str_p("DECLARE_UPDATED_UNITSCLASS") >> *blank >> '(' >> UpdatedUnitsClassRule >> ')' >> endLine
307 
308  | str_p("DECLARE_SCHEDULING_UNDEFINED")[boost::bind(&ware::SignatureTimeScheduling::setAsUndefined,
309  &self.mp_Owner->m_TimeScheduling)] >> endLine
310  | str_p("DECLARE_SCHEDULING_DEFAULT")[boost::bind(
311  &ware::SignatureTimeScheduling::setAsDefaultDeltaT,
312  &self.mp_Owner->m_TimeScheduling)] >> endLine
313  | str_p("DECLARE_SCHEDULING_FIXED") >> *blank >> '(' >> *blank
314  >> real_p[boost::bind(&Sim2DocBuddy::setSchedulingFixed, self.mp_Owner, _1)]
315  >> *blank >> ')' >> endLine
316  | str_p("DECLARE_SCHEDULING_RANGE") >> *blank >> '('
317  >> *blank >> real_p[boost::bind(&Sim2DocBuddy::setSchedulingFixed, self.mp_Owner, _1)]
318  >> *blank >> ','
319  >> *blank >> real_p[boost::bind(&Sim2DocBuddy::setSchedulingRange, self.mp_Owner, _1)]
320  >> *blank >> ')' >> endLine
321 
322  | linemarker >> endLine
323  )
324  >> str_p("END_SIMULATOR_SIGNATURE") >> endLine
325  ;
326 
327  /** List of common rules **/
328 
329 
330  /* Ignoring of inserted lines by the preprocessor which mean
331  * the original position of lines in source file.
332  */
333  linemarker = '#' >> *(anychar_p - eol_p) >> eol_p;
334 
335  blank = blank_p | eol_p; // Parse all spaces, tabs and newlines
336  endLine = *(blank | ';');
337  escapedQuote = str_p("\\\"");
338 
339  string = *(escapedQuote | (anychar_p - '"')); // String content composed to all characters
340 
341  varName = *(print_p - ')');
342 
343  // Parameter of a method surrounded by quotes (string) or not (var name)
344  element = (+(*blank >> '"' >> string[boost::bind(&Sim2DocBuddy::buildParsedParam, self.mp_Owner, _1, _2)]
345  >> '"' >> *blank))
346  | (*blank >> varName[boost::bind(&Sim2DocBuddy::buildParsedParam, self.mp_Owner, _1, _2)]
347  >> *blank);
348 
349  // List of parameters of a declaration (here not stored)
350  parameters = element[boost::bind(&Sim2DocBuddy::clearParsedParam, self.mp_Owner)]
351  >> *(',' >> element[boost::bind(&Sim2DocBuddy::clearParsedParam, self.mp_Owner)]);
352 
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 #endif /* !defined(OPENFLUID_OS_MAC) */
443 
444 #endif /* __OPENFLUID_BUDDIES_SIM2DOCBUDDY_HPP__ */
SimSignatureGrammar(Sim2DocBuddy *Owner)
Definition: Sim2DocBuddy.hpp:239
definition(SimSignatureGrammar const &self)
Definition: Sim2DocBuddy.hpp:265
rule< ScannerT > const & start() const
Definition: Sim2DocBuddy.hpp:433
Definition: OpenFLUIDBuddy.hpp:55
Sim2DocBuddy * mp_Owner
Definition: Sim2DocBuddy.hpp:238
Definition: ExternalProgram.hpp:53
Definition: Sim2DocBuddy.hpp:71
Definition: SimulatorSignature.hpp:223
std::vector< SignatureUnitsClassItem > UpdatedUnitsClass
Definition: SimulatorSignature.hpp:229
Definition: ApplicationException.hpp:47
rule< ScannerT > VersionRule
Definition: Sim2DocBuddy.hpp:246
#define OPENFLUID_API
Definition: dllexport.hpp:87
Definition: BuddiesListener.hpp:55
Definition: SimulatorSignature.hpp:250
std::string UpdatedUnitsGraph
Definition: SimulatorSignature.hpp:227