Cambridge SMT System
registrypo.hpp
Go to the documentation of this file.
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use these files except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 // http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 
13 // Copyright 2012 - Gonzalo Iglesias, Adrià de Gispert, William Byrne
14 
21 #ifndef REGISTRYPO_HPP
22 #define REGISTRYPO_HPP
23 
24 namespace HifstConstants {
25 // General. Some of them are extended with short versions of the program option
26 const std::string kHelp = "help";
27 const std::string kHelpExtended = kHelp + ",h";
28 // const string kLoggerVerbose="logger.verbose"; //defined in logger.hpp
29 const std::string kLoggerVerboseExtended = kLoggerVerbose + ",v";
30 const std::string kConfig = "config";
31 const std::string kConfigExtended = kConfig + ",c"; // short options
32 
33 }
34 
35 namespace ucam {
36 namespace util {
37 
38 using boost::any_cast;
39 namespace bpo = boost::program_options;
40 
41 inline void init_param_options ( int argc, const char* argv[],
42  bpo::variables_map *vm ); //forward definition
47 inline void initGlobalOptions (bpo::options_description& generic
48  , std::string& configFile) {
49  generic.add_options()
50  ( HifstConstants::kHelpExtended.c_str(), "produce help message" )
52  "log with more info messages " )
54  bpo::value<std::string> ( &configFile )->default_value ( "" ),
55  "name of a configuration file" );
56 }
57 
58 inline void parseOptionsGeneric ( bpo::options_description& desc
59  , bpo::variables_map *vm
60  , int argc, const char* argv[] ) {
61  std::string config_file;
62  bpo::options_description generic ( "Command-line options" );
63  initGlobalOptions (generic, config_file);
64  bpo::options_description cmdline_options;
65  cmdline_options.add ( generic ).add ( desc );
66  bpo::options_description config_file_options;
67  config_file_options.add ( desc );
68  bpo::positional_options_description p;
69  p.add ( HifstConstants::kConfig.c_str(), -1 );
70  bpo::store ( bpo::command_line_parser ( argc,
71  argv ).options ( cmdline_options ).positional ( p ).run(), *vm );
72  bpo::notify ( *vm );
73  if ( vm->count ( HifstConstants::kHelp.c_str() ) ) {
74  cout << cmdline_options << "\n";
75  exit ( EXIT_SUCCESS );
76  }
77  if ( config_file != "" ) {
78  std::vector<std::string> configFiles;
79  boost::algorithm::split (configFiles, config_file,
80  boost::algorithm::is_any_of (",") );
81  for (int k = configFiles.size() - 1 ; k >= 0; --k) {
82  LINFO ("Reading config file" << configFiles[k] );
83  std::ifstream ifs ( configFiles[k].c_str() );
84  if ( !ifs ) {
85  LERROR ( "can not open config file: " << configFiles[k] );
86  exit ( EXIT_FAILURE );
87  } else {
88  bpo::store ( parse_config_file ( ifs, config_file_options ), *vm );
89  bpo::notify ( *vm );
90  }
91  }
92  }
93 }
94 
95 class RegistryPO {
96  private:
98  bpo::variables_map vm_;
99 
100  public:
101 
108  std::string dump ( const std::string& decorator_start = "",
109  const std::string& decorator_end = "" ) {
110  std::stringstream ss;
111  ss << decorator_start << endl;
112  for ( bpo::variables_map::iterator itx = vm_.begin(); itx != vm_.end();
113  ++itx ) {
114  if ( !print<std::string> ( ss, itx ) )
115  if ( !print<uint> ( ss, itx ) )
116  if ( !print<int> ( ss, itx ) )
117  if ( !print<short> ( ss, itx ) )
118  if ( !print<long> ( ss, itx ) )
119  if ( !print<std::size_t> ( ss, itx ) )
120  if ( !print<float> ( ss, itx ) )
121  if ( !print<double> ( ss, itx ) )
122  if ( !print<char> ( ss, itx ) )
123  if ( !print<int64> ( ss, itx ) ) {
124  LERROR ( "Error dumping configuration -- type not recognized for:" <<
125  itx->first );
126  exit ( EXIT_FAILURE );
127  return ss.str() + decorator_end;
128  }
129  }
130  return ss.str() + decorator_end + "\n";
131  };
132 
134  RegistryPO ( const bpo::variables_map& vm ) : vm_ ( vm ) {};
143  RegistryPO ( int argc, const char* argv[] ) {
144  init_param_options ( argc, argv, &vm_ );
145  };
146 
155  RegistryPO ( const std::unordered_map<std::string, boost::any>& v ) {
156  bpo::options_description desc ( "" );
157  for ( std::unordered_map<std::string, boost::any>::const_iterator itx =
158  v.begin(); itx != v.end(); ++itx ) {
159  if ( any_cast<std::string> ( & ( itx->second ) ) ) {
160  desc.add_options() ( itx->first.c_str(),
161  bpo::value<std::string>()->default_value ( any_cast<std::string>
162  ( itx->second ) ), "" );
163  } else if ( itx->second.type() == typeid ( int ) ) {
164  desc.add_options() ( itx->first.c_str(),
165  bpo::value<int>()->default_value ( any_cast<int> ( itx->second ) ), "" );
166  } else if ( itx->second.type() == typeid ( uint ) ) {
167  desc.add_options() ( itx->first.c_str(),
168  bpo::value<uint>()->default_value ( any_cast<uint> ( itx->second ) ), "" );
169  } else if ( itx->second.type() == typeid ( bool ) ) {
170  desc.add_options() ( itx->first.c_str(),
171  bpo::value<bool>()->default_value ( any_cast<bool> ( itx->second ) ), "" );
172  } else if ( itx->second.type() == typeid ( char ) ) {
173  desc.add_options() ( itx->first.c_str(),
174  bpo::value<char>()->default_value ( any_cast<char> ( itx->second ) ), "" );
175  } else if ( itx->second.type() == typeid ( float ) ) {
176  desc.add_options() ( itx->first.c_str(),
177  bpo::value<float>()->default_value ( any_cast<float> ( itx->second ) ), "" );
178  } else if ( itx->second.type() == typeid ( double ) ) {
179  desc.add_options() ( itx->first.c_str(),
180  bpo::value<double>()->default_value ( any_cast<double> ( itx->second ) ), "" );
181  } else {
182  LERROR ( "Undetected type for " << itx->first );
183  exit ( EXIT_FAILURE );
184  }
185  uint ac = 0;
186  char **av = NULL;
187  bpo::store ( bpo::parse_command_line ( ac, av, desc ), vm_ );
188  bpo::notify ( vm_ );
189  }
190  };
191 
193  template<typename T>
194  inline T get ( const std::string& key ) const {
195  LDEBUG ( "Quering key=" << key );
196  // if (!USER_CHECK ( exists ( key ), "Key is not defined!" )){
197  if ( !exists ( key ) ) {
198  LERROR ( "Failed to query undefined program option key=" << key );
199  exit ( EXIT_FAILURE );
200  }
201  return vm_[key].as< T >();
202  };
203 
205  inline std::string getString ( const std::string& key ) const {
206  std::string value = get<std::string> ( key );
207  if ( value.size() > 7 )
208  if ( value.substr ( 0, 7 ) == "file://" ) {
209  LINFO ( "Loading from " << value.substr ( 7 ) );
210  iszfstream aux ( value.substr ( 7 ) );
211  std::string line;
212  value = "";
213  while ( !aux.eof() ) {
214  getline ( aux, line );
215  boost::algorithm::trim ( line );
216  if ( line != "" ) value += " " + line;
217  }
218  aux.close();
219  boost::algorithm::trim ( value );
220  }
221  return value;
222  };
223 
225  inline bool getBool ( const std::string& key ) const {
226  std::string value = get<std::string> ( key );
227  boost::algorithm::trim ( value );
228  if (value == "yes") return true;
229  else if (value == "no") return false;
230  LERROR ("Expected yes|no value for program option --" << key);
231  exit (EXIT_FAILURE);
232  };
233 
235  bool exists ( const std::string& key ) const {
236  return vm_.count ( key ) > 0;
237  };
238 
245  inline std::vector<std::string> getVectorString ( const std::string& key )
246  const {
247  std::vector<std::string> vaux;
248  std::string aux = get<std::string> ( key );
249  if ( aux != "" ) boost::algorithm::split ( vaux, aux,
250  boost::algorithm::is_any_of ( ", " ) );
251  return vaux;
252  };
253 
261  inline std::string getVectorString ( const std::string& key ,
262  uint index ) const {
263  std::vector<std::string> vaux = getVectorString ( key );
264  if ( !vaux.size() && !index ) return std::string ( "" );
265  LDEBUG ( "Accessing " << key << ",with index=" << index );
266  if ( index > vaux.size() - 1 ) {
267  LERROR ( "Wrong index at program option key=" << key );
268  exit ( EXIT_FAILURE );
269  }
270  return vaux[index];
271  };
272 
279  inline unordered_set<std::string> getSetString ( const std::string& key ) const {
280  std::vector<std::string> vaux = getVectorString ( key );
281  unordered_set<std::string> saux;
282  for ( uint k = 0; k < vaux.size(); ++k )
283  saux.insert ( vaux[k] );
284  return saux;
285  };
286 
293  template<typename NumberT>
294  inline unordered_set<NumberT> getSetNumber ( const std::string& key ) const {
295  std::vector<std::string> vaux = getVectorString ( key );
296  unordered_set<NumberT> saux;
297  for ( uint k = 0; k < vaux.size(); ++k )
298  saux.insert ( toNumber<NumberT> (vaux[k]) );
299  return saux;
300  };
301 
308  unordered_map<uint, std::string> getMappedIndexString ( const std::string& key )
309  const {
310  std::vector <std::string> aux = getVectorString ( key );
311  unordered_map<uint, std::string> mraux;
312  for ( uint k = 0; k < aux.size(); ++k )
313  mraux[k + 1] = aux[k]; //Note that mapped indices always start from 1
314  return mraux;
315  };
316 
323  inline unordered_map<std::string, uint> getMappedStringIndex (
324  const std::string& key ) const {
325  std::vector <std::string> aux = getVectorString ( key );
326  unordered_map<std::string, uint> miraux;
327  for ( uint k = 0; k < aux.size(); ++k ) {
328  miraux[aux[k]] = k + 1; //Note that mapped inverse indices always start from 1
329  }
330  return miraux;
331  };
332 
340  unordered_map<std::string, uint> getPairMappedStringUInt (
341  const std::string& key ) const {
342  std::vector <std::string> aux = getVectorString ( key );
343  unordered_map<std::string, uint> mraux;
344  if ( !USER_CHECK ( ! ( aux.size() % 2 ),
345  "Values are expected to come by pairs string,uint,string,uint,..." ) )
346  return mraux;
347  for ( uint k = 0; k < aux.size(); k += 2 )
348  mraux[aux[k]] = toNumber<uint> ( aux[k + 1] );
349  return mraux;
350  };
351 
352  private:
353 
360  template <class T>
361  inline bool print ( std::stringstream& ss, bpo::variables_map::iterator itx ) {
362  if ( any_cast<T> ( & ( itx->second.value() ) ) ) {
363  std::stringstream ssaux;
364  ssaux << any_cast<T> ( itx->second.value() );
365  if ( ssaux.str() != "" )
366  ss << "\t\t+" << itx->first << "=" << any_cast<T> ( itx->second.value() ) <<
367  endl;
368  else
369  ss << "\t\t+" << itx->first << endl;
370  return true;
371  }
372  return false;
373  };
374 
375  DISALLOW_COPY_AND_ASSIGN ( RegistryPO );
376 
377 };
378 
379 }
380 } // end of namespaces
381 
382 #endif
void parseOptionsGeneric(bpo::options_description &desc, bpo::variables_map *vm, int argc, const char *argv[])
Definition: registrypo.hpp:58
const std::string kConfigExtended
Definition: registrypo.hpp:31
void run(ucam::util::RegistryPO const &rg)
void init_param_options(int argc, const char *argv[], bpo::variables_map *vm)
std::vector< std::string > getVectorString(const std::string &key) const
Convenience method that returns a vector of strings taking "," as the separator character.
Definition: registrypo.hpp:245
#define LINFO(msg)
RegistryPO(int argc, const char *argv[])
Constructor Runs init_param_options to parse and store in a bpo::variables_map all the values...
Definition: registrypo.hpp:143
unordered_set< NumberT > getSetNumber(const std::string &key) const
Templated method that returns a set of numbers taking "," as the separator character.
Definition: registrypo.hpp:294
#define LDEBUG(msg)
const std::string kConfig
Definition: registrypo.hpp:30
unordered_map< uint, std::string > getMappedIndexString(const std::string &key) const
Convenience method that returns a hash of strings indexed by position and taking "," as the separator character.
Definition: registrypo.hpp:308
std::string getVectorString(const std::string &key, uint index) const
Convenience method that returns a vector of strings taking "," as the separator character.
Definition: registrypo.hpp:261
unordered_map< std::string, uint > getMappedStringIndex(const std::string &key) const
Convenience method that returns a hash of indices indexed by string and taking "," as the separator c...
Definition: registrypo.hpp:323
iszfstream & getline(iszfstream &izs, std::string &line)
Definition: szfstream.hpp:178
unordered_map< std::string, uint > getPairMappedStringUInt(const std::string &key) const
Convenience method that builds a hash with pairs taking "," as the separator character. Pair elements assumed to be unsigned integers. For instance, –param=X,3,T,5 => hash["X"]=3 and hash["T"]=5.
Definition: registrypo.hpp:340
bool exists(const std::string &source, const std::string &needle)
Convenience function to find out whether a needle exists in a text.
std::string getString(const std::string &key) const
Performs get<string> and checks whether the real value is to be loaded from file (–param=file://.....)
Definition: registrypo.hpp:205
const std::string kHelpExtended
Definition: registrypo.hpp:27
bool exists(const std::string &key) const
Determines whether a program option (key) has been defined by the user.
Definition: registrypo.hpp:235
const std::string kHelp
Definition: registrypo.hpp:26
const std::string kLoggerVerbose
Definition: logger.hpp:25
bool getBool(const std::string &key) const
To handle yes|no program option values.
Definition: registrypo.hpp:225
void initGlobalOptions(bpo::options_description &generic, std::string &configFile)
class wrapping around the boost program_options variable with parsed values.
Definition: registrypo.hpp:47
std::string dump(const std::string &decorator_start="", const std::string &decorator_end="")
Dumps all configuration parameters into a string with a reasonably pretty format. ...
Definition: registrypo.hpp:108
#define USER_CHECK(exp, comment)
Tests whether exp is true. If not, comment is printed and program ends.
#define LERROR(msg)
const std::string kLoggerVerboseExtended
Definition: registrypo.hpp:29
Wrapper stream class that reads pipes, text files or gzipped files.
Definition: szfstream.hpp:34
Definition: bleu.hpp:14
RegistryPO(const bpo::variables_map &vm)
Trivial Constructor.
Definition: registrypo.hpp:134
RegistryPO(const std::unordered_map< std::string, boost::any > &v)
Constructor Forces a set of values using program_options. The hashmap can contain either bools...
Definition: registrypo.hpp:155
unordered_set< std::string > getSetString(const std::string &key) const
Convenience method that returns a set of strings taking "," as the separator character.
Definition: registrypo.hpp:279