NOMAD Source  Version 4.0.0 Beta
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 [7]
 
const std::map< std::string, bool > attributeFlagsRegistered
 Registered attribute flags and default value. More...
 

Function Documentation

◆ duplicateParPlurals()

void duplicateParPlurals ( std::string &  blockOfStrings)

Utility to interpret plural words.

Definition at line 113 of file WriteAttributeDefinitionFile.cpp.

114 {
115  // Pad with blanks
116  blockOfStrings.insert(0," ");
117  blockOfStrings.append(" ");
118 
119  size_t posBegin = 0;
120 
121  // Loop on ()
122  while ( true )
123  {
124  size_t posPar1 = blockOfStrings.find( "(" , posBegin );
125  if ( posPar1 != std::string::npos )
126  {
127  size_t posBlank = blockOfStrings.rfind( " " , posPar1 );
128  size_t posPar2 = blockOfStrings.find( ")" ,posBegin );
129  if ( posPar2 != std::string::npos && posBlank < posPar2 )
130  {
131  // Word to duplicate
132  std::string word = blockOfStrings.substr(posBlank+1,posPar1-posBlank-1)+" ";
133 
134  // Remove parenthesis
135  blockOfStrings.erase(posPar2,1);
136  blockOfStrings.erase(posPar1,1);
137 
138  // Insert word without parenthesis
139  blockOfStrings.insert(posBlank+1,word);
140 
141  posBegin = posBlank;
142  }
143  else
144  break;
145  }
146  else
147  break;
148 
149  }
150 }

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 205 of file WriteAttributeDefinitionFile.cpp.

206 {
207  // Get directory where the input .txt files are.
208  std::string inputDir, outputDir;
209  if (argc > 1)
210  {
211  std::string s = argv[1];
212  // Ensure directory ends with '/'.
213  if (s[s.size()-1] != '/')
214  {
215  s += '/';
216  }
217  inputDir = s;
218  outputDir = s;
219  }
220 
221  std::ifstream fin;
222  std::ofstream fout;
223  std::string errMsg ;
224 
225  std::istringstream iss;
226  std::ostringstream oss;
227 
228  std::map<std::string,bool> attributeFlags;
229 
230  for ( auto attDefName : attributeDefinitionNames )
231  {
232  std::string attDefFile = inputDir + attDefName + ".txt";
233  std::string attDefHeader = outputDir + attDefName + ".hpp";
234 
235  // Clear input stream
236  iss.str("");
237  iss.clear();
238 
239  // Clear output stream
240  oss.str("");
241  oss.clear();
242  std::string UpperAttDefName = attDefName ;
243  for (auto & c: UpperAttDefName) c = toupper(c);
244 
245  oss << "//////////// THIS FILE MUST BE CREATED BY EXECUTING WriteAttributeDefinitionFile ////////////" << std::endl;
246  oss << "//////////// DO NOT MODIFY THIS FILE MANUALLY ///////////////////////////////////////////////" << std::endl << std::endl;
247 
248  oss << "#ifndef __NOMAD400_"<< UpperAttDefName << "__" << std::endl;
249  oss << "#define __NOMAD400_"<< UpperAttDefName << "__" << std::endl << std::endl;
250  oss << "_definition = {" ;
251 
252  bool flagInFile;
253  try
254  {
255  flagInFile=true;
256 
257  // Default error message for problem opening file
258  errMsg = " Failed to open file " + attDefFile + ".";
259 
260  size_t lineNumber=0;
261  fin.open ( attDefFile );
262 
263  if ( !fin.fail() )
264  {
265  errMsg.clear();
266  }
267  if ( !errMsg.empty() )
268  {
269  throw ( Exception( 0,errMsg ) );
270  }
271 
272  std::string line;
273  bool firstAttribute = true;
274 
275  while ( fin.good() && !fin.eof() )
276  {
277 
278  // Read attribute name
279  if ( firstAttribute )
280  {
281  getline(fin, line);
282  lineNumber++;
283  }
284 
285  // the previous getline may have reached end of file
286  if ( fin.eof() )
287  {
288  continue;
289  }
290 
291  if ( fin.fail() )
292  {
293  errMsg = " Failed to read file " + attDefFile + ".";
294  throw ( Exception(lineNumber,errMsg) );
295  }
296 
297  if ( line.size() > 0 && line.find_first_of("#")== 0 )
298  {
299  if (!firstAttribute)
300  {
301  getline(fin, line);
302  lineNumber++;
303  }
304  continue;
305  }
306 
307  // After the first attribute we need comma separation between attributes
308  if ( ! firstAttribute )
309  oss << "," << std::endl;
310  else
311  oss << std::endl;
312 
313  std::string attributeName;
314  iss.clear();
315  iss.str(line);
316  iss >> attributeName;
317 
318  if ( attributeName.size()==0)
319  {
320  errMsg = " The first word after a comment must be an attribute name. \n An empty line is not valid.";
321  throw ( Exception(lineNumber,errMsg) );
322  }
323  oss << "{ \"" << attributeName << "\", ";
324 
325  // Read attribute type
326  getline(fin, line);
327  lineNumber++;
328 
329  if ( fin.fail() || line.empty() )
330  {
331  errMsg = "Failed to read file " + attDefFile + ".";
332  throw ( Exception(lineNumber,errMsg) );
333  }
334 
335  std::string attributeType;
336  iss.clear();
337  iss.str(line);
338 
339  iss >> attributeType ;
340 
341  if ( attributeType.size()==0 )
342  {
343  errMsg = " The next word after an attribute name must be the attribute type. \n An empty line is not valid.";
344  throw ( Exception(lineNumber,errMsg) );
345  }
346  oss << " \"" << attributeType << "\", " ;
347 
348  // Read attribute default value (can be undefined)
349  getline(fin, line);
350  lineNumber++;
351 
352  if ( fin.fail() || line.empty() )
353  {
354  errMsg = " Failed to read file " + attDefFile + ".";
355  throw ( Exception(lineNumber,errMsg) );
356  }
357 
358  std::string attributeDefault= line;
359 
360 
361  // Special case: attributeType is std::string or NOMAD::ArrayOfString, and attributeDefault
362  // is set to a string meaning no default: set attributeDefault to empty string.
363  if ("std::string" == attributeType || "NOMAD::ArrayOfString" == attributeType)
364  {
365  if ("\"\"" == attributeDefault || "-" == attributeDefault || "N/A" == attributeDefault)
366  {
367  attributeDefault.clear();
368  }
369  }
370 
371  oss << " \"" << attributeDefault << "\", ";
372 
373  // Read attribute short info
374  // The block delimiter string must be "\(" and "\)" in the text
375  // file but the string passed to the function must be preceeded
376  // by the escape symbol "\"
377  // We use raw string literals (R) to avoid escaping of any character. Anything between the delimiters becomes part of the string.
378  std::string attributeShortInfo = readBlockOfLines( fin, lineNumber ,R"f(\()f" , R"f(\))f" );
379  oss << " \"" << attributeShortInfo << "\", " ;
380 
381 
382  // Read attribute help info
383  // The block delimiter string must be "\(" and "\)" in the text
384  // file but the string passed to the function must be preceeded
385  // by the escape symbol "\"
386  // We use raw string literals (R) to avoid escaping of any character. Anything between the delimiters becomes part of the string.
387  std::string attributeHelpInfo = readBlockOfLines( fin , lineNumber , R"f(\()f", R"f(\))f");
388 
389 
390  //Put attributeDefault value as a special line of HelpInfo
391  bool flagEmpty = attributeDefault.empty() || attributeDefault=="\"\"";
392  bool flagNoDefault = attributeDefault=="-";
393  attributeHelpInfo += ". ";
394  if (flagNoDefault)
395  {
396  attributeHelpInfo += "No default value.";
397  }
398  else if (flagEmpty)
399  {
400  attributeHelpInfo += "Default: Empty string.";
401  }
402  else
403  {
404  attributeHelpInfo += "Default: " + attributeDefault;
405  }
406  attributeHelpInfo += "\\n\\n";
407 
408  oss << " \"" << attributeHelpInfo << "\", ";
409 
410  // Read keywords
411  // The block delimiter string must be "\(" and "\)" in the text
412  // file but the string passed to the function must be preceeded
413  // by the escape symbol "\"
414  // We use raw string literals (R) to avoid escaping of any character. Anything between the delimiters becomes part of the string.
415  std::string attributeKeywords = readBlockOfLines( fin , lineNumber , R"f(\()f", R"f(\))f");
416  duplicateParPlurals(attributeKeywords);
417  oss << " \"" << attributeKeywords << "\" ";
418 
419 
420  // Read optional flags for attribute
421  getline(fin, line);
422  lineNumber++;
423  std::string attributeFlagName,attributeFlagValue;
424 
425  // Set the flag value to default
426  attributeFlags = attributeFlagsRegistered ;
427 
428  while ( line.size() > 0 && line.find_first_of("#") != 0 )
429  {
430  iss.clear();
431  iss.str(line);
432  iss >> attributeFlagName >> attributeFlagValue;
433 
434  if ( attributeFlagName.size()==0 || attributeFlagValue.size()==0 )
435  {
436  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.";
437  throw ( Exception(lineNumber,errMsg) );
438  }
439 
440  // Toupper the attribute flag name
441  toUpperCase( attributeFlagName );
442 
443  if ( attributeFlags.find(attributeFlagName) != attributeFlags.end() )
444  {
445  // The flag name is registered --> update the flag value
446 
447  toUpperCase( attributeFlagValue );
448  if ( attributeFlagValue.compare("YES")==0 || attributeFlagValue.compare("TRUE")==0 )
449  attributeFlags[attributeFlagName] = true;
450  else if ( attributeFlagValue.compare("NO")==0 || attributeFlagValue.compare("FALSE")==0 )
451  attributeFlags[attributeFlagName] = false;
452  else
453  {
454  errMsg = " An attribute flag name and value (bool) is expected (ex. RESTART_ATTRIBUTE yes). \n The value must be YES/TRUE or NO/FALSE.";
455  throw ( Exception(lineNumber,errMsg) );
456  }
457  }
458  else
459  {
460  errMsg = " An attribute flag name and value (bool) is expected (ex. RESTART_ATTRIBUTE yes).\n This flag name: " + attributeFlagName + " is not registered.";
461  throw ( Exception(lineNumber,errMsg) );
462  }
463 
464  getline(fin, line);
465  lineNumber++;
466  }
467 
468  // Write the flag in the registered order
469  for ( auto attFlag : attributeFlags )
470  {
471  oss << " , \"" << ((attFlag.second) ? "true":"false") << "\"";
472  }
473  oss << " }";
474 
475  getline(fin, line);
476  lineNumber++;
477 
478  firstAttribute = false;
479 
480  }
481  oss << " };";
482  oss << std::endl << std::endl << "#endif" << std::endl;
483 
484 
485  // input file is closed:
486  fin.close();
487 
488  // write header
489  // Default error message for problem opening file
490  fout.open( attDefHeader );
491 
492  if ( fout.fail() )
493  {
494  errMsg = " Failed to open the header file for writing attribute definition.";
495  throw ( Exception(0,errMsg) );
496  }
497  fout << oss.str() ;
498  fout.close();
499 
500  flagInFile = false;
501 
502  }
503  catch ( Exception & e)
504  {
505  fin.close();
506  std::cerr << "ERROR: Problem handling file for attribute definition: " << ((flagInFile) ? attDefFile:attDefHeader) << " at line " << e.getLineNumber() << ". \n" << e.what() << std::endl << std::endl;
507  return -1;
508  }
509  }
510  return 0;
511 }

◆ readBlockOfLines()

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 154 of file WriteAttributeDefinitionFile.cpp.

159 {
160  std::string line;
161 
162  std::getline(fin, line);
163  lineNumber++;
164 
165 
166  if ( fin.fail() )
167  throw ( Exception(lineNumber,"Cannot read file") );
168 
169  // The block must be provided between delimiters
170  if (line.find( blockDelimiterOpen ) != 0)
171  {
172  std::string errMsg = " Cannot find opening delimiter ";
173  errMsg = errMsg.append(blockDelimiterOpen) ;
174  throw ( Exception(lineNumber,errMsg) );
175  }
176  std::string blockOfLines = line + " \\n ";
177 
178  // Take the content of line and put it in string
179  // with end of line
180  while ( line.empty() || line.find( blockDelimiterClose ) == std::string::npos )
181  {
182  std::getline(fin, line);
183  lineNumber++;
184 
185  if ( fin.fail() )
186  {
187  std::string errMsg = " Reached end of file without finding end delimiter ";
188  errMsg = errMsg.append(blockDelimiterClose) ;
189  throw ( Exception(lineNumber,errMsg) );
190  }
191 
192  blockOfLines += line + " \\n ";
193 
194  }
195 
196  // Remove block delimiters
197  blockOfLines.erase(0,blockDelimiterOpen.size() );
198  size_t posEnd = blockOfLines.find( blockDelimiterClose );
199  blockOfLines.erase(posEnd);
200 
201  return blockOfLines;
202 }

◆ toUpperCase()

void toUpperCase ( std::string &  str)

Toupper utility.

Definition at line 80 of file WriteAttributeDefinitionFile.cpp.

81 {
82  for_each(str.begin(), str.end(), [](char& in){ in = std::toupper(in); });
83 }

Variable Documentation

◆ attributeDefinitionNames

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

Definition at line 61 of file WriteAttributeDefinitionFile.cpp.

◆ attributeFlagsRegistered

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 74 of file WriteAttributeDefinitionFile.cpp.

Exception::what
const char * what(void) const noexcept
Access to the error message.
Definition: WriteAttributeDefinitionFile.cpp:107
attributeFlagsRegistered
const std::map< std::string, bool > attributeFlagsRegistered
Registered attribute flags and default value.
Definition: WriteAttributeDefinitionFile.cpp:74
Exception::getLineNumber
size_t getLineNumber(void) const noexcept
Definition: WriteAttributeDefinitionFile.cpp:108
attributeDefinitionNames
const std::string attributeDefinitionNames[7]
Definition: WriteAttributeDefinitionFile.cpp:61
toupper
void toupper(std::string &s)
Put a string into upper cases.
Definition: utils.cpp:84
readBlockOfLines
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: WriteAttributeDefinitionFile.cpp:154
Exception
Exception utility.
Definition: WriteAttributeDefinitionFile.cpp:86
duplicateParPlurals
void duplicateParPlurals(std::string &blockOfStrings)
Utility to interpret plural words.
Definition: WriteAttributeDefinitionFile.cpp:113
toUpperCase
void toUpperCase(std::string &str)
Toupper utility.
Definition: WriteAttributeDefinitionFile.cpp:80