Pol  Revision:cb584c9
cfgrepos.cpp
Go to the documentation of this file.
1 
18 #include "cfgrepos.h"
19 
20 #include <ctype.h>
21 #include <exception>
22 #include <iosfwd>
23 #include <stdlib.h>
24 #include <sys/stat.h>
25 
26 #include "../bscript/bobject.h"
27 #include "../bscript/escrutil.h"
28 #include "../bscript/impstr.h"
29 #include "../clib/cfgelem.h"
30 #include "../clib/cfgfile.h"
31 #include "../clib/fileutil.h"
32 #include "../clib/logfacility.h"
33 #include "../clib/strutil.h"
34 #include "../plib/pkg.h"
35 #include "../plib/systemstate.h"
36 #include "globals/ucfg.h"
37 #include "polcfg.h"
38 
39 namespace Pol
40 {
41 namespace Core
42 {
44 {
45  std::string propname, propval;
46 
47  while ( elem.remove_first_prop( &propname, &propval ) )
48  {
50 
51  addprop( propname, newimp );
52  }
53 }
54 
55 // ToDo: we have to think over... it's a problem with script-inside references
57 {
58  // while (!propimps_.empty())
59  // {
60  // delete ((*propimps_.begin()).second);
61  // propimps_.erase( propimps_.begin() );
62  // }
63 }
64 
65 void StoredConfigElem::addprop( const std::string& propname, Bscript::BObjectImp* imp )
66 {
67  propimps_.insert( PropImpList::value_type( boost_utils::cfg_key_flystring( propname ),
69 }
70 
71 Bscript::BObjectImp* StoredConfigElem::getimp( const std::string& propname ) const
72 {
73  PropImpList::const_iterator itr = propimps_.find( boost_utils::cfg_key_flystring( propname ) );
74  if ( itr == propimps_.end() )
75  return nullptr;
76  else
77  return ( *itr ).second.get();
78 }
79 
81 {
83  PropImpList::const_iterator itr;
84  for ( itr = propimps_.begin(); itr != propimps_.end(); ++itr )
85  {
86  Bscript::String propname( ( *itr ).first );
87  if ( !objarr->contains( propname ) )
88  objarr->addElement( propname.copy() );
89  }
90  return objarr;
91 }
92 
93 std::pair<StoredConfigElem::const_iterator, StoredConfigElem::const_iterator>
94 StoredConfigElem::equal_range( const std::string& propname ) const
95 {
96  return propimps_.equal_range( boost_utils::cfg_key_flystring( propname ) );
97 }
98 
100 {
101  size_t size = 0;
102  for ( const auto& pair : propimps_ )
103  {
104  size_t elemsize = sizeof( ref_ptr<Bscript::BObjectImp> );
105  if ( pair.second.get() != nullptr )
106  elemsize = pair.second->sizeEstimate();
107  size += ( sizeof( pair.first ) + elemsize ) + ( sizeof( void* ) * 3 + 1 ) / 2;
108  }
109  return size;
110 }
111 
112 StoredConfigFile::StoredConfigFile() : reload( false ), modified_( 0 ) {}
113 
114 // ToDo: we have to think over... it's a problem with script-inside references
115 // StoredConfigFile::~StoredConfigFile( )
116 //{
117 // while (!elements_bynum_.empty())
118 // {
119 // delete ((*elements_bynum_.begin()).second);
120 // elements_bynum_.erase( elements_bynum_.begin() );
121 // }
122 //
123 // while (!elements_byname_.empty())
124 // {
125 // delete ((*elements_byname_.begin()).second);
126 // elements_byname_.erase( elements_byname_.begin() );
127 // }
128 //}
129 
131 {
132  reload = false;
133  modified_ = cf.modified();
134 
135  Clib::ConfigElem elem;
136  while ( cf.read( elem ) )
137  {
138  ElemRef elemref( new StoredConfigElem( elem ) );
139 
140  if ( isdigit( elem.rest()[0] ) )
141  {
142  unsigned int key = strtoul( elem.rest(), nullptr, 0 );
143  elements_bynum_.insert( ElementsByNum::value_type( key, elemref ) );
144  }
145 
146  std::string key( elem.rest() );
147  elements_byname_.insert( ElementsByName::value_type( key, elemref ) );
148  }
149 }
150 
152 {
153  ElementsByNum::const_iterator itr = elements_bynum_.find( key );
154  if ( itr == elements_bynum_.end() )
155  return ElemRef( 0 );
156  else
157  return ( *itr ).second;
158 }
159 
161 {
162  ElementsByName::const_iterator itr = elements_byname_.find( key );
163  if ( itr == elements_byname_.end() )
164  return ElemRef( 0 );
165  else
166  return ( *itr ).second;
167 }
168 
170 {
171  if ( elements_bynum_.empty() )
172  {
173  return 0;
174  }
175  else
176  {
177  ElementsByNum::const_iterator itr = elements_bynum_.end();
178  --itr;
179  return ( *itr ).first;
180  }
181 }
182 
184 {
185  return modified_;
186 }
187 
188 // From "[some stuff]" return "some stuff"
189 std::string extractkey( const std::string& istr )
190 {
191  std::string::size_type vstart = istr.find_first_not_of( " [" );
192  std::string::size_type vend = istr.find_last_not_of( "] " );
193  return istr.substr( vstart, vend );
194 }
195 
196 void StoredConfigFile::load_tus_scp( const std::string& filename )
197 {
198  std::ifstream ifs( filename.c_str() );
199 
200  int count = 0;
201  ElemRef elemref( new StoredConfigElem() );
202  elements_bynum_.insert( ElementsByNum::value_type( count++, elemref ) );
203 
204  std::string strbuf;
205  while ( getline( ifs, strbuf ) )
206  {
207  if ( strbuf[0] == '[' )
208  {
209  elemref.set( new StoredConfigElem() );
210  elements_bynum_.insert( ElementsByNum::value_type( count++, elemref ) );
211  strbuf = extractkey( strbuf );
212  elemref->addprop( "_key", Bscript::bobject_from_string( strbuf, 16 ) );
213  }
214  // FIXME: skip empty lines and comment lines (duh)
215  std::string propname, propvalue;
216  Clib::splitnamevalue( strbuf, propname, propvalue );
217 
218  if ( propname == "" || propname.substr( 0, 2 ) == "//" )
219  continue;
220 
221  Bscript::BObjectImp* newimp = Bscript::bobject_from_string( propvalue, 16 );
222 
223  elemref->addprop( propname, newimp );
224  }
225 }
226 
228 {
229  size_t size = sizeof( bool ) /* bool reload*/
230  + sizeof( time_t ); /* time_t modified_*/
231 
232  for ( const auto& pair : elements_byname_ )
233  {
234  size_t elemsize = sizeof( ElemRef );
235  if ( pair.second.get() != nullptr )
236  elemsize = pair.second->estimateSize();
237  size += ( pair.first.capacity() + elemsize ) + ( sizeof( void* ) * 3 + 1 ) / 2;
238  }
239  // both maps share the same ref
240  size += ( ( sizeof( int ) + sizeof( ElemRef ) ) + ( sizeof( void* ) * 3 + 1 ) / 2 ) *
241  elements_bynum_.size();
242  return size;
243 }
244 
245 ConfigFileRef FindConfigFile( const std::string& filename, const std::string& allpkgbase )
246 {
247  CfgFiles::iterator itr = Core::configurationbuffer.cfgfiles.find( filename );
248  if ( itr != Core::configurationbuffer.cfgfiles.end() )
249  {
250  if ( ( *itr ).second->reload ) // check cfg file modification?
251  {
252  struct stat newcfgstat;
253  stat( filename.c_str(), &newcfgstat );
254  if ( ( *itr ).second->modified() != newcfgstat.st_mtime )
255  {
256  Core::configurationbuffer.oldcfgfiles.push_back( ( *itr ).first );
257  Core::configurationbuffer.cfgfiles.erase( itr );
258  }
259  else
260  return ( *itr ).second;
261  }
262  else
263  return ( *itr ).second;
264  }
265 
266  try
267  {
268  if ( !allpkgbase.empty() )
269  {
270  bool any = false;
272  std::string main_cfg = "config/" + allpkgbase + ".cfg";
273  if ( Clib::FileExists( main_cfg.c_str() ) )
274  {
275  Clib::ConfigFile cf_main( main_cfg.c_str() );
276  scfg->load( cf_main );
277  any = true;
278  }
279  for ( Plib::Packages::iterator pitr = Plib::systemstate.packages.begin(),
280  pitrend = Plib::systemstate.packages.end();
281  pitr != pitrend; ++pitr )
282  {
283  Plib::Package* pkg = ( *pitr );
284  // string pkgfilename = pkg->dir() + allpkgbase + ".cfg";
285  std::string pkgfilename = GetPackageCfgPath( pkg, allpkgbase + ".cfg" );
286  if ( Clib::FileExists( pkgfilename.c_str() ) )
287  {
288  Clib::ConfigFile cf( pkgfilename.c_str() );
289  scfg->load( cf );
290  any = true;
291  }
292  }
293  if ( !any )
294  return ConfigFileRef( 0 );
295  Core::configurationbuffer.cfgfiles.insert( CfgFiles::value_type( filename, scfg ) );
296  return scfg;
297  }
298  else
299  {
300  if ( !Clib::FileExists( filename.c_str() ) )
301  {
302  if ( Plib::systemstate.config.report_missing_configs )
303  {
304  DEBUGLOG << "Config File " << filename << " does not exist.\n";
305  }
306  return ConfigFileRef( 0 );
307  }
308 
309  Clib::ConfigFile cf( filename.c_str() );
310 
312  scfg->load( cf );
313  Core::configurationbuffer.cfgfiles.insert( CfgFiles::value_type( filename, scfg ) );
314  return scfg;
315  }
316  }
317  catch ( std::exception& ex )
318  {
319  // There was some weird problem reading the config file.
320  DEBUGLOG << "An exception was encountered while reading " << filename << ": " << ex.what()
321  << "\n";
322  return ConfigFileRef( 0 );
323  }
324 }
325 
326 ConfigFileRef LoadTusScpFile( const std::string& filename )
327 {
328  if ( !Clib::FileExists( filename.c_str() ) )
329  {
330  return ConfigFileRef( 0 );
331  }
332 
334  scfg->load_tus_scp( filename );
335  return scfg;
336 }
337 
338 void CreateEmptyStoredConfigFile( const std::string& filename )
339 {
341  Core::configurationbuffer.cfgfiles.insert( CfgFiles::value_type( filename, scfg ) );
342 }
343 
344 int UnloadConfigFile( const std::string& filename )
345 {
346  CfgFiles::iterator itr = Core::configurationbuffer.cfgfiles.find( filename );
347  if ( itr != Core::configurationbuffer.cfgfiles.end() )
348  {
349  ( *itr ).second->reload = true; // check cfg file modification on FindConfigFile
350 
351  return ( *itr ).second->count() - 1;
352  }
353  else
354  {
355  return -1;
356  }
357 }
358 
359 #ifdef MEMORYLEAK
360 void ConfigFiles_log_stuff()
361 {
362  DEBUGLOG << "ConfigFiles: " << Core::configurationbuffer.cfgfiles.size() << " files loaded and "
363  << Core::configurationbuffer.oldcfgfiles.size() << " files 'removed'\n";
364 
366  << Core::configurationbuffer.oldcfgfiles.size() << ";";
367 }
368 #endif
369 }
370 }
bool remove_first_prop(std::string *propname, std::string *value)
Definition: cfgfile.cpp:100
ref_ptr< StoredConfigElem > ElemRef
Definition: cfgrepos.h:75
boost::flyweight< std::string, boost::flyweights::tag< cfg_key_tag >, FLYWEIGHT_HASH_FACTORY > cfg_key_flystring
Definition: boostutils.h:136
void splitnamevalue(const std::string &istr, std::string &propname, std::string &propvalue)
Definition: strutil.cpp:107
ref_ptr< StoredConfigFile > ConfigFileRef
Definition: cfgrepos.h:101
SystemState systemstate
Definition: systemstate.cpp:12
void addprop(const std::string &propname, Bscript::BObjectImp *imp)
Definition: cfgrepos.cpp:65
void CreateEmptyStoredConfigFile(const std::string &filename)
Definition: cfgrepos.cpp:338
int UnloadConfigFile(const std::string &filename)
Definition: cfgrepos.cpp:344
ElementsByName elements_byname_
Definition: cfgrepos.h:90
OldCfgFiles oldcfgfiles
Definition: ucfg.h:50
virtual long contains(const BObjectImp &imp) const POL_OVERRIDE
Definition: object.cpp:1429
void load(Clib::ConfigFile &cf)
Definition: cfgrepos.cpp:130
const char * rest() const
Definition: cfgfile.cpp:71
#define LEAKLOG
Definition: logfacility.h:241
#define DEBUGLOG
Definition: logfacility.h:237
virtual BObjectImp * copy() const POL_OVERRIDE
Definition: impstr.h:53
Definition: refptr.h:65
BObjectImp * bobject_from_string(const std::string &str, int radix)
Definition: escrutil.cpp:125
ConfigurationBuffer configurationbuffer
Definition: ucfg.cpp:13
Bscript::BObjectImp * listprops() const
Definition: cfgrepos.cpp:80
size_t estimateSize() const
Definition: cfgrepos.cpp:227
Bscript::BObjectImp * getimp(const std::string &propname) const
Definition: cfgrepos.cpp:71
void load_tus_scp(const std::string &filename)
Definition: cfgrepos.cpp:196
ElementsByNum elements_bynum_
Definition: cfgrepos.h:92
unsigned int count() const
Definition: refptr.h:130
ElemRef findelem(int key)
Definition: cfgrepos.cpp:151
void addElement(BObjectImp *imp)
Definition: object.cpp:1399
size_t estimateSize() const
Definition: cfgrepos.cpp:99
std::string GetPackageCfgPath(const Package *pkg, const std::string &filename)
Definition: pkg.cpp:491
std::string extractkey(const std::string &istr)
Definition: cfgrepos.cpp:189
bool FileExists(const char *filename)
Definition: fileutil.cpp:118
void set(T *ptr)
Definition: refptr.h:276
bool read(ConfigElem &elem)
Definition: cfgfile.cpp:1015
ConfigFileRef FindConfigFile(const std::string &filename, const std::string &allpkgbase)
Definition: cfgrepos.cpp:245
ConfigFileRef LoadTusScpFile(const std::string &filename)
Definition: cfgrepos.cpp:326
Definition: berror.cpp:12
time_t modified() const
Definition: cfgrepos.cpp:183
time_t modified() const
Definition: cfgfile.cpp:591
std::pair< const_iterator, const_iterator > equal_range(const std::string &propname) const
Definition: cfgrepos.cpp:94