NOMAD Source  Version 4.0.0 Beta
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
WriteAttributeDefinitionFile.cpp File Reference
#include <algorithm>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <map>
Include dependency graph for WriteAttributeDefinitionFile.cpp:

Go to the source code of this file.

Classes

class  Exception
 Exception utility. More...
 

Functions

void toUpperCase (std::string &str)
 Toupper utility. More...
 
void duplicateParPlurals (std::string &blockOfStrings)
 Utility to interpret plural words. More...
 
std::string readBlockOfLines (std::ifstream &fin, size_t &lineNumber, const std::string &blockDelimiterOpen, const std::string &blockDelimiterClose)
 Utility to read a block of lines. More...
 
int main (int argc, char *argv[])
 

Variables

const std::string attributeDefinitionNames [6]
 
const std::map< std::string, bool > attributeFlagsRegistered
 Registered attribute flags and default value. More...
 

Function Documentation

void duplicateParPlurals ( std::string &  blockOfStrings)

Utility to interpret plural words.

Definition at line 64 of file WriteAttributeDefinitionFile.cpp.

65 {
66  // Pad with blanks
67  blockOfStrings.insert(0," ");
68  blockOfStrings.append(" ");
69 
70  size_t posBegin = 0;
71 
72  // Loop on ()
73  while ( true )
74  {
75  size_t posPar1 = blockOfStrings.find( "(" , posBegin );
76  if ( posPar1 != std::string::npos )
77  {
78  size_t posBlank = blockOfStrings.rfind( " " , posPar1 );
79  size_t posPar2 = blockOfStrings.find( ")" ,posBegin );
80  if ( posPar2 != std::string::npos && posBlank < posPar2 )
81  {
82  // Word to duplicate
83  std::string word = blockOfStrings.substr(posBlank+1,posPar1-posBlank-1)+" ";
84 
85  // Remove parenthesis
86  blockOfStrings.erase(posPar2,1);
87  blockOfStrings.erase(posPar1,1);
88 
89  // Insert word without parenthesis
90  blockOfStrings.insert(posBlank+1,word);
91 
92  posBegin = posBlank;
93  }
94  else
95  break;
96  }
97  else
98  break;
99 
100  }
101 }
int main ( int  argc,
char *  argv[] 
)

Definition at line 156 of file WriteAttributeDefinitionFile.cpp.

157 {
158  // Get directory where the input .txt files are.
159  std::string inputDir, outputDir;
160  if (argc > 1)
161  {
162  std::string s = argv[1];
163  // Ensure directory ends with '/'.
164  if (s[s.size()-1] != '/')
165  {
166  s += '/';
167  }
168  inputDir = s;
169  outputDir = s;
170  }
171 
172  std::ifstream fin;
173  std::ofstream fout;
174  std::string errMsg ;
175 
176  std::istringstream iss;
177  std::ostringstream oss;
178 
179  std::map<std::string,bool> attributeFlags;
180 
181  for ( auto attDefName : attributeDefinitionNames )
182  {
183  std::string attDefFile = inputDir + attDefName + ".txt";
184  std::string attDefHeader = outputDir + attDefName + ".hpp";
185 
186  // Clear input stream
187  iss.str("");
188  iss.clear();
189 
190  // Clear output stream
191  oss.str("");
192  oss.clear();
193  std::string UpperAttDefName = attDefName ;
194  for (auto & c: UpperAttDefName) c = toupper(c);
195 
196  oss << "//////////// THIS FILE MUST BE CREATED BY EXECUTING WriteAttributeDefinitionFile ////////////" << std::endl;
197  oss << "//////////// DO NOT MODIFY THIS FILE MANUALLY ///////////////////////////////////////////////" << std::endl << std::endl;
198 
199  oss << "#ifndef __NOMAD400_"<< UpperAttDefName << "__" << std::endl;
200  oss << "#define __NOMAD400_"<< UpperAttDefName << "__" << std::endl << std::endl;
201  oss << "_definition = {" ;
202 
203  bool flagInFile;
204  try
205  {
206  flagInFile=true;
207 
208  // Default error message for problem opening file
209  errMsg = " Failed to open file " + attDefFile + ".";
210 
211  size_t lineNumber=0;
212  fin.open ( attDefFile );
213 
214  if ( !fin.fail() )
215  {
216  errMsg.clear();
217  }
218  if ( !errMsg.empty() )
219  {
220  throw ( Exception( 0,errMsg ) );
221  }
222 
223  std::string line;
224  bool firstAttribute = true;
225 
226  while ( fin.good() && !fin.eof() )
227  {
228 
229  // Read attribute name
230  if ( firstAttribute )
231  {
232  getline(fin, line);
233  lineNumber++;
234  }
235 
236  // the previous getline may have reached end of file
237  if ( fin.eof() )
238  {
239  continue;
240  }
241 
242  if ( fin.fail() )
243  {
244  errMsg = " Failed to read file " + attDefFile + ".";
245  throw ( Exception(lineNumber,errMsg) );
246  }
247 
248  if ( line.size() > 0 && line.find_first_of("#")== 0 )
249  {
250  if (!firstAttribute)
251  {
252  getline(fin, line);
253  lineNumber++;
254  }
255  continue;
256  }
257 
258  // After the first attribute we need comma separation between attributes
259  if ( ! firstAttribute )
260  oss << "," << std::endl;
261  else
262  oss << std::endl;
263 
264  std::string attributeName;
265  iss.clear();
266  iss.str(line);
267  iss >> attributeName;
268 
269  if ( attributeName.size()==0)
270  {
271  errMsg = " The first word after a comment must be an attribute name. \n An empty line is not valid.";
272  throw ( Exception(lineNumber,errMsg) );
273  }
274  oss << "{ \"" << attributeName << "\", ";
275 
276  // Read attribute type
277  getline(fin, line);
278  lineNumber++;
279 
280  if ( fin.fail() || line.empty() )
281  {
282  errMsg = "Failed to read file " + attDefFile + ".";
283  throw ( Exception(lineNumber,errMsg) );
284  }
285 
286  std::string attributeType;
287  iss.clear();
288  iss.str(line);
289 
290  iss >> attributeType ;
291 
292  if ( attributeType.size()==0 )
293  {
294  errMsg = " The next word after an attribute name must be the attribute type. \n An empty line is not valid.";
295  throw ( Exception(lineNumber,errMsg) );
296  }
297  oss << " \"" << attributeType << "\", " ;
298 
299  // Read attribute default value (can be undefined)
300  getline(fin, line);
301  lineNumber++;
302 
303  if ( fin.fail() || line.empty() )
304  {
305  errMsg = " Failed to read file " + attDefFile + ".";
306  throw ( Exception(lineNumber,errMsg) );
307  }
308 
309  std::string attributeDefault;
310  iss.clear();
311  iss.str(line);
312  iss >> attributeDefault ;
313 
314  // Special case: attributeType is std::string and attributeDefault
315  // is set to a string meaning no default: set attributeDefault to empty string.
316  if ("std::string" == attributeType)
317  {
318  if ("\"\"" == attributeDefault || "-" == attributeDefault || "N/A" == attributeDefault)
319  {
320  attributeDefault.clear();
321  }
322  }
323 
324  oss << " \"" << attributeDefault << "\", ";
325 
326  // Read attribute short info
327  // The block delimiter string must be "\(" and "\)" in the text
328  // file but the string passed to the function must be preceeded
329  // by the escape symbol "\"
330  // We use raw string literals (R) to avoid escaping of any character. Anything between the delimiters becomes part of the string.
331  std::string attributeShortInfo = readBlockOfLines( fin, lineNumber ,R"f(\()f" , R"f(\))f" );
332  oss << " \"" << attributeShortInfo << "\", " ;
333 
334 
335  // Read attribute help info
336  // The block delimiter string must be "\(" and "\)" in the text
337  // file but the string passed to the function must be preceeded
338  // by the escape symbol "\"
339  // We use raw string literals (R) to avoid escaping of any character. Anything between the delimiters becomes part of the string.
340  std::string attributeHelpInfo = readBlockOfLines( fin , lineNumber , R"f(\()f", R"f(\))f");
341  oss << " \"" << attributeHelpInfo << "\", ";
342 
343  // Read keywords
344  // The block delimiter string must be "\(" and "\)" in the text
345  // file but the string passed to the function must be preceeded
346  // by the escape symbol "\"
347  // We use raw string literals (R) to avoid escaping of any character. Anything between the delimiters becomes part of the string.
348  std::string attributeKeywords = readBlockOfLines( fin , lineNumber , R"f(\()f", R"f(\))f");
349  duplicateParPlurals(attributeKeywords);
350  oss << " \"" << attributeKeywords << "\" ";
351 
352 
353  // Read optional flags for attribute
354  getline(fin, line);
355  lineNumber++;
356  std::string attributeFlagName,attributeFlagValue;
357 
358  // Set the flag value to default
359  attributeFlags = attributeFlagsRegistered ;
360 
361  while ( line.size() > 0 && line.find_first_of("#") != 0 )
362  {
363  iss.clear();
364  iss.str(line);
365  iss >> attributeFlagName >> attributeFlagValue;
366 
367  if ( attributeFlagName.size()==0 || attributeFlagValue.size()==0 )
368  {
369  errMsg = " An attribute flag name and value (bool) is expected (ex. RESTART_ATTRIBUTE yes). \n An empty line or a missing flag value (bool) is not valid.";
370  throw ( Exception(lineNumber,errMsg) );
371  }
372 
373  // Toupper the attribute flag name
374  toUpperCase( attributeFlagName );
375 
376  if ( attributeFlags.find(attributeFlagName) != attributeFlags.end() )
377  {
378  // The flag name is registered --> update the flag value
379 
380  toUpperCase( attributeFlagValue );
381  if ( attributeFlagValue.compare("YES")==0 || attributeFlagValue.compare("TRUE")==0 )
382  attributeFlags[attributeFlagName] = true;
383  else if ( attributeFlagValue.compare("NO")==0 || attributeFlagValue.compare("FALSE")==0 )
384  attributeFlags[attributeFlagName] = false;
385  else
386  {
387  errMsg = " An attribute flag name and value (bool) is expected (ex. RESTART_ATTRIBUTE yes). \n The value must be YES/TRUE or NO/FALSE.";
388  throw ( Exception(lineNumber,errMsg) );
389  }
390  }
391  else
392  {
393  errMsg = " An attribute flag name and value (bool) is expected (ex. RESTART_ATTRIBUTE yes).\n This flag name: " + attributeFlagName + " is not registered.";
394  throw ( Exception(lineNumber,errMsg) );
395  }
396 
397  getline(fin, line);
398  lineNumber++;
399  }
400 
401  // Write the flag in the registered order
402  for ( auto attFlag : attributeFlags )
403  {
404  oss << " , \"" << ((attFlag.second) ? "true":"false") << "\"";
405  }
406  oss << " }";
407 
408  getline(fin, line);
409  lineNumber++;
410 
411  firstAttribute = false;
412 
413  }
414  oss << " };";
415  oss << std::endl << std::endl << "#endif" << std::endl;
416 
417 
418  // input file is closed:
419  fin.close();
420 
421  // write header
422  // Default error message for problem opening file
423  fout.open( attDefHeader );
424 
425  if ( fout.fail() )
426  {
427  errMsg = " Failed to open the header file for writing attribute definition.";
428  throw ( Exception(0,errMsg) );
429  }
430  fout << oss.str() ;
431  fout.close();
432 
433  flagInFile = false;
434 
435  }
436  catch ( Exception & e)
437  {
438  fin.close();
439  std::cerr << "ERROR: Problem handling file for attribute definition: " << ((flagInFile) ? attDefFile:attDefHeader) << " at line " << e.getLineNumber() << ". \n" << e.what() << std::endl << std::endl;
440  return -1;
441  }
442  }
443  return 0;
444 }
Exception utility.
void toupper(std::string &s)
Put a string into upper cases.
Definition: utils.cpp:36
void duplicateParPlurals(std::string &blockOfStrings)
Utility to interpret plural words.
const char * what(void) const noexcept
Access to the error message.
const std::string attributeDefinitionNames[6]
size_t getLineNumber(void) const noexcept
std::string readBlockOfLines(std::ifstream &fin, size_t &lineNumber, const std::string &blockDelimiterOpen, const std::string &blockDelimiterClose)
Utility to read a block of lines.
void toUpperCase(std::string &str)
Toupper utility.
const std::map< std::string, bool > attributeFlagsRegistered
Registered attribute flags and default value.
std::string readBlockOfLines ( std::ifstream &  fin,
size_t &  lineNumber,
const std::string &  blockDelimiterOpen,
const std::string &  blockDelimiterClose 
)

Utility to read a block of lines.

Definition at line 105 of file WriteAttributeDefinitionFile.cpp.

110 {
111  std::string line;
112 
113  std::getline(fin, line);
114  lineNumber++;
115 
116 
117  if ( fin.fail() )
118  throw ( Exception(lineNumber,"Cannot read file") );
119 
120  // The block must be provided between delimiters
121  if (line.find( blockDelimiterOpen ) != 0)
122  {
123  std::string errMsg = " Cannot find opening delimiter ";
124  errMsg = errMsg.append(blockDelimiterOpen) ;
125  throw ( Exception(lineNumber,errMsg) );
126  }
127  std::string blockOfLines = line + " \\n ";
128 
129  // Take the content of line and put it in string
130  // with end of line
131  while ( line.empty() || line.find( blockDelimiterClose ) == std::string::npos )
132  {
133  std::getline(fin, line);
134  lineNumber++;
135 
136  if ( fin.fail() )
137  {
138  std::string errMsg = " Reached end of file without finding end delimiter ";
139  errMsg = errMsg.append(blockDelimiterClose) ;
140  throw ( Exception(lineNumber,errMsg) );
141  }
142 
143  blockOfLines += line + " \\n ";
144 
145  }
146 
147  // Remove block delimiters
148  blockOfLines.erase(0,blockDelimiterOpen.size() );
149  size_t posEnd = blockOfLines.find( blockDelimiterClose );
150  blockOfLines.erase(posEnd);
151 
152  return blockOfLines;
153 }
Exception utility.
void toUpperCase ( std::string &  str)

Toupper utility.

Definition at line 31 of file WriteAttributeDefinitionFile.cpp.

32 {
33  for_each(str.begin(), str.end(), [](char& in){ in = std::toupper(in); });
34 }
void toupper(std::string &s)
Put a string into upper cases.
Definition: utils.cpp:36

Variable Documentation

const std::string attributeDefinitionNames[6]
Initial value:
= { "displayAttributesDefinition",
"evalAttributesDefinition",
"cacheAttributesDefinition",
"evaluatorControlAttributesDefinition",
"pbAttributesDefinition",
"runAttributesDefinition" }

Definition at line 13 of file WriteAttributeDefinitionFile.cpp.

const std::map<std::string, bool> attributeFlagsRegistered
Initial value:
{
{"RESTART_ATTRIBUTE", false},
{"ALGO_COMPATIBILITY_CHECK", false},
{"UNIQUE_ENTRY", true} }

Registered attribute flags and default value.

The order of the registered attribute flags is important for attribute definition in the parameter classes. Default value for the registered flag is given here.

Definition at line 25 of file WriteAttributeDefinitionFile.cpp.