SEvMgr Logo  1.00.0
C++ Simulation-Oriented Discrete Event Management Library
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros Pages
sevmgr.cpp
Go to the documentation of this file.
1 
5 // STL
6 #include <cassert>
7 #include <iostream>
8 #include <sstream>
9 #include <fstream>
10 #include <string>
11 // Boost (Extended STL)
12 #include <boost/program_options.hpp>
13 #include <boost/tokenizer.hpp>
14 #include <boost/regex.hpp>
15 #include <boost/swap.hpp>
16 #include <boost/algorithm/string/case_conv.hpp>
17 // StdAir
18 #include <stdair/stdair_exceptions.hpp>
19 #include <stdair/basic/BasLogParams.hpp>
20 #include <stdair/basic/BasDBParams.hpp>
21 #include <stdair/service/Logger.hpp>
22 #include <stdair/bom/BookingRequestStruct.hpp>
23 #include <stdair/bom/BookingRequestTypes.hpp>
24 #include <stdair/basic/ProgressStatusSet.hpp>
25 #include <stdair/bom/EventStruct.hpp>
26 // GNU Readline Wrapper
27 #include <stdair/ui/cmdline/SReadline.hpp>
28 // SEvMgr
30 #include <sevmgr/config/sevmgr-paths.hpp>
31 
32 // //////// Constants //////
36 const std::string K_SEVMGR_DEFAULT_LOG_FILENAME ("sevmgr.log");
37 
41 const int K_SEVMGR_EARLY_RETURN_STATUS = 99;
42 
47 typedef std::vector<std::string> TokenList_T;
48 
52 struct Command_T {
53  typedef enum {
54  NOP = 0,
55  QUIT,
56  HELP,
57  LIST,
58  DISPLAY,
59  SELECT,
60  NEXT,
61  RUN,
62  JSON_LIST,
63  JSON_DISPLAY,
64  LAST_VALUE
65  } Type_T;
66 };
67 
68 // ///////// Parsing of Options & Configuration /////////
69 // A helper function to simplify the main part.
70 template<class T> std::ostream& operator<< (std::ostream& os,
71  const std::vector<T>& v) {
72  std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout, " "));
73  return os;
74 }
75 
79 int readConfiguration (int argc, char* argv[], std::string& ioLogFilename) {
80  // Declare a group of options that will be allowed only on command line
81  boost::program_options::options_description generic ("Generic options");
82  generic.add_options()
83  ("prefix", "print installation prefix")
84  ("version,v", "print version string")
85  ("help,h", "produce help message");
86 
87  // Declare a group of options that will be allowed both on command
88  // line and in config file
89 
90  boost::program_options::options_description config ("Configuration");
91  config.add_options()
92  ("log,l",
93  boost::program_options::value< std::string >(&ioLogFilename)->default_value(K_SEVMGR_DEFAULT_LOG_FILENAME),
94  "Filename for the logs")
95  ;
96 
97  // Hidden options, will be allowed both on command line and
98  // in config file, but will not be shown to the user.
99  boost::program_options::options_description hidden ("Hidden options");
100  hidden.add_options()
101  ("copyright",
102  boost::program_options::value< std::vector<std::string> >(),
103  "Show the copyright (license)");
104 
105  boost::program_options::options_description cmdline_options;
106  cmdline_options.add(generic).add(config).add(hidden);
107 
108  boost::program_options::options_description config_file_options;
109  config_file_options.add(config).add(hidden);
110  boost::program_options::options_description visible ("Allowed options");
111  visible.add(generic).add(config);
112 
113  boost::program_options::positional_options_description p;
114  p.add ("copyright", -1);
115 
116  boost::program_options::variables_map vm;
117  boost::program_options::
118  store (boost::program_options::command_line_parser (argc, argv).
119  options (cmdline_options).positional(p).run(), vm);
120 
121  std::ifstream ifs ("sevmgr.cfg");
122  boost::program_options::store (parse_config_file (ifs, config_file_options),
123  vm);
124  boost::program_options::notify (vm);
125 
126  if (vm.count ("help")) {
127  std::cout << visible << std::endl;
129  }
130 
131  if (vm.count ("version")) {
132  std::cout << PACKAGE_NAME << ", version " << PACKAGE_VERSION << std::endl;
134  }
135 
136  if (vm.count ("prefix")) {
137  std::cout << "Installation prefix: " << PREFIXDIR << std::endl;
139  }
140 
141  if (vm.count ("log")) {
142  ioLogFilename = vm["log"].as< std::string >();
143  std::cout << "Log filename is: " << ioLogFilename << std::endl;
144  }
145 
146  return 0;
147 }
148 
149 // //////////////////////////////////////////////////////////////////
150 void initReadline (swift::SReadline& ioInputReader) {
151 
152  // Prepare the list of my own completers
153  std::vector<std::string> Completers;
154 
155  // The following is supported:
156  // - "identifiers"
157  // - special identifier %file - means to perform a file name completion
158  Completers.push_back ("help");
159  Completers.push_back ("list");
160  Completers.push_back ("list BookingRequest");
161  Completers.push_back ("list BreakPoint");
162  Completers.push_back ("select %date %time");
163  Completers.push_back ("display");
164  Completers.push_back ("next");
165  Completers.push_back ("run");
166  Completers.push_back ("json_list");
167  Completers.push_back ("json_display");
168  Completers.push_back ("quit");
169 
170 
171  // Now register the completers.
172  // Actually it is possible to re-register another set at any time
173  ioInputReader.RegisterCompletions (Completers);
174 }
175 
176 // //////////////////////////////////////////////////////////////////
177 void parseEventDateTime (const TokenList_T& iTokenList,
178  stdair::Date_T& ioEventDate,
179  stdair::Duration_T& ioEventTime) {
180  //
181  const std::string kMonthStr[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
182  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
183  //
184  unsigned short ioEventDateYear = ioEventDate.year();
185  unsigned short ioEventDateMonth = ioEventDate.month();
186  std::string ioEventDateMonthStr = kMonthStr[ioEventDateMonth-1];
187  unsigned short ioEventDateDay = ioEventDate.day();
188  //
189  unsigned short ioEventTimeHours = ioEventTime.hours();
190  unsigned short ioEventTimeMinutes = ioEventTime.minutes();
191  unsigned short ioEventTimeSeconds = ioEventTime.seconds();
192 
193  // Interpret the user input
194  if (iTokenList.empty() == false) {
195 
196  // Read the date year
197  TokenList_T::const_iterator itTok = iTokenList.begin();
198 
199  // Read the year for the event date
200  if (itTok != iTokenList.end()) {
201 
202  if (itTok->empty() == false) {
203  try {
204 
205  ioEventDateYear = boost::lexical_cast<unsigned short> (*itTok);
206  if (ioEventDateYear < 100) {
207  ioEventDateYear += 2000;
208  }
209 
210  } catch (boost::bad_lexical_cast& eCast) {
211  std::cerr << "The year of the event date ('" << *itTok
212  << "') cannot be understood. The default value ("
213  << ioEventDateYear << ") is kept. " << std::endl;
214  return;
215  }
216  }
217 
218  } else {
219  return;
220  }
221 
222  // Read the month for the event date
223  ++itTok;
224  if (itTok != iTokenList.end()) {
225 
226  if (itTok->empty() == false) {
227  try {
228 
229  const boost::regex lMonthRegex ("^(\\d{1,2})$");
230  const bool isMonthANumber = regex_match (*itTok, lMonthRegex);
231 
232  if (isMonthANumber == true) {
233  const unsigned short lMonth =
234  boost::lexical_cast<unsigned short> (*itTok);
235  if (lMonth > 12) {
236  throw boost::bad_lexical_cast();
237  }
238  ioEventDateMonthStr = kMonthStr[lMonth-1];
239 
240  } else {
241  const std::string lMonthStr (*itTok);
242  if (lMonthStr.size() < 3) {
243  throw boost::bad_lexical_cast();
244  }
245  std::string lMonthStr1 (lMonthStr.substr (0, 1));
246  boost::algorithm::to_upper (lMonthStr1);
247  std::string lMonthStr23 (lMonthStr.substr (1, 2));
248  boost::algorithm::to_lower (lMonthStr23);
249  ioEventDateMonthStr = lMonthStr1 + lMonthStr23;
250  }
251 
252  } catch (boost::bad_lexical_cast& eCast) {
253  std::cerr << "The month of the event date ('" << *itTok
254  << "') cannot be understood. The default value ("
255  << ioEventDateMonthStr << ") is kept. " << std::endl;
256  return;
257  }
258  }
259  }
260 
261  // Read the day for the event date
262  ++itTok;
263  if (itTok != iTokenList.end()) {
264 
265  if (itTok->empty() == false) {
266  try {
267 
268  ioEventDateDay = boost::lexical_cast<unsigned short> (*itTok);
269 
270  } catch (boost::bad_lexical_cast& eCast) {
271  std::cerr << "The day of the event date ('" << *itTok
272  << "') cannot be understood. The default value ("
273  << ioEventDateDay << ") is kept. " << std::endl;
274  return;
275  }
276  }
277 
278  } else {
279  return;
280  }
281 
282  // Re-compose the event date
283  std::ostringstream lEventDateStr;
284  lEventDateStr << ioEventDateYear << "-" << ioEventDateMonthStr
285  << "-" << ioEventDateDay;
286 
287  try {
288 
289  ioEventDate =
290  boost::gregorian::from_simple_string (lEventDateStr.str());
291 
292  } catch (boost::gregorian::bad_month& eCast) {
293  std::cerr << "The event date ('" << lEventDateStr.str()
294  << "') cannot be understood. The default value ("
295  << ioEventDate << ") is kept. " << std::endl;
296  return;
297  }
298 
299  // Read the hours of the event time
300  ++itTok;
301  if (itTok != iTokenList.end()) {
302 
303  if (itTok->empty() == false) {
304  try {
305 
306  ioEventTimeHours = boost::lexical_cast<unsigned short> (*itTok);
307 
308  } catch (boost::bad_lexical_cast& eCast) {
309  std::cerr << "The hours of the event time ('" << *itTok
310  << "') cannot be understood. The default value ("
311  << ioEventTimeHours << ") is kept. " << std::endl;
312  return;
313  }
314  }
315 
316  } else {
317  return;
318  }
319 
320  // Read the minutes of the event time
321  ++itTok;
322  if (itTok != iTokenList.end()) {
323 
324  if (itTok->empty() == false) {
325  try {
326 
327  ioEventTimeMinutes = boost::lexical_cast<unsigned short> (*itTok);
328 
329  } catch (boost::bad_lexical_cast& eCast) {
330  std::cerr << "The minutes of the event time ('" << *itTok
331  << "') cannot be understood. The default value ("
332  << ioEventTimeMinutes << ") is kept. " << std::endl;
333  return;
334  }
335  }
336 
337  } else {
338  return;
339  }
340 
341  // Read the seconds of the event time
342  ++itTok;
343  if (itTok != iTokenList.end()) {
344 
345  if (itTok->empty() == false) {
346  try {
347 
348  ioEventTimeSeconds = boost::lexical_cast<unsigned short> (*itTok);
349 
350  } catch (boost::bad_lexical_cast& eCast) {
351  std::cerr << "The seconds of the event time ('" << *itTok
352  << "') cannot be understood. The default value ("
353  << ioEventTimeSeconds << ") is kept. " << std::endl;
354  return;
355  }
356  }
357 
358  } else {
359  return;
360  }
361 
362  // Re-compose the event time
363  std::ostringstream lEventTimeStr;
364  lEventTimeStr << ioEventTimeHours << ":" << ioEventTimeMinutes
365  << ":" << ioEventTimeSeconds;
366 
367  try {
368 
369  ioEventTime =
370  boost::posix_time::duration_from_string (lEventTimeStr.str());
371 
372  } catch (boost::gregorian::bad_month& eCast) {
373  std::cerr << "The event time ('" << lEventTimeStr.str()
374  << "') cannot be understood. The default value ("
375  << ioEventTime << ") is kept. " << std::endl;
376  return;
377  }
378 
379  }
380 
381 }
382 
383 // //////////////////////////////////////////////////////////////////
384 Command_T::Type_T extractCommand (TokenList_T& ioTokenList) {
385  Command_T::Type_T oCommandType = Command_T::LAST_VALUE;
386 
387  // Interpret the user input
388  if (ioTokenList.empty() == false) {
389  TokenList_T::iterator itTok = ioTokenList.begin();
390  std::string lCommand (*itTok);
391  boost::algorithm::to_lower (lCommand);
392 
393  if (lCommand == "help") {
394  oCommandType = Command_T::HELP;
395 
396  } else if (lCommand == "list") {
397  oCommandType = Command_T::LIST;
398 
399  } else if (lCommand == "display") {
400  oCommandType = Command_T::DISPLAY;
401 
402  } else if (lCommand == "select") {
403  oCommandType = Command_T::SELECT;
404 
405  } else if (lCommand == "next") {
406  oCommandType = Command_T::NEXT;
407 
408  } else if (lCommand == "run") {
409  oCommandType = Command_T::RUN;
410 
411  } else if (lCommand == "json_list") {
412  oCommandType = Command_T::JSON_LIST;
413 
414  } else if (lCommand == "json_display") {
415  oCommandType = Command_T::JSON_DISPLAY;
416 
417  } else if (lCommand == "quit") {
418  oCommandType = Command_T::QUIT;
419  }
420 
421  // Remove the first token (the command), as the corresponding information
422  // has been extracted in the form of the returned command type enumeration
423  ioTokenList.erase (itTok);
424 
425  } else {
426  oCommandType = Command_T::NOP;
427  }
428 
429  return oCommandType;
430 }
431 
432 // /////////////////////////////////////////////////////////
433 std::string toString (const TokenList_T& iTokenList) {
434  std::ostringstream oStr;
435 
436  // Re-create the string with all the tokens, trimmed by read-line
437  unsigned short idx = 0;
438  for (TokenList_T::const_iterator itTok = iTokenList.begin();
439  itTok != iTokenList.end(); ++itTok, ++idx) {
440  if (idx != 0) {
441  oStr << " ";
442  }
443  oStr << *itTok;
444  }
445 
446  return oStr.str();
447 }
448 
449 // /////////////////////////////////////////////////////////
450 TokenList_T extractTokenList (const TokenList_T& iTokenList,
451  const std::string& iRegularExpression) {
452  TokenList_T oTokenList;
453 
454  // Re-create the string with all the tokens (which had been trimmed
455  // by read-line)
456  const std::string lFullLine = toString (iTokenList);
457 
458  // See the caller for the regular expression
459  boost::regex expression (iRegularExpression);
460 
461  std::string::const_iterator start = lFullLine.begin();
462  std::string::const_iterator end = lFullLine.end();
463 
464  boost::match_results<std::string::const_iterator> what;
465  boost::match_flag_type flags = boost::match_default | boost::format_sed;
466  regex_search (start, end, what, expression, flags);
467 
468  // Put the matched strings in the list of tokens to be returned back
469  // to the caller
470  const unsigned short lMatchSetSize = what.size();
471  for (unsigned short matchIdx = 1; matchIdx != lMatchSetSize; ++matchIdx) {
472  const std::string lMatchedString (std::string (what[matchIdx].first,
473  what[matchIdx].second));
474  //if (lMatchedString.empty() == false) {
475  oTokenList.push_back (lMatchedString);
476  //}
477  }
478 
479  // DEBUG
480  // std::cout << "After (token list): " << oTokenList << std::endl;
481 
482  return oTokenList;
483 }
484 
485 // /////////////////////////////////////////////////////////
486 TokenList_T extractTokenListForDateTime (const TokenList_T& iTokenList) {
499  const std::string lRegEx("^([[:digit:]]{2,4})?[/-]?[[:space:]]*"
500  "([[:alpha:]]{3}|[[:digit:]]{1,2})?[/-]?[[:space:]]*"
501  "([[:digit:]]{1,2})?[[:space:]]*"
502  "([[:digit:]]{1,2})?[:-]?[[:space:]]*"
503  "([[:alpha:]]{3}|[[:digit:]]{1,2})?[:-]?[[:space:]]*"
504  "([[:digit:]]{1,2})?[[:space:]]*$");
505 
506  //
507  const TokenList_T& oTokenList = extractTokenList (iTokenList, lRegEx);
508  return oTokenList;
509 }
510 
511 // ///////// M A I N ////////////
512 int main (int argc, char* argv[]) {
513 
514  // Readline history
515  const unsigned int lHistorySize (100);
516  const std::string lHistoryFilename ("sevmgr.hist");
517  const std::string lHistoryBackupFilename ("sevmgr.hist.bak");
518 
519  // Default parameters for the interactive session
520  stdair::EventStruct lCurrentInteractiveEventStruct;
521  stdair::DateTime_T lCurrentInteractiveDateTime;
522  stdair::EventType::EN_EventType lCurrentInteractiveEventType;
523 
524  // Output log File
525  stdair::Filename_T lLogFilename;
526 
527  // Call the command-line option parser
528  const int lOptionParserStatus = readConfiguration (argc, argv, lLogFilename);
529 
530  if (lOptionParserStatus == K_SEVMGR_EARLY_RETURN_STATUS) {
531  return 0;
532  }
533 
534  // Set the log parameters
535  std::ofstream logOutputFile;
536  // Open and clean the log outputfile
537  logOutputFile.open (lLogFilename.c_str());
538  logOutputFile.clear();
539 
540  // Initialise the inventory service
541  const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
542  SEVMGR::SEVMGR_Service sevmgrService (lLogParams);
543 
544  // Build the sample event queue.
545  sevmgrService.buildSampleQueue();
546 
547  // Pop out the first event from the queue.
548  sevmgrService.popEvent(lCurrentInteractiveEventStruct);
549 
550  // DEBUG
551  STDAIR_LOG_DEBUG ("====================================================");
552  STDAIR_LOG_DEBUG ("= Beginning of the interactive session =");
553  STDAIR_LOG_DEBUG ("====================================================");
554 
555  // Initialise the GNU readline wrapper
556  swift::SReadline lReader (lHistoryFilename, lHistorySize);
557  initReadline (lReader);
558 
559  // Now we can ask user for a line
560  std::string lUserInput;
561  bool EndOfInput (false);
562  Command_T::Type_T lCommandType (Command_T::NOP);
563 
564  while (lCommandType != Command_T::QUIT && EndOfInput == false) {
565 
566  // Update the interactive parameters which have not been updated yet
567  lCurrentInteractiveDateTime = lCurrentInteractiveEventStruct.getEventTime ();
568  lCurrentInteractiveEventType = lCurrentInteractiveEventStruct.getEventType ();
569 
570  // Prompt
571  std::ostringstream oPromptStr;
572  oPromptStr << "sevmgr "
573  << stdair::EventType::getTypeLabelAsString(lCurrentInteractiveEventType)
574  << " / " << lCurrentInteractiveDateTime << "> " ;
575  // Call read-line, which will fill the list of tokens
576  TokenList_T lTokenListByReadline;
577  lUserInput = lReader.GetLine (oPromptStr.str(), lTokenListByReadline,
578  EndOfInput);
579 
580  // The history can be saved to an arbitrary file at any time
581  lReader.SaveHistory (lHistoryBackupFilename);
582 
583  // The end-of-input typically corresponds to a CTRL-D typed by the user
584  if (EndOfInput) {
585  std::cout << std::endl;
586  break;
587  }
588 
589  // Interpret the user input
590  lCommandType = extractCommand (lTokenListByReadline);
591 
592  switch (lCommandType) {
593 
594  // ////////////////////////////// Help ////////////////////////
595  case Command_T::HELP: {
596  std::cout << std::endl;
597  std::cout << "Commands: " << std::endl;
598  std::cout << " help" << "\t\t" << "Display this help" << std::endl;
599  std::cout << " quit" << "\t\t" << "Quit the application" << std::endl;
600  std::cout << " list" << "\t\t" << "List events in the queue. It is "
601  << "possible to filter events according to their types"
602  << std::endl
603  << "\t\t\t\t 'list_event BookingRequest' "
604  << "list all the booking requests" << std::endl
605  << "\t\t\t\t 'list_event BreakPoint' "
606  << "list all the break points" << std::endl;
607  std::cout << " select" << "\t\t"
608  << "Select an event into the 'list' to become the current one. For instance, try the command:\n"
609  << "\t\t 'select 2011-May-14 00:00:00'"
610  << std::endl;
611  std::cout << " display" << "\t"
612  << "Display the current event" << std::endl;
613  std::cout << " next" << "\t\t"
614  << "Play the current event and pop the next one from the queue"
615  << std::endl;
616  std::cout << " run" << "\t\t"
617  << "Play all the events until the next break-point, if any"
618  << std::endl;
619  std::cout << " \nDebug Commands" << std::endl;
620  std::cout << " json_list" << "\t"
621  << "List events in the queue in a JSON format"
622  << std::endl;
623  std::cout << " json_display" << "\t"
624  << "Display the current event in a JSON format"
625  << std::endl;
626  std::cout << std::endl;
627  break;
628  }
629 
630  // ////////////////////////////// Quit ////////////////////////
631  case Command_T::QUIT: {
632  break;
633  }
634 
635  // ////////////////////////////// List /////////////////////////
636  case Command_T::LIST: {
637 
638  //
639  std::ostringstream oEventListStr;
640 
641  if (lTokenListByReadline.empty() == true) {
642 
643  // If no parameter is given, list all the events in the queue
644  oEventListStr << sevmgrService.list ();
645 
646  } else if (lTokenListByReadline.size() == 1) {
647 
648  assert (lTokenListByReadline.empty() == false);
649  const std::string lEventTypeStr (lTokenListByReadline[0]);
650 
651  // If exactly one parameter is given, try to convert it into
652  // an event type
653  try {
654 
655  const stdair::EventType lEventType (lEventTypeStr);
656  const stdair::EventType::EN_EventType& lActualEventType =
657  lEventType.getType();
658  oEventListStr << sevmgrService.list (lActualEventType);
659 
660  } catch (stdair::CodeConversionException e) {
661  oEventListStr << "The event type '" << lEventTypeStr
662  << "' is not known. Try 'help' for "
663  << "more information on the 'list_event' command."
664  << std::endl;
665  }
666  } else {
667 
668  // If more than one parameter is given, display an error message
669  oEventListStr << "The event type is not understood: try 'help' for "
670  << "more information on the 'list_event' command."
671  << std::endl;
672  }
673  std::cout << oEventListStr.str() << std::endl;
674  STDAIR_LOG_DEBUG (oEventListStr.str());
675 
676  //
677  break;
678  }
679 
680  // ////////////////////////////// Select ////////////////////////
681  case Command_T::SELECT: {
682 
683  //
684  TokenList_T lTokenList = extractTokenListForDateTime (lTokenListByReadline);
685  stdair::Date_T lUserDate = lCurrentInteractiveDateTime.date();
686  stdair::Duration_T lUserTime = lCurrentInteractiveDateTime.time_of_day();
687  parseEventDateTime (lTokenList, lUserDate, lUserTime);
688 
689  std::cout << "Try to select event: "
690  << lUserDate << " " << lUserTime
691  << std::endl;
692 
693  const stdair::DateTime_T lUserDateTime =
694  boost::posix_time::ptime (lUserDate, lUserTime);
695 
696  const bool hasSelectBeenSuccessful =
697  sevmgrService.select (lCurrentInteractiveEventStruct,
698  lUserDateTime);
699 
700  std::cout << "Selection successful: "
701  << hasSelectBeenSuccessful << std::endl;
702 
703  //
704  break;
705  }
706 
707  // ////////////////////////////// Display ////////////////////////
708  case Command_T::DISPLAY: {
709  //
710  std::cout << "Display" << std::endl;
711 
712  // DEBUG
713  std::ostringstream oEventStr;
714  oEventStr << lCurrentInteractiveEventStruct.describe();
715  std::cout << oEventStr.str() << std::endl;
716  STDAIR_LOG_DEBUG (oEventStr.str());
717 
718  //
719  break;
720  }
721 
722  // ////////////////////////////// Next ////////////////////////
723  case Command_T::NEXT: {
724  //
725  std::cout << "Next" << std::endl;
726 
727  if (sevmgrService.isQueueDone() == true) {
728 
729  // DEBUG
730  std::ostringstream oEmptyQueueStr;
731  oEmptyQueueStr << "The event queue is empty: no event can be popped out.";
732  std::cout << oEmptyQueueStr.str() << std::endl;
733  STDAIR_LOG_DEBUG (oEmptyQueueStr.str());
734 
735  //
736  break;
737 
738  }
739 
740  // Get the next event from the event queue
741  stdair::ProgressStatusSet lPPS =
742  sevmgrService.popEvent (lCurrentInteractiveEventStruct);
743 
744  // DEBUG
745  std::ostringstream oEventStr;
746  oEventStr << "Poped event: '"
747  << lCurrentInteractiveEventStruct.describe() << "'.";
748  std::cout << oEventStr.str() << std::endl;
749  STDAIR_LOG_DEBUG (oEventStr.str());
750 
751  //
752  break;
753  }
754 
755  // ////////////////////////////// Run ////////////////////////
756  case Command_T::RUN: {
757  //
758  std::cout << "Run" << std::endl;
759 
760  // Delegate the call to the dedicated service
761  sevmgrService.run (lCurrentInteractiveEventStruct);
762  lCurrentInteractiveEventType = lCurrentInteractiveEventStruct.getEventType ();
763 
764  // DEBUG
765  if (lCurrentInteractiveEventType == stdair::EventType::BRK_PT) {
766  std::ostringstream oBreakPointStr;
767  oBreakPointStr << "Break point found. Stop at: '"
768  << lCurrentInteractiveEventStruct.describe() << "'.";
769  std::cout << oBreakPointStr.str() << std::endl;
770  STDAIR_LOG_DEBUG (oBreakPointStr.str());
771  } else {
772  std::ostringstream oNoBreakPointStr;
773  oNoBreakPointStr << "No break point found. All the events have been played.\n"
774  << "The current event is the last one.";
775  std::cout << oNoBreakPointStr.str() << std::endl;
776  STDAIR_LOG_DEBUG (oNoBreakPointStr.str());
777  }
778 
779  //
780  break;
781  }
782 
783  // ////////////////////////////// JSon List ////////////////////////
784 
785  case Command_T::JSON_LIST: {
786  //
787  std::cout << "JSON List" << std::endl;
788 
789  // Delegate the call to the dedicated service
790  const std::string& lCSVEventQueueDumpAfter =
791  sevmgrService.jsonExportEventQueue ();
792 
793  // DEBUG: Display the events queue JSON string
794  std::cout << lCSVEventQueueDumpAfter << std::endl;
795  STDAIR_LOG_DEBUG (lCSVEventQueueDumpAfter);
796 
797  break;
798  }
799 
800  // ////////////////////////////// JSon Display ////////////////////////
801 
802  case Command_T::JSON_DISPLAY: {
803  //
804  std::cout << "JSON Display" << std::endl;
805 
806  // Delegate the call to the dedicated service
807  const std::string& lCSVEventDumpAfter =
808  sevmgrService.jsonExportEvent (lCurrentInteractiveEventStruct);
809 
810  // DEBUG: Display the event JSON string
811  std::cout << lCSVEventDumpAfter << std::endl;
812  STDAIR_LOG_DEBUG (lCSVEventDumpAfter);
813 
814  //
815  break;
816  }
817 
818  // /////////////////////////// Default / No value ///////////////////////
819  case Command_T::NOP: {
820  break;
821  }
822 
823  case Command_T::LAST_VALUE:
824  default: {
825  // DEBUG
826  std::ostringstream oStr;
827  oStr << "That command is not yet understood: '" << lUserInput
828  << "' => " << lTokenListByReadline;
829  STDAIR_LOG_DEBUG (oStr.str());
830  std::cout << oStr.str() << std::endl;
831  }
832  }
833  }
834 
835  // DEBUG
836  STDAIR_LOG_DEBUG ("End of the session. Exiting.");
837  std::cout << "End of the session. Exiting." << std::endl;
838 
839  // Close the Log outputFile
840  logOutputFile.close();
841 
842  /*
843  Note: as that program is not intended to be run on a server in
844  production, it is better not to catch the exceptions. When it
845  happens (that an exception is throwned), that way we get the
846  call stack.
847  */
848 
849  return 0;
850 }