CASToR  3.0
Tomographic Reconstruction (PET/SPECT/CT)
gOptions.cc
Go to the documentation of this file.
1 /*
2 This file is part of CASToR.
3 
4  CASToR is free software: you can redistribute it and/or modify it under the
5  terms of the GNU General Public License as published by the Free Software
6  Foundation, either version 3 of the License, or (at your option) any later
7  version.
8 
9  CASToR is distributed in the hope that it will be useful, but WITHOUT ANY
10  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  details.
13 
14  You should have received a copy of the GNU General Public License along with
15  CASToR (in file GNU_GPL.TXT). If not, see <http://www.gnu.org/licenses/>.
16 
17 Copyright 2017-2019 all CASToR contributors listed below:
18 
19  --> Didier BENOIT, Claude COMTAT, Marina FILIPOVIC, Thibaut MERLIN, Mael MILLARDET, Simon STUTE, Valentin VIELZEUF
20 
21 This is CASToR version 3.0.
22 */
23 
31 #include "gVariables.hh"
32 #include "gOptions.hh"
33 #include "sOutputManager.hh"
34 // For error handling
35 #include <errno.h>
36 #include <limits.h>
37 #ifdef _WIN32
38 // Avoid compilation errors due to mix up between std::min()/max() and
39 // min max macros
40 #undef min
41 #undef max
42 #endif
43 
44 // =====================================================================
45 // ---------------------------------------------------------------------
46 // ---------------------------------------------------------------------
47 // =====================================================================
48 
49 template<class T>
50 int ReadStringOption(const string& a_input, T* ap_return, int a_nbElts, const string& a_sep, const string& a_option)
51 {
52  // If number of elements is negative or null, then exit
53  if (a_nbElts<=0) return 0;
54  // Check that the separator is not empty
55  if (a_sep=="")
56  {
57  Cerr("***** gOptions::ReadStringOption() -> Separator is empty while reading option '" << a_option << "' !" << endl);
58  return 1;
59  }
60  // Count the number of separators in the input string
61  int nb_sep = 0;
62  string tmp_input = a_input;
63  size_t pos = 0;
64  while ((pos=tmp_input.find_first_of(a_sep,0))!=string::npos)
65  {
66  tmp_input = tmp_input.substr(pos+1);
67  nb_sep++;
68  }
69  // Check for too many parameters
70  if (nb_sep>a_nbElts-1)
71  {
72  Cerr("***** gOptions::ReadStringOption() -> Too many parameters in '" << a_input << "' while reading option '" << a_option << "' (expecting " << a_nbElts << ") !" << endl);
73  return 1;
74  }
75  // Check for not enough parameters
76  if (nb_sep<a_nbElts-1)
77  {
78  Cerr("***** gOptions::ReadStringOption() -> Not enough parameters in '" << a_input << "' while reading option '" << a_option << "' (expecting " << a_nbElts << ") !" << endl);
79  return 1;
80  }
81  // Loop on elements to be read
82  size_t pos1 = 0;
83  size_t pos2 = a_input.find_first_of(a_sep, 0);
84  for (int i=0; i<a_nbElts; i++)
85  {
86  // Extract element and convert the parameter
87  string elt = a_input.substr(pos1, pos2-pos1);
88  if (ConvertFromString(elt, &ap_return[i]))
89  {
90  Cerr("***** gOptions::ReadStringOption() -> Error when trying to read input data for option '" << a_option << "' !" << endl);
91  return 1;
92  }
93  pos1 = pos2+1;
94  pos2 = a_input.find_first_of(a_sep, pos1);
95  }
96  // Normal end
97  return 0;
98 }
99 
100 
101 
102 
103 // =====================================================================
104 // ---------------------------------------------------------------------
105 // ---------------------------------------------------------------------
106 // =====================================================================
107 /*
108  \fn ReadDataASCIIFile
109  \param a_file : string containing the path to the ASCII file
110  \param a_keyword : key related to the data we want to recover
111  \param ap_return : templated array in which the data will be returned
112  the recovered data will be converted to its type
113  its size should be equal to the number of elts to recover
114  \param a_nbElts : number of elements to recover
115  \param a_mandatoryFlag : boolean indicating the data to recover is
116  mandatory (KEYWORD_MANDATORY) (error value (=1) will be returned if not found)
117  or optional (KEYWORD_OPTIONAL) (warning value (=2) will be returned if not found)
118  \brief Look for "a_nbElts" elts in the "a_file" file matching the "a_keyword" string passed as parameter
119  and return the corresponding value(s) in the "ap_return" templated array.
120  This function expects the following parsing :
121  KEY : elt1,elt2,...,eltN
122  \details This function assumes the following separators :
123  ":" is used as separator between the keyworld and the value
124  "#" is used for comment. Every following characters will be discarded
125  "," is used to separate elements if more than one are required
126  \return 0 if success, and positive value otherwise (1 if error, 2 if tag not found).
127 */
128 template<class T>
129 int ReadDataASCIIFile(const string& a_file, const string& a_keyword, T* ap_return, int a_nbElts, bool a_mandatoryFlag)
130 {
131  ifstream input_file(a_file.c_str(), ios::in);
132  string line;
133  string sep = ":";
134  string sep_comment = "#";
135  string sep_elt = ",";
136 
137  // Check file
138  if (input_file)
139  {
140  while(!input_file.eof())
141  {
142  getline(input_file, line);
143 
144  //remove comment
145  if (line.find(sep_comment) != string::npos) line = line.substr(0, line.find_first_of(sep_comment)) ;
146 
147  if (line.find(a_keyword) != string::npos)
148  //if (line.compare(a_keyword) == 0)
149  {
150  //remove field in string
151  line = line.substr(line.find_first_of(sep)+1);
152 
153  //clear every spaces in the line string;
154  //line.erase(remove_if(line.begin(), line.end(), (int(*)(int))isspace), line.end()); // Explicit type (int(*)(int)) is required to tell compiler which function to take the address of.
155 
156  // Erase all blank stuff before first character
157  line.erase(0, line.find_first_not_of(" !\t\r\n")); // Erase all blank stuff before first character
158  line.erase(line.find_last_not_of(" \t\r\n")+1 , line.length());
159 
160  size_t pos = 0;
161  size_t pos2 = line.find_first_of(sep_elt, pos);
162 
163  // Check if separators were found
164  if (a_nbElts>1 && pos2 == string::npos)
165  {
166  Cerr("***** gOptions::ReadDataASCIIFile() -> The required separator : '" << sep_elt << "' not found for tag: " << a_keyword << endl);
167  return 1;
168  }
169  else // Read one element, or several (a_nbElts) elements separated with ','
170  {
171  for (int i=0 ; i<a_nbElts ; i++)
172  {
173  // Check if we reach the end of the line before initializing all elements
174  // SS: corrected this incorrect line: if(pos<0)
175  if (pos==string::npos)
176  {
177  Cerr("***** gOptions::ReadDataASCIIFile() -> Exception when trying to read tag '" << a_keyword << "' in file '" << a_file << "'." << endl);
178  Cerr("***** Expected to read " << a_nbElts << " elements, but only " << i+1 << " were found." << endl);
179  return 1;
180  }
181 
182  // Parse the line only if more than 1 elt are requested. Just pick the line otherwise
183  string elt = (a_nbElts>1) ? line.substr(pos, pos2-pos) : line ;
184 
185  if (ConvertFromString(elt, &ap_return[i]))
186  {
187  Cerr("***** gOptions::ReadDataASCIIFile() -> Exception when trying to read tag '" << a_keyword << "' in file '" << a_file << "'." << endl);
188  return 1;
189  }
190 
191 
192  //pos = pos2+1;
193  // return string::npos if pos2 not found, meaning we reach the end of the line
194  // SS: corrected this incorrect line pos = (pos2<0) ? -1 : pos2+1 ;
195  pos = (pos2==string::npos) ? string::npos : pos2+1;
196  pos2 = line.find_first_of(sep_elt, pos);
197 
198  }
199  }
200  return 0;
201  }
202 
203  }
204  // Throw an error message if the tag is mandatory
205  if (a_mandatoryFlag == true)
206  {
207  Cerr("***** gOptions::ReadDataASCIIFile() -> Error when reading file '" << a_file << "'. Tag '" << a_keyword << "' was not found." << endl);
209  }
210  else
211  {
213  }
214  }
215  else
216  {
217  Cerr("***** gOptions::ReadDataASCIIFile() -> Couldn't find or read data-file '"<< a_file << "' !" << endl);
218  return 1;
219  }
220 }
221 
222 
223 
224 
225 // =====================================================================
226 // ---------------------------------------------------------------------
227 // ---------------------------------------------------------------------
228 // =====================================================================
229 /*
230  \fn ReadDataASCIIFile
231  \param a_file : string containing the path to the ASCII file
232  \param a_keyword : key related to the data we want to recover
233  \param ap_return : templated array in which the data will be returned
234  the recovered data will be converted to its type
235  its size should be equal to the nb of lines*nb of elts to recover
236  \param a_nbElts : number of elements to recover (on each line)
237  \param a_nbLines : number of lines to recover
238  \param a_mandatoryFlag : boolean indicating the data to recover is
239  mandatory (KEYWORD_MANDATORY) (error value (=1) will be returned if not found)
240  or optional (KEYWORD_OPTIONAL) (warning value (=2) will be returned if not found)
241  \brief Look for "a_nbLines" lines of "a_nbElts" elts in the 'a_file' file matching the "a_keyword" string
242  passed as parameter and return the corresponding value(s) in the "ap_return" templated 1D array.
243  This function expects the following parsing :
244  KEY :
245  line1 : elt1,elt2,...,eltN
246  line2 : elt1,elt2,...,eltN
247  (...)
248  lineN : elt1,elt2,...,eltN
249  \details This function assumes the following separators :
250  ":" is used as separator between the keyworld and the value
251  "#" is used for comment. Every following characters will be discarded
252  "," is used to separate elements if more than one are required
253  \return 0 if success, and positive value otherwise (1 if error, 2 if tag not found).
254 */
255 template<class T>
256 int ReadDataASCIIFile(const string& a_file, const string& a_keyword, T* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag)
257 {
258  ifstream input_file(a_file.c_str(), ios::in);
259  string line;
260  string sep = ":";
261  string sep_comment = "#";
262  string sep_elt = ",";
263 
264  // Check file
265  if (input_file)
266  {
267  while (!input_file.eof())
268  {
269  getline(input_file, line);
270 
271  //remove comment
272  if (line.find(sep_comment) != string::npos) line = line.substr(0, line.find_first_of(sep_comment));
273 
274  if (line.find(a_keyword) != string::npos)
275  //if (line.compare(a_keyword) == 0)
276  {
277  for (int l=0 ; l<a_nbLines ; l++)
278  {
279  getline(input_file, line);
280  //remove field in string
281  line = line.substr(line.find_first_of(sep)+1);
282 
283  //clear the space before the first element in the line string;
284  //line.erase(remove_if(line.begin(), line.end(), (int(*)(int))isspace), line.end()); // Explicit type (int(*)(int)) is required to tell compiler which function to take the address of.
285 
286  // Erase all blank stuff before first character
287  line.erase(0, line.find_first_not_of(" !\t\r\n")); // Erase all blank stuff before first character
288  line.erase(line.find_last_not_of(" \t\r\n")+1 , line.length());
289 
290  size_t pos = 0;
291  size_t pos2 = line.find_first_of(sep_elt, pos);
292 
293  // Check if separators were found
294  if (a_nbElts>1 && pos2 == string::npos)
295  {
296  Cerr("***** gOptions::ReadDataASCIIFile() -> The required separator : '" << sep_elt << "' not found for tag: " << a_keyword << endl);
297  return 1;
298  }
299  else // Read one element, or several (a_nbElts) elements separated with ','
300  {
301  for (int i=0 ; i<a_nbElts ; i++)
302  {
303  // Check if we reach the end of the line before initializing all elements
304  // SS: corrected this incorrect line: if(pos<0)
305  if (pos==string::npos)
306  {
307  Cerr("***** gOptions::ReadDataASCIIFile() -> Exception when trying to read tag '" << a_keyword << "' in file '" << a_file << "'." << endl);
308  Cerr("***** Expected to read " << a_nbElts << " elements, but only " << i+1 << " were found." << endl);
309  return 1;
310  }
311 
312  // Parse the line only if more than 1 elt are requested. Just pick the line otherwise
313  string elt = (a_nbElts>1) ? line.substr(pos, pos2-pos) : line ;
314 
315  if (ConvertFromString(elt, &ap_return[l*a_nbElts+i]))
316  {
317  Cerr("***** gOptions::ReadDataASCIIFile() -> Exception when trying to read tag '" << a_keyword << "' in file " << a_file << endl);
318  return 1;
319  }
320 
321  //pos = pos2+1;
322  // return string::npos if pos2 not found, meaning we reach the end of the line
323  // SS: corrected this incorrect line pos = (pos2<0) ? -1 : pos2+1 ;
324  pos = (pos2==string::npos) ? string::npos : pos2+1;
325  pos2 = line.find_first_of(sep_elt, pos);
326  }
327  }
328  }
329  return 0;
330  }
331  }
332 
333  // Throw an error message if the tag is mandatory
334  if (a_mandatoryFlag == true)
335  {
336  Cerr("***** gOptions::ReadDataASCIIFile() -> Error when reading file '" << a_file << "'. Tag '" << a_keyword << "' was not found." << endl);
338  }
339  else
340  {
342  }
343  }
344  else
345  {
346  Cerr("***** gOptions::ReadDataASCIIFile() -> Couldn't find or read data-file '" << a_file << "' !" << endl);
347  return 1;
348  }
349 }
350 
351 
352 
353 
354 // =====================================================================
355 // ---------------------------------------------------------------------
356 // ---------------------------------------------------------------------
357 // =====================================================================
358 /*
359  \fn ReadDataASCIIFile
360  \param a_file : string containing the path to the ASCII file
361  \param a_keyword : key related to the data we want to recover
362  \param a2p_return : 2D templated array in which the data will be returned
363  the recovered data will be converted to its type
364  its size should be equal [nb of lines][nb of elts to recover]
365  \param a_nbElts : number of elements to recover (on each line)
366  \param a_nbLines : number of lines to recover
367  \param a_mandatoryFlag : boolean indicating the data to recover is
368  mandatory (KEYWORD_MANDATORY) (error value (=1) will be returned if not found)
369  or optional (KEYWORD_OPTIONAL) (warning value (=2) will be returned if not found)
370  \brief Look for "a_nbLines" lines of "a_nbElts" elts in the 'a_file' file matching the "a_keyword" string
371  passed as parameter and return the corresponding value(s) in the "a2p_return" 2D array.
372  The first and second dimensions of "a2p_return" correspond to the line and elements respectively
373  This function expects the following parsing :
374  KEY :
375  line1 : elt1,elt2,...,eltN
376  line2 : elt1,elt2,...,eltN
377  (...)
378  lineN : elt1,elt2,...,eltN
379  \details This function assumes the following separators :
380  ":" is used as separator between the keyworld and the value
381  "#" is used for comment. Every following characters will be discarded
382  "," is used to separate elements if more than one are required
383  \return 0 if success, and positive value otherwise (1 if error, 2 if tag not found).
384 */
385 template<class T>
386 int ReadDataASCIIFile(const string& a_file, const string& a_keyword, T** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag)
387 {
388  ifstream input_file(a_file.c_str(), ios::in);
389  string line;
390  string sep = ":";
391  string sep_comment = "#";
392  string sep_elt = ",";
393 
394  // Check file
395  if (input_file)
396  {
397  while (!input_file.eof())
398  {
399  getline(input_file, line);
400 
401  //remove comment
402 
403  if (line.find(sep_comment) != string::npos) line = line.substr(0, line.find_first_of(sep_comment));
404 
405  if (line.find(a_keyword) != string::npos)
406  //if (line.compare(a_keyword) == 0)
407  {
408  for (int l=0 ; l<a_nbLines ; l++)
409  {
410  getline(input_file, line);
411 
412  //remove field in string
413  line = line.substr(line.find_first_of(sep)+1);
414 
415  //clear the space before the first element in the line string;
416  //line.erase(remove_if(line.begin(), line.end(), (int(*)(int))isspace), line.end()); // Explicit type (int(*)(int)) is required to tell compiler which function to take the address of.
417 
418  // Erase all blank stuff before first character
419  line.erase(0, line.find_first_not_of(" !\t\r\n")); // Erase all blank stuff before first character
420  line.erase(line.find_last_not_of(" \t\r\n")+1 , line.length());
421 
422  size_t pos = 0;
423  size_t pos2 = line.find_first_of(sep_elt, pos);
424 
425  // Check if separators were found
426  if (a_nbElts>1 && pos2 == string::npos)
427  {
428  Cerr("***** gOptions::ReadDataASCIIFile() -> The required separator : '" << sep_elt << "' not found for tag: " << a_keyword << endl);
429  return 1;
430  }
431  else // Read one element, or several (a_nbElts) elements separated with ','
432  {
433  for (int i=0 ; i<a_nbElts ; i++)
434  {
435  // Check if we reach the end of the line before initializing all elements
436  // SS: corrected this incorrect line: if(pos<0)
437  if (pos==string::npos)
438  {
439  Cerr("***** gOptions::ReadDataASCIIFile() -> Exception when trying to read tag '" << a_keyword << "' in file '" << a_file << "'." << endl);
440  Cerr("***** Expected to read " << a_nbElts << " elements, but only " << i+1 << " were found." << endl);
441  return 1;
442  }
443 
444  // Parse the line only if more than 1 elt are requested. Just pick the line otherwise
445  string elt = (a_nbElts>1) ? line.substr(pos, pos2-pos) : line ;
446 
447  if (ConvertFromString(elt, &a2p_return[l][i]))
448  {
449  Cerr("***** gOptions::ReadDataASCIIFile() -> Exception when trying to read tag '" << a_keyword << "' in file " << a_file << endl);
450  return 1;
451  }
452 
453  //pos = pos2+1;
454  // return string::npos if pos2 not found, meaning we reach the end of the line
455  // SS: corrected this incorrect line pos = (pos2<0) ? -1 : pos2+1 ;
456  pos = (pos2==string::npos) ? string::npos : pos2+1;
457  pos2 = line.find_first_of(sep_elt, pos);
458  }
459  }
460  }
461  return 0;
462  }
463  }
464 
465  // Throw an error message if the tag is mandatory
466  if (a_mandatoryFlag == true )
467  {
468  Cerr("***** gOptions::ReadDataASCIIFile() -> Error when reading file '" << a_file << "'. Tag '" << a_keyword << "' was not found." << endl);
470  }
471  else
472  {
474  }
475  }
476  else
477  {
478  Cerr("***** gOptions::ReadDataASCIIFile() -> Couldn't find or read data-file '" << a_file << "' !" << endl);
479  return 1;
480  }
481 }
482 
483 
484 
485 
486 // =====================================================================
487 // ---------------------------------------------------------------------
488 // ---------------------------------------------------------------------
489 // =====================================================================
490 
491 /*
492  \fn ReadDataASCIIFile
493  \param a_file : string containing the path to the ASCII file
494  \param a_keyword : key related to the data we want to recover
495  \param ap_return : templated array in which the data will be returned
496  the recovered data will be converted to its type
497  its size should be equal to the number of elts to recover
498  \param a_nbElts : number of elements to recover
499  \param a_mandatoryFlag : boolean indicating the data to recover is
500  mandatory (KEYWORD_MANDATORY) (error value (=1) will be returned if not found)
501  or optional (KEYWORD_OPTIONAL) (warning value (=2) will be returned if not found)
502  \param a_firstTag : the requested key will be looked for after the first occurence of this string
503  \param a_lastTag : the requested key will be looked for before the first occurence of this string
504  \brief Look for "a_nbElts" elts in the "a_file" file matching the "a_keyword" string passed as parameter
505  and return the corresponding value(s) in the "ap_return" templated array.
506  Additionnal two parameters allow to search within two specific tags
507  This function expects the following parsing :
508  FIRST_TAG
509  (...)
510  KEY : elt1,elt2,...,eltN
511  (...)
512  LAST_TAG
513  \details This function assumes the following separators :
514  ":" is used as separator between the keyworld and the value
515  "#" is used for comment. Every following characters will be discarded
516  "," is used to separate elements if more than one are required
517  \return 0 if success, and positive value otherwise (1 if error, 2 if tag not found).
518 */
519 template<class T>
520 int ReadDataASCIIFile(const string& a_file, const string& a_keyword, T* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag)
521 {
522  ifstream input_file(a_file.c_str(), ios::in);
523  string line;
524  string sep = ":";
525  string sep_comment = "#";
526  string sep_elt = ",";
527  bool search_on = false;
528 
529  // Check file
530  if(input_file)
531  {
532  while(!input_file.eof())
533  {
534  getline(input_file, line);
535 
536  //remove comment
537  if (line.find(sep_comment) != string::npos) line = line.substr(0, line.find_first_of(sep_comment)) ;
538 
539  if( line.find(a_firstTag) != string::npos) search_on = true;
540  if( line.find(a_lastTag) != string::npos || line.find("eof") != string::npos ) search_on = false;
541 
542  if( search_on )
543  {
544  if (line.find(a_keyword) != string::npos)
545  //if (line.compare(a_keyword) == 0)
546  {
547  //remove field in string
548  line = line.substr(line.find_first_of(sep)+1);
549 
550  //clear the space before the first element in the line string;
551  //line.erase(remove_if(line.begin(), line.end(), (int(*)(int))isspace), line.end()); // Explicit type (int(*)(int)) is required to tell compiler which function to take the address of.
552 
553  // Erase all blank stuff before first character
554  line.erase(0, line.find_first_not_of(" !\t\r\n")); // Erase all blank stuff before first character
555  line.erase(line.find_last_not_of(" \t\r\n")+1 , line.length());
556 
557  size_t pos = 0;
558  size_t pos2 = line.find_first_of(sep_elt, pos);
559 
560  // Check if separators were found
561  if (a_nbElts>1 && pos2 == string::npos)
562  {
563  Cerr("***** gOptions::ReadDataASCIIFile() -> The required separator : '" << sep_elt << "' not found for tag: " << a_keyword << endl);
564  return 1;
565  }
566  else // Read one element, or several (a_nbElts) elements separated with ','
567  {
568  for (int i=0 ; i<a_nbElts ; i++)
569  {
570 
571  // Check if we reach the end of the line before initializing all elements
572  // SS: corrected this incorrect line: if(pos<0)
573  if (pos==string::npos)
574  {
575  Cerr("***** gOptions::ReadDataASCIIFile() -> Exception when trying to read tag '" << a_keyword << "' in file '" << a_file << "'." << endl);
576  Cerr("***** Expected to read " << a_nbElts << " elements, but only " << i+1 << " were found." << endl);
577  return 1;
578  }
579 
580  // Parse the line only if more than 1 elt are requested. Just pick the line otherwise
581  string elt = (a_nbElts>1) ? line.substr(pos, pos2-pos) : line ;
582 
583  if(ConvertFromString(elt, &ap_return[i]))
584  {
585  Cerr("***** gOptions::ReadDataASCIIFile() -> Exception when trying to read tag '" << a_keyword << "' in file '" << a_file << "'." << endl);
586  return 1;
587  }
588 
589  //pos = pos2+1;
590  // return string::npos if pos2 not found, meaning we reach the end of the line
591  // SS: corrected this incorrect line pos = (pos2<0) ? -1 : pos2+1 ;
592  pos = (pos2==string::npos) ? string::npos : pos2+1;
593  pos2 = line.find_first_of(sep_elt, pos);
594  }
595  }
596  return 0;
597  }
598  }
599 
600 
601 
602 
603 
604  }
605  // Throw an error message if the tag is mandatory
606  if(a_mandatoryFlag == true)
607  {
608  Cerr("***** gOptions::ReadDataASCIIFile() -> Error when reading file '" << a_file << "'. Tag '" << a_keyword << "' was not found." << endl);
610  }
611  else
612  {
614  }
615  }
616  else
617  {
618  Cerr("***** gOptions::ReadDataASCIIFile() -> Couldn't find or read data-file '"<< a_file << "' !" << endl);
619  return 1;
620  }
621 }
622 
623 
624 
625 
626 // =====================================================================
627 // ---------------------------------------------------------------------
628 // ---------------------------------------------------------------------
629 // =====================================================================
630 /*
631  \fn ReadDataASCIIFile
632  \param a_file : string containing the path to the ASCII file
633  \param a_keyword : key related to the data we want to recover
634  \param a2p_return : 2D templated array in which the data will be returned
635  the recovered data will be converted to its type
636  its size should be equal [nb of lines][nb of elts to recover]
637  \param a_nbElts : number of elements to recover (on each line)
638  \param a_nbLines : number of lines to recover
639  \param a_mandatoryFlag : boolean indicating the data to recover is
640  mandatory (KEYWORD_MANDATORY) (error value (=1) will be returned if not found)
641  or optional (KEYWORD_OPTIONAL) (warning value (=2) will be returned if not found)
642  \param a_firstTag : the requested key will be looked for after the first occurence of this string
643  \param a_lastTag : the requested key will be looked for before the first occurence of this string
644  \brief Look for "a_nbLines" lines of "a_nbElts" elts in the "a_file" file matching the "a_keyword" string
645  passed as parameter and return the corresponding value(s) in the "a2p_return" templated 2D array.
646  The first and second dimensions of "a2p_return" correspond to the line and elements respectively
647  Additionnal two parameters allow to search within two specific tags
648  This function expects the following parsing :
649  KEY :
650  FIRST_TAG
651  (...)
652  line1 : elt1,elt2,...,eltN
653  line2 : elt1,elt2,...,eltN
654  (...)
655  lineN : elt1,elt2,...,eltN
656  (...)
657  LAST_TAG
658  \details This function assumes the following separators :
659  ":" is used as separator between the keyworld and the value
660  "#" is used for comment. Every following characters will be discarded
661  "," is used to separate elements if more than one are required
662  \return 0 if success, and positive value otherwise (1 if error, 2 if tag not found).
663 */
664 template<class T>
665 int ReadDataASCIIFile(const string& a_file, const string& a_keyword, T** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag)
666 {
667  ifstream input_file(a_file.c_str(), ios::in);
668  string line;
669  string sep = ":";
670  string sep_comment = "#";
671  string sep_elt = ",";
672  bool search_on = false;
673 
674  // Check file
675  if(input_file)
676  {
677  while(!input_file.eof())
678  {
679  getline(input_file, line);
680 
681  //remove comment
682  if (line.find(sep_comment) != string::npos) line = line.substr(0, line.find_first_of(sep_comment)) ;
683 
684  if( line.find(a_firstTag) != string::npos) search_on = true;
685  if( line.find(a_lastTag) != string::npos || line.find("eof") != string::npos ) search_on = false;
686 
687  if( search_on )
688  {
689  if (line.find(a_keyword) != string::npos)
690  {
691  for (int l=0 ; l<a_nbLines ; l++)
692  {
693  getline(input_file, line);
694 
695  //remove field in string
696  line = line.substr(line.find_first_of(sep)+1);
697 
698  //clear the space before the first element in the line string;
699  //line.erase(remove_if(line.begin(), line.end(), (int(*)(int))isspace), line.end()); // Explicit type (int(*)(int)) is required to tell compiler which function to take the address of.
700 
701  // Erase all blank stuff before and after first character
702  line.erase(0, line.find_first_not_of(" !\t\r\n"));
703  line.erase(line.find_last_not_of(" \t\r\n")+1 , line.length());
704 
705  size_t pos = 0;
706  size_t pos2 = line.find_first_of(sep_elt, pos);
707 
708  // Check if separators were found
709  if (a_nbElts>1 && pos2 == string::npos)
710  {
711  Cerr("***** gOptions::ReadDataASCIIFile() -> The required separator : '" << sep_elt << "' not found for tag: " << a_keyword << endl);
712  return 1;
713  }
714  else // Read one element, or several (a_nbElts) elements separated with ','
715  {
716  for (int i=0 ; i<a_nbElts ; i++)
717  {
718  // Check if we reach the end of the line before initializing all elements
719  // SS: corrected this incorrect line: if(pos<0)
720  if (pos==string::npos)
721  {
722  Cerr("***** gOptions::ReadDataASCIIFile() -> Exception when trying to read tag '" << a_keyword << "' in file '" << a_file << "'." << endl);
723  Cerr("***** Expected to read " << a_nbElts << " elements, but only " << i+1 << " were found." << endl);
724  return 1;
725  }
726 
727  // Parse the line only if more than 1 elt are requested. Just pick the line otherwise
728  string elt = (a_nbElts>1) ? line.substr(pos, pos2-pos) : line ;
729 
730  if (ConvertFromString(elt, &a2p_return[l][i]))
731  {
732  Cerr("***** gOptions::ReadDataASCIIFile() -> Exception when trying to read tag '" << a_keyword << "' in file " << a_file << endl);
733  return 1;
734  }
735 
736  //pos = pos2+1;
737  // return string::npos if pos2 not found, meaning we reach the end of the line
738  // SS: corrected this incorrect line pos = (pos2<0) ? -1 : pos2+1 ;
739  pos = (pos2==string::npos) ? string::npos : pos2+1;
740  pos2 = line.find_first_of(sep_elt, pos);
741  }
742  }
743  }
744  return 0;
745  }
746  }
747  }
748  // Throw an error message if the tag is mandatory
749  if(a_mandatoryFlag == true)
750  {
751  Cerr("***** gOptions::ReadDataASCIIFile() -> Error when reading file '" << a_file << "'. Tag '" << a_keyword << "' was not found." << endl);
753  }
754  else
755  {
757  }
758  }
759  else
760  {
761  Cerr("***** gOptions::ReadDataASCIIFile() -> Couldn't find or read data-file '"<< a_file << "' !" << endl);
762  return 1;
763  }
764 }
765 
766 
767 
768 
769 // =====================================================================
770 // ---------------------------------------------------------------------
771 // ---------------------------------------------------------------------
772 // =====================================================================
773 /*
774  \fn ConvertFromString
775  \param a_str : string to convert
776  \param a_result : variable which will recover the result
777  \brief Copy the 'a_str' string in the position pointed by 'a_result'
778  \details The only purposes of this function is to have an
779  unified templated conversion function for each type
780  \return 0 if success, and positive value otherwise
781 */
782 int ConvertFromString(const string& a_str, string* a_result)
783 {
784  *a_result = a_str.c_str();
785  return 0;
786 }
787 
788 
789 
790 
791 // =====================================================================
792 // ---------------------------------------------------------------------
793 // ---------------------------------------------------------------------
794 // =====================================================================
795 /*
796  \fn ConvertFromString
797  \param a_str : string to convert
798  \param a_result : variable which will recover the result
799  \brief Convert the 'a_str' string in float and copy the result in the variable pointed by 'a_result'
800  \details Uses strtod to check errors with str to float conversion
801  (implementation similar to c++11 std::stof() ).
802  \return 0 if success, and positive value otherwise
803 */
804 int ConvertFromString(const string& a_str, float* a_result)
805 {
806  const char* p = a_str.c_str();
807  char* end;
808  errno = 0;
809  double val = strtod(p, &end);
810 
811  if (p == end)
812  {
813  Cerr("***** gOptions::ConvertFromString() -> Invalid argument exception while trying to convert '" << a_str << "' into float " << endl);
814  return 1;
815  }
816  if (errno == ERANGE)
817  {
818  Cerr("***** gOptions::ConvertFromString() -> Out of range exception while trying to convert '" << a_str << "' into float " << endl);
819  return 1;
820  }
821 
822  *a_result = static_cast<float>(val);
823 
824  return 0;
825 }
826 
827 
828 
829 
830 // =====================================================================
831 // ---------------------------------------------------------------------
832 // ---------------------------------------------------------------------
833 // =====================================================================
834 /*
835  \fn ConvertFromString
836  \param a_str : string to convert
837  \param a_result : variable which will recover the result
838  \brief Convert the 'a_str' string in double and copy the result in the position pointed by 'a_result'
839  \details Uses strtod to check errors with str to double conversion
840  (implementation similar to c++11 std::stod() ).
841  \return 0 if success, and positive value otherwise
842 */
843 int ConvertFromString(const string& a_str, double* a_result)
844 {
845  const char* p = a_str.c_str();
846  char* end;
847  errno = 0;
848  double val = strtod(p, &end);
849 
850  if (p == end)
851  {
852  Cerr("***** gOptions::ConvertFromString() -> Invalid argument exception while trying to convert '" << a_str << "' into double " << endl);
853  return 1;
854  }
855  if (errno == ERANGE)
856  {
857  Cerr("***** gOptions::ConvertFromString() -> Out of range exception while trying to convert '" << a_str << "' into double " << endl);
858  return 1;
859  }
860 
861  *a_result = val;
862 
863  return 0;
864 }
865 
866 
867 
868 
869 // =====================================================================
870 // ---------------------------------------------------------------------
871 // ---------------------------------------------------------------------
872 // =====================================================================
873 /*
874  \fn ConvertFromString
875  \param a_str : string to convert
876  \param a_result : variable which will recover the result
877  \brief Convert the 'a_str' string in long double and copy the result in the position pointed by 'a_result'
878  \details Uses strtod to check errors with str to ldouble conversion
879  (implementation similar to c++11 std::stod() ).
880  \return 0 if success, and positive value otherwise
881 */
882 int ConvertFromString(const string& a_str, long double* a_result)
883 {
884  const char* p = a_str.c_str();
885  char* end;
886  errno = 0;
887  long double val = strtold(p, &end);
888 
889  if (p == end)
890  {
891  Cerr("***** gOptions::ConvertFromString() -> Invalid argument exception while trying to convert '" << a_str << "' into double " << endl);
892  return 1;
893  }
894  if (errno == ERANGE)
895  {
896  Cerr("***** gOptions::ConvertFromString() -> Out of range exception while trying to convert '" << a_str << "' into double " << endl);
897  return 1;
898  }
899 
900  *a_result = val;
901 
902  return 0;
903 }
904 
905 
906 
907 
908 // =====================================================================
909 // ---------------------------------------------------------------------
910 // ---------------------------------------------------------------------
911 // =====================================================================
912 /*
913  \fn ConvertFromString
914  \param a_str : string to convert
915  \param a_result : variable which will recover the result
916  \brief Convert the 'a_str' string in int and copy the result in the position pointed by 'a_result'
917  \details Uses strtol to check errors with str to int conversion
918  (implementation similar to c++11 std::stoi() ).
919  \return 0 if success, and positive value otherwise
920 */
921 int ConvertFromString(const string& a_str, int* a_result)
922 {
923  const char* p = a_str.c_str();
924  char* end;
925  errno = 0;
926  int64_t val = strtol(p, &end, 10);
927 
928  if (p == end)
929  {
930  Cerr("***** gOptions::ConvertFromString() -> Invalid argument exception while trying to convert '" << a_str << "' into int " << endl);
931  return 1;
932  }
933  if (errno==ERANGE || val<INT_MIN || val>INT_MAX)
934  {
935  Cerr("***** gOptions::ConvertFromString() -> Out of range exception while trying to convert '" << a_str << "' into int " << endl);
936  return 1;
937  }
938 
939  *a_result = static_cast<int>(val);
940 
941  return 0;
942 }
943 
944 
945 
946 
947 // =====================================================================
948 // ---------------------------------------------------------------------
949 // ---------------------------------------------------------------------
950 // =====================================================================
951 /*
952  \fn ConvertFromString
953  \param a_str : string to convert
954  \param a_result : variable which will recover the result
955  \brief Convert the 'a_str' string in int64_t and copy the result in the position pointed by 'a_result'
956  \details Uses strtol to check errors with str to lint conversion
957  (implementation similar to c++11 std::stol() ).
958  \return 0 if success, and positive value otherwise
959 */
960 int ConvertFromString(const string& a_str, int64_t* a_result)
961 {
962  const char* p = a_str.c_str();
963  char* end;
964  errno = 0;
965  int64_t val = strtol(p, &end, 10);
966 
967  if (p == end)
968  {
969  Cerr("***** gOptions::ConvertFromString() -> Invalid argument exception while trying to convert '" << a_str << "' into int64_t " << endl);
970  return 1;
971  }
972  if (errno == ERANGE)
973  {
974  Cerr("***** gOptions::ConvertFromString() -> Out of range exception while trying to convert '" << a_str << "' into int64_t " << endl);
975  return 1;
976  }
977 
978  *a_result = val;
979 
980  return 0;
981 }
982 
983 
984 
985 
986 // =====================================================================
987 // ---------------------------------------------------------------------
988 // ---------------------------------------------------------------------
989 // =====================================================================
990 /*
991  \fn ConvertFromString
992  \param a_str : string to convert
993  \param a_result : variable which will recover the result
994  \brief Convert the 'a_str' string in uint16_t and copy the result in the position pointed by 'a_result'
995  \details Uses strtol to check errors with str to uint8 conversion
996  (implementation similar to c++11 std::stoi() ).
997  \return 0 if success, and positive value otherwise
998 */
999 int ConvertFromString(const string& a_str, uint8_t* a_result)
1000 {
1001  const char* p = a_str.c_str();
1002  char* end;
1003  errno = 0;
1004  int64_t val = strtol(p, &end, 10);
1005 
1006  if (p == end)
1007  {
1008  Cerr("***** gOptions::ConvertFromString() -> Invalid argument exception while trying to convert '" << a_str << "' into uint16 " << endl);
1009  return 1;
1010  }
1011  if (errno == ERANGE || val<0 || val>UCHAR_MAX)
1012  {
1013  Cerr("***** gOptions::ConvertFromString() -> Out of range exception while trying to convert '" << a_str << "' into uint16 " << endl);
1014  return 1;
1015  }
1016 
1017  *a_result = val;
1018 
1019  return 0;
1020 }
1021 
1022 
1023 
1024 
1025 // =====================================================================
1026 // ---------------------------------------------------------------------
1027 // ---------------------------------------------------------------------
1028 // =====================================================================
1029 /*
1030  \fn ConvertFromString
1031  \param a_str : string to convert
1032  \param a_result : variable which will recover the result
1033  \brief Convert the 'a_str' string in uint16_t and copy the result in the position pointed by 'a_result'
1034  \details Uses strtol to check errors with str to uint16 conversion
1035  (implementation similar to c++11 std::stoi() ).
1036  \return 0 if success, and positive value otherwise
1037 */
1038 int ConvertFromString(const string& a_str, uint16_t* a_result)
1039 {
1040  const char* p = a_str.c_str();
1041  char* end;
1042  errno = 0;
1043  int64_t val = strtol(p, &end, 10);
1044 
1045  if (p == end)
1046  {
1047  Cerr("***** gOptions::ConvertFromString() -> Invalid argument exception while trying to convert '" << a_str << "' into uint16 " << endl);
1048  return 1;
1049  }
1050  if (errno == ERANGE || val<0 || val>USHRT_MAX)
1051  {
1052  Cerr("***** gOptions::ConvertFromString() -> Out of range exception while trying to convert '" << a_str << "' into uint16 " << endl);
1053  return 1;
1054  }
1055 
1056  *a_result = val;
1057 
1058  return 0;
1059 }
1060 
1061 
1062 
1063 
1064 // =====================================================================
1065 // ---------------------------------------------------------------------
1066 // ---------------------------------------------------------------------
1067 // =====================================================================
1068 /*
1069  \fn ConvertFromString
1070  \param a_str : string to convert
1071  \param a_result : variable which will recover the result
1072  \brief Convert the 'a_str' string in uint32_t and copy the result in the position pointed by 'a_result'
1073  \details Uses strtol to check errors with str to uint32 conversion
1074  (implementation similar to c++11 std::stoi() ).
1075  \return 0 if success, and positive value otherwise
1076 */
1077 int ConvertFromString(const string& a_str, uint32_t* a_result)
1078 {
1079  const char* p = a_str.c_str();
1080  char* end;
1081  errno = 0;
1082  int64_t val = strtol(p, &end, 10);
1083 
1084  if (p == end)
1085  {
1086  Cerr("***** gOptions::ConvertFromString() -> Invalid argument exception while trying to convert '" << a_str << "' into uint32 " << endl);
1087  return 1;
1088  }
1089  if (errno == ERANGE || val<0 || val>UINT_MAX)
1090  {
1091  Cerr("***** gOptions::ConvertFromString() -> Out of range exception while trying to convert '" << a_str << "' into uint32 " << endl);
1092  return 1;
1093  }
1094 
1095  *a_result = val;
1096 
1097  return 0;
1098 }
1099 
1100 
1101 
1102 
1103 // =====================================================================
1104 // ---------------------------------------------------------------------
1105 // ---------------------------------------------------------------------
1106 // =====================================================================
1107 /*
1108  \fn ConvertFromString
1109  \param a_str : string to convert
1110  \param a_result : variable which will recover the result
1111  \brief Convert the 'a_str' string in bool and copy the result in the position pointed by 'a_result'
1112  \details Uses strtol to check errors with str to bool conversion
1113  (implementation similar to c++11 std::stoi() ).
1114  \return 0 if success, and positive value otherwise
1115 */
1116 int ConvertFromString(const string& a_str, bool* a_result)
1117 {
1118  const char* p = a_str.c_str();
1119  char* end;
1120  errno = 0;
1121  int64_t val = strtol(p, &end, 10);
1122 
1123  if (p == end)
1124  {
1125  Cerr("***** gOptions::ConvertFromString() -> Invalid argument exception while trying to convert '" << a_str << "' into bool " << endl);
1126  return 1;
1127  }
1128  if (errno == ERANGE || val<0 || val>1)
1129  {
1130  Cerr("***** gOptions::ConvertFromString() -> Out of range exception while trying to convert '" << a_str << "' into bool " << endl);
1131  return 1;
1132  }
1133 
1134  *a_result = val;
1135 
1136  return 0;
1137 }
1138 
1139 
1140 
1141 
1142 // =====================================================================
1143 // ---------------------------------------------------------------------
1144 // ---------------------------------------------------------------------
1145 // =====================================================================
1146 /*
1147  \fn GetFileFromPath()
1148  \param a_pathToFile
1149  \brief Simply return the file from a path string passed in parameter
1150  \return The path.
1151 */
1152 string GetFileFromPath(const string& a_pathToFile)
1153 {
1154  string path = a_pathToFile;
1155 
1156  int pos = path.find_last_of(OS_SEP);
1157  if (path.find_last_of(OS_SEP) == string::npos)
1158  return path;
1159 
1160  path = path.substr(pos+1);
1161  return path;
1162 }
1163 
1164 
1165 
1166 
1167 // =====================================================================
1168 // ---------------------------------------------------------------------
1169 // ---------------------------------------------------------------------
1170 // =====================================================================
1171 /*
1172  \fn GetPathOfFile()
1173  \param a_pathToFile
1174  \brief Simply return the path to the directory of a file path string passed in parameter
1175  \return The path.
1176 */
1177 string GetPathOfFile(const string& a_pathToFile)
1178 {
1179  string path = a_pathToFile;
1180 
1181  int pos = path.find_last_of(OS_SEP);
1182  if (path.find_last_of(OS_SEP) == string::npos)
1183  return "";
1184 
1185  path = path.substr(0,pos+1);
1186 
1187  return path;
1188 }
1189 
1190 
1191 /*
1192  \fn string ConvertAllSlashOcurrencesToBackSlash()
1193  \param const string& a_path
1194  \brief Simply convert all occurrences of "/" to "\"
1195  \return A new converted string
1196 */
1197 string ConvertAllSlashOccurrencesToBackSlash(const string& a_path)
1198 {
1199  string result = a_path;
1200  size_t position;
1201  while ( (position = result.find_first_of("/")) != string::npos )
1202  {
1203  result.replace(position,1,"\\");
1204  }
1205  return result;
1206 }
1207 
1208 
1209 /*
1210  \fn bool FLTNBIsEqual(FLTNB a, FLTNB b, FLTNB a_eps)
1211  \param a : 1st FLTNB nb to compare
1212  \param b : 2nd FLTNB nb to compare
1213  \param a_eps : epsilon for comparison
1214  \brief Comparison of FLTNB numbers
1215  \return true if equal according to the provided epsilon, false otherwise
1216 */
1217 bool FLTNBIsEqual(FLTNB a, FLTNB b, FLTNB a_eps)
1218 {
1219  FLTNB absA = abs(a);
1220  FLTNB absB = abs(b);
1221  FLTNB diff = abs(a - b);
1222 
1223  if (a == b)
1224  {
1225  return true;
1226  }
1227  else if (a == 0 ||
1228  b == 0 ||
1229  diff < std::numeric_limits<FLTNB>::min())
1230  { // a or b is 0, or extremely close to it
1231  return diff < (a_eps * std::numeric_limits<FLTNB>::min() );
1232  }
1233  else
1234  { // relative error
1235  return diff / min((absA + absB), std::numeric_limits<FLTNB>::max()) < a_eps;
1236  }
1237 }
1238 
1239 
1240 // =====================================================================
1241 // ---------------------------------------------------------------------
1242 // ---------------------------------------------------------------------
1243 // =====================================================================
1244 // Explicit template instantiation
1245 // (that way no one would use the templated versions of these functions for not yet implemented type (long double, unsigned, ect..) )
1246 template int ReadStringOption<string>(const string& a_input, string* ap_return, int a_nbElts, const string& sep, const string& a_option);
1247 template int ReadStringOption<int>(const string& a_input, int* ap_return, int a_nbElts, const string& sep, const string& a_option);
1248 template int ReadStringOption<int64_t>(const string& a_input, int64_t* ap_return, int a_nbElts, const string& sep, const string& a_option);
1249 template int ReadStringOption<float>(const string& a_input, float* ap_return, int a_nbElts, const string& sep, const string& a_option);
1250 template int ReadStringOption<double>(const string& a_input, double* ap_return, int a_nbElts, const string& sep, const string& a_option);
1251 template int ReadStringOption<long double>(const string& a_input, long double* ap_return, int a_nbElts, const string& sep, const string& a_option);
1252 template int ReadStringOption<uint8_t>(const string& a_input, uint8_t* ap_return, int a_nbElts, const string& sep, const string& a_option);
1253 template int ReadStringOption<uint16_t>(const string& a_input, uint16_t* ap_return, int a_nbElts, const string& sep, const string& a_option);
1254 template int ReadStringOption<uint32_t>(const string& a_input, uint32_t* ap_return, int a_nbElts, const string& sep, const string& a_option);
1255 template int ReadStringOption<bool>(const string& a_input, bool* ap_return, int a_nbElts, const string& sep, const string& a_option);
1256 
1257 template int ReadDataASCIIFile<string>(const string& a_file, const string& a_keyword, string* ap_return, int a_nbElts, bool a_mandatoryFlag);
1258 template int ReadDataASCIIFile<int>(const string& a_file, const string& a_keyword, int* ap_return, int a_nbElts, bool a_mandatoryFlag);
1259 template int ReadDataASCIIFile<int64_t>(const string& a_file, const string& a_keyword, int64_t* ap_return, int a_nbElts, bool a_mandatoryFlag);
1260 template int ReadDataASCIIFile<float>(const string& a_file, const string& a_keyword, float* ap_return, int a_nbElts, bool a_mandatoryFlag);
1261 template int ReadDataASCIIFile<double>(const string& a_file, const string& a_keyword, double* ap_return, int a_nbElts, bool a_mandatoryFlag);
1262 template int ReadDataASCIIFile<long double>(const string& a_file, const string& a_keyword, long double* ap_return, int a_nbElts, bool a_mandatoryFlag);
1263 template int ReadDataASCIIFile<uint8_t>(const string& a_file, const string& a_keyword, uint8_t* ap_return, int a_nbElts, bool a_mandatoryFlag);
1264 template int ReadDataASCIIFile<uint16_t>(const string& a_file, const string& a_keyword, uint16_t* ap_return, int a_nbElts, bool a_mandatoryFlag);
1265 template int ReadDataASCIIFile<uint32_t>(const string& a_file, const string& a_keyword, uint32_t* ap_return, int a_nbElts, bool a_mandatoryFlag);
1266 template int ReadDataASCIIFile<bool>(const string& a_file, const string& a_keyword, bool* ap_return, int a_nbElts, bool a_mandatoryFlag);
1267 
1268 template int ReadDataASCIIFile<string>(const string& a_file, const string& a_keyword, string* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1269 template int ReadDataASCIIFile<int>(const string& a_file, const string& a_keyword, int* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1270 template int ReadDataASCIIFile<int64_t>(const string& a_file, const string& a_keyword, int64_t* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1271 template int ReadDataASCIIFile<float>(const string& a_file, const string& a_keyword, float* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1272 template int ReadDataASCIIFile<double>(const string& a_file, const string& a_keyword, double* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1273 template int ReadDataASCIIFile<long double>(const string& a_file, const string& a_keyword, long double* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1274 template int ReadDataASCIIFile<uint8_t>(const string& a_file, const string& a_keyword, uint8_t* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1275 template int ReadDataASCIIFile<uint16_t>(const string& a_file, const string& a_keyword, uint16_t* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1276 template int ReadDataASCIIFile<uint32_t>(const string& a_file, const string& a_keyword, uint32_t* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1277 template int ReadDataASCIIFile<bool>(const string& a_file, const string& a_keyword, bool* ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1278 
1279 template int ReadDataASCIIFile<string>(const string& a_file, const string& a_keyword, string** ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1280 template int ReadDataASCIIFile<int>(const string& a_file, const string& a_keyword, int** ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1281 template int ReadDataASCIIFile<int64_t>(const string& a_file, const string& a_keyword, int64_t** ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1282 template int ReadDataASCIIFile<float>(const string& a_file, const string& a_keyword, float** ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1283 template int ReadDataASCIIFile<double>(const string& a_file, const string& a_keyword, double** ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1284 template int ReadDataASCIIFile<long double>(const string& a_file, const string& a_keyword, long double** ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1285 template int ReadDataASCIIFile<uint8_t>(const string& a_file, const string& a_keyword, uint8_t** ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1286 template int ReadDataASCIIFile<uint16_t>(const string& a_file, const string& a_keyword, uint16_t** ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1287 template int ReadDataASCIIFile<uint32_t>(const string& a_file, const string& a_keyword, uint32_t** ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1288 template int ReadDataASCIIFile<bool>(const string& a_file, const string& a_keyword, bool** ap_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag);
1289 
1290 template int ReadDataASCIIFile<string>(const string& a_file, const string& a_keyword, string* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1291 template int ReadDataASCIIFile<int>(const string& a_file, const string& a_keyword, int* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1292 template int ReadDataASCIIFile<int64_t>(const string& a_file, const string& a_keyword, int64_t* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1293 template int ReadDataASCIIFile<float>(const string& a_file, const string& a_keyword, float* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1294 template int ReadDataASCIIFile<double>(const string& a_file, const string& a_keyword, double* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1295 template int ReadDataASCIIFile<long double>(const string& a_file, const string& a_keyword, long double* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1296 template int ReadDataASCIIFile<uint8_t>(const string& a_file, const string& a_keyword, uint8_t* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1297 template int ReadDataASCIIFile<uint16_t>(const string& a_file, const string& a_keyword, uint16_t* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1298 template int ReadDataASCIIFile<uint32_t>(const string& a_file, const string& a_keyword, uint32_t* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1299 template int ReadDataASCIIFile<bool>(const string& a_file, const string& a_keyword, bool* ap_return, int a_nbElts, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1300 
1301 template int ReadDataASCIIFile<string>(const string& a_file, const string& a_keyword, string** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1302 template int ReadDataASCIIFile<int>(const string& a_file, const string& a_keyword, int** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1303 template int ReadDataASCIIFile<int64_t>(const string& a_file, const string& a_keyword, int64_t** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1304 template int ReadDataASCIIFile<float>(const string& a_file, const string& a_keyword, float** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1305 template int ReadDataASCIIFile<double>(const string& a_file, const string& a_keyword, double** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1306 template int ReadDataASCIIFile<long double>(const string& a_file, const string& a_keyword, long double** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1307 template int ReadDataASCIIFile<uint8_t>(const string& a_file, const string& a_keyword, uint8_t** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1308 template int ReadDataASCIIFile<uint16_t>(const string& a_file, const string& a_keyword, uint16_t** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1309 template int ReadDataASCIIFile<uint32_t>(const string& a_file, const string& a_keyword, uint32_t** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
1310 template int ReadDataASCIIFile<bool>(const string& a_file, const string& a_keyword, bool** a2p_return, int a_nbElts, int a_nbLines, bool a_mandatoryFlag, string a_firstTag, string a_lastTag);
string GetFileFromPath(const string &a_pathToFile)
Simply return the file from a path string passed in parameter.
Definition: gOptions.cc:1152
This header file is mainly used to declare some macro definitions and all includes needed from the st...
template int ReadDataASCIIFile< double >(const string &a_file, const string &a_keyword, double *ap_return, int a_nbElts, bool a_mandatoryFlag)
#define FLTNB
Definition: gVariables.hh:81
template int ReadDataASCIIFile< float >(const string &a_file, const string &a_keyword, float *ap_return, int a_nbElts, bool a_mandatoryFlag)
template int ReadDataASCIIFile< int >(const string &a_file, const string &a_keyword, int *ap_return, int a_nbElts, bool a_mandatoryFlag)
template int ReadStringOption< int64_t >(const string &a_input, int64_t *ap_return, int a_nbElts, const string &sep, const string &a_option)
int ReadStringOption(const string &a_input, T *ap_return, int a_nbElts, const string &a_sep, const string &a_option)
Parse the &#39;a_input&#39; string corresponding to the &#39;a_option&#39; into &#39;a_nbElts&#39; elements, using the &#39;sep&#39; separator. The results are returned in the templated &#39;ap_return&#39; dynamic templated array. Call "ConvertFromString()" to perform the correct conversion depending on the type of the data to convert.
Definition: gOptions.cc:50
template int ReadStringOption< uint8_t >(const string &a_input, uint8_t *ap_return, int a_nbElts, const string &sep, const string &a_option)
template int ReadStringOption< uint32_t >(const string &a_input, uint32_t *ap_return, int a_nbElts, const string &sep, const string &a_option)
template int ReadDataASCIIFile< int64_t >(const string &a_file, const string &a_keyword, int64_t *ap_return, int a_nbElts, bool a_mandatoryFlag)
#define KEYWORD_MANDATORY_NOT_FOUND
Definition: gOptions.hh:51
template int ReadStringOption< string >(const string &a_input, string *ap_return, int a_nbElts, const string &sep, const string &a_option)
template int ReadDataASCIIFile< long double >(const string &a_file, const string &a_keyword, long double *ap_return, int a_nbElts, bool a_mandatoryFlag)
template int ReadStringOption< uint16_t >(const string &a_input, uint16_t *ap_return, int a_nbElts, const string &sep, const string &a_option)
string ConvertAllSlashOccurrencesToBackSlash(const string &a_path)
Definition: gOptions.cc:1197
#define Cerr(MESSAGE)
bool FLTNBIsEqual(FLTNB a, FLTNB b, FLTNB a_eps)
Comparison of FLTNB numbers.
Definition: gOptions.cc:1217
string GetPathOfFile(const string &a_pathToFile)
Simply return the path to the directory of a file path string passed in parameter.
Definition: gOptions.cc:1177
template int ReadDataASCIIFile< bool >(const string &a_file, const string &a_keyword, bool *ap_return, int a_nbElts, bool a_mandatoryFlag)
template int ReadDataASCIIFile< uint16_t >(const string &a_file, const string &a_keyword, uint16_t *ap_return, int a_nbElts, bool a_mandatoryFlag)
template int ReadDataASCIIFile< uint8_t >(const string &a_file, const string &a_keyword, uint8_t *ap_return, int a_nbElts, bool a_mandatoryFlag)
template int ReadDataASCIIFile< string >(const string &a_file, const string &a_keyword, string *ap_return, int a_nbElts, bool a_mandatoryFlag)
#define OS_SEP
template int ReadStringOption< bool >(const string &a_input, bool *ap_return, int a_nbElts, const string &sep, const string &a_option)
#define KEYWORD_OPTIONAL_NOT_FOUND
Definition: gOptions.hh:57
template int ReadStringOption< double >(const string &a_input, double *ap_return, int a_nbElts, const string &sep, const string &a_option)
Declaration of class sOutputManager.
template int ReadDataASCIIFile< uint32_t >(const string &a_file, const string &a_keyword, uint32_t *ap_return, int a_nbElts, bool a_mandatoryFlag)
This file is used for all kind of different functions designed for options parsing and ASCII file rea...
int ReadDataASCIIFile(const string &a_file, const string &a_keyword, T *ap_return, int a_nbElts, bool a_mandatoryFlag)
Look for "a_nbElts" elts in the "a_file" file matching the "a_keyword" string passed as parameter a...
Definition: gOptions.cc:129
int ConvertFromString(const string &a_str, string *a_result)
Copy the &#39;a_str&#39; string in the position pointed by &#39;a_result&#39;.
Definition: gOptions.cc:782
template int ReadStringOption< float >(const string &a_input, float *ap_return, int a_nbElts, const string &sep, const string &a_option)
template int ReadStringOption< int >(const string &a_input, int *ap_return, int a_nbElts, const string &sep, const string &a_option)
template int ReadStringOption< long double >(const string &a_input, long double *ap_return, int a_nbElts, const string &sep, const string &a_option)