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