mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
appConfigurator.cpp
Go to the documentation of this file.
1/** \file appConfigurator.cpp
2 * \author Jared R. Males
3 * \brief Implementation of An application configuration manager
4 *
5 * \ingroup mxApp_files
6 *
7 */
8
9//***********************************************************************//
10// Copyright 2021 Jared R. Males (jaredmales@gmail.com)
11//
12// This file is part of mxlib.
13//
14// mxlib is free software: you can redistribute it and/or modify
15// it under the terms of the GNU General Public License as published by
16// the Free Software Foundation, either version 3 of the License, or
17// (at your option) any later version.
18//
19// mxlib is distributed in the hope that it will be useful,
20// but WITHOUT ANY WARRANTY; without even the implied warranty of
21// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22// GNU General Public License for more details.
23//
24// You should have received a copy of the GNU General Public License
25// along with mxlib. If not, see <http://www.gnu.org/licenses/>.
26//***********************************************************************//
27
29
30namespace mx
31{
32namespace app
33{
34
36{
37 m_targets.clear();
38 clOnlyTargets.clear();
39 nonOptions.clear();
40 m_unusedConfigs.clear();
41}
42
44{
45
46 // First check for duplicate name and command line only
47 if( m_targets.count( tgt.name ) > 0 && tgt.section == "" && tgt.keyword == "" )
48 {
49 clOnlyTargets.push_back( tgt );
50 clOnlyTargets.back().orderAdded = nAdded;
51 }
52 else
53 {
54 std::pair<targetIterator, bool> res = m_targets.insert( { tgt.name, tgt } );
55 res.first->second.orderAdded = nAdded;
56 }
57
58 ++nAdded;
59}
60
61void appConfigurator::add( const std::string &n,
62 const std::string &so,
63 const std::string &lo,
64 int clt,
65 const std::string &s,
66 const std::string &kw,
67 bool isReq,
68 const std::string &ht,
69 const std::string &he )
70{
71 add( configTarget( n, so, lo, clt, s, kw, isReq, ht, he ) );
72}
73
74void appConfigurator::parseCommandLine( int argc, char **argv, const std::string &oneTarget )
75{
76 if( argc == 0 )
77 return;
78
79 clOptions clOpts;
80
81 // First load the options into the clOptions parser
83 for( it = m_targets.begin(); it != m_targets.end(); ++it )
84 {
85 if( it->second.shortOpt == "" && it->second.longOpt == "" )
86 continue; // No command line opts specified.
87
88 clOpts.add( it->second.name, it->second.shortOpt.c_str(), it->second.longOpt.c_str(), it->second.clType );
89 }
90
91 // Then load the command-line-only options.
93 for( cloit = clOnlyTargets.begin(); cloit != clOnlyTargets.end(); ++cloit )
94 {
95 if( cloit->shortOpt == "" && cloit->longOpt == "" )
96 continue; // Nothing to add?
97
98 clOpts.add( cloit->name, cloit->shortOpt.c_str(), cloit->longOpt.c_str(), cloit->clType );
99 }
100
101 // Now we parse
102 clOpts.parse( argc, argv, &nonOptions );
103
104 if( clOpts.numUnknown() > 0 )
105 {
106 std::vector<std::string> unk;
107 clOpts.unknown( unk );
108
109 for( size_t n = 0; n < unk.size(); ++n )
110 {
111 // Insert or update existing
112 m_unusedConfigs[unk[n]].name = unk[n];
113 if( m_sources )
114 m_unusedConfigs[unk[n]].sources.push_back( "command line" );
115 m_unusedConfigs[unk[n]].set = true;
116 }
117 }
118
119 // If nothing more to do, get out
120 if( clOpts.nOpts == 0 )
121 {
122 return;
123 }
124 // And then load the results in the config target map.
125 for( it = m_targets.begin(); it != m_targets.end(); ++it )
126 {
127 if( oneTarget != "" && it->second.name != oneTarget )
128 continue;
129
130 if( clOpts.optSet( it->second.name ) )
131 {
132 std::vector<std::string> args;
133
134 clOpts.getAll( args, it->second.name );
135
136 it->second.values.insert( it->second.values.end(), args.begin(), args.end() );
137 if( m_sources )
138 {
139 for( size_t n = 0; n < args.size(); ++n )
140 it->second.sources.push_back( "command line" );
141 }
142
143 it->second.verbosity = clOpts.count( it->second.name );
144 it->second.set = true;
145 }
146 }
147}
148
149int appConfigurator::readConfig( const std::string &fname, bool reportFileNotFound )
150{
151 // Handle empty string quietly
152 if( fname == "" )
153 return 0;
154
155 iniFile iF;
156
157 ///\todo update error handling to include >0 (line numer of parse error) and -2 memory allocation error.
158 int prv = iF.parse( fname );
159
160 if( prv == -1 )
161 {
162 if( !reportFileNotFound )
163 return -1;
164
165 internal::mxlib_error_report( error_t::filenotfound, "The file " + fname + " was not found" );
166 return -1;
167 }
168
169 if( prv == -2 )
170 {
171 internal::mxlib_error_report( error_t::allocerr, "Memory allocation error in config file parser" );
172 return -1;
173 }
174
175 if( prv > 0 )
176 {
178 "Parsing error in " + fname + " at line " + std::to_string( prv ) );
179 return -1;
180 }
181
183
184 for( it = m_targets.begin(); it != m_targets.end(); ++it )
185 {
186 if( iF.count( it->second.section, it->second.keyword ) > 0 )
187 {
188 it->second.values.push_back( iF( it->second.section, it->second.keyword ) );
189 if( m_sources )
190 {
191 it->second.sources.push_back( fname );
192 }
193 it->second.set = true;
194
195 iF.erase( it->second.section, it->second.keyword ); // Erase it from the iniFile map.
196 }
197 }
198
199 // here set aside non-deleted iF entries
200 for( auto iFit = iF.names.begin(); iFit != iF.names.end(); ++iFit )
201 {
202 // Insert or update existing
203 m_unusedConfigs[iFit->first].name = iFit->first;
204
205 std::string sect, nam;
206 iniFile::parseKey( sect, nam, iFit->first );
207 m_unusedConfigs[iFit->first].section = sect;
208 m_unusedConfigs[iFit->first].keyword = nam;
209
210 m_unusedConfigs[iFit->first].values.push_back( iFit->second );
211
212 if( m_sources )
213 m_unusedConfigs[iFit->first].sources.push_back( fname );
214
215 m_unusedConfigs[iFit->first].set = true;
216 }
217
218 return 0;
219}
220
221bool appConfigurator::isSet( const std::string &name, std::unordered_map<std::string, configTarget> &targets )
222{
223 if( targets.count( name ) == 0 )
224 return false;
225
226 targets[name].used = true;
227
228 return targets[name].set;
229}
230
231bool appConfigurator::isSet( const std::string &name )
232{
233 return isSet( name, m_targets );
234}
235
236int appConfigurator::count( const std::string &name, std::unordered_map<std::string, configTarget> &targets )
237{
238 targets[name].used = true;
239 return targets[name].values.size();
240}
241
242int appConfigurator::count( const std::string &name )
243{
244 return count( name, m_targets );
245}
246
247int appConfigurator::verbosity( const std::string &name, std::unordered_map<std::string, configTarget> &targets )
248{
249 targets[name].used = true;
250 return targets[name].verbosity;
251}
252
253int appConfigurator::verbosity( const std::string &name )
254{
255 return verbosity( name, m_targets );
256}
257
258//+++++++++++++++++++++++++++++++++++++
259// Explicit instants:
260//+++++++++++++++++++++++++++++++++++++
261
262template int appConfigurator::get<char>( char &v,
263 const std::string &name,
264 size_t i,
265 std::unordered_map<std::string, configTarget> &targets );
266
267template int appConfigurator::get<signed char>( signed char &v,
268 const std::string &name,
269 size_t i,
270 std::unordered_map<std::string, configTarget> &targets );
271
272template int appConfigurator::get<short>( short &v,
273 const std::string &name,
274 size_t i,
275 std::unordered_map<std::string, configTarget> &targets );
276
277template int appConfigurator::get<int>( int &v,
278 const std::string &name,
279 size_t i,
280 std::unordered_map<std::string, configTarget> &targets );
281
282template int appConfigurator::get<long>( long &v,
283 const std::string &name,
284 size_t i,
285 std::unordered_map<std::string, configTarget> &targets );
286
287template int appConfigurator::get<long long>( long long &v,
288 const std::string &name,
289 size_t i,
290 std::unordered_map<std::string, configTarget> &targets );
291
292template int appConfigurator::get<unsigned char>( unsigned char &v,
293 const std::string &name,
294 size_t i,
295 std::unordered_map<std::string, configTarget> &targets );
296
297template int appConfigurator::get<unsigned short>( unsigned short &v,
298 const std::string &name,
299 size_t i,
300 std::unordered_map<std::string, configTarget> &targets );
301
302template int appConfigurator::get<unsigned int>( unsigned int &v,
303 const std::string &name,
304 size_t i,
305 std::unordered_map<std::string, configTarget> &targets );
306
307template int appConfigurator::get<unsigned long>( unsigned long &v,
308 const std::string &name,
309 size_t i,
310 std::unordered_map<std::string, configTarget> &targets );
311
312template int appConfigurator::get<unsigned long long>( unsigned long long &v,
313 const std::string &name,
314 size_t i,
315 std::unordered_map<std::string, configTarget> &targets );
316
317template int appConfigurator::get<float>( float &v,
318 const std::string &name,
319 size_t i,
320 std::unordered_map<std::string, configTarget> &targets );
321
322template int appConfigurator::get<double>( double &v,
323 const std::string &name,
324 size_t i,
325 std::unordered_map<std::string, configTarget> &targets );
326
327template int appConfigurator::get<long double>( long double &v,
328 const std::string &name,
329 size_t i,
330 std::unordered_map<std::string, configTarget> &targets );
331
332#ifdef HASQUAD
333template int appConfigurator::get<__float128>( __float128 &v,
334 const std::string &name,
335 size_t i,
336 std::unordered_map<std::string, configTarget> &targets );
337#endif
338
339template int appConfigurator::get<bool>( bool &v,
340 const std::string &name,
341 size_t i,
342 std::unordered_map<std::string, configTarget> &targets );
343
344template int appConfigurator::get<std::string>( std::string &v,
345 const std::string &name,
346 size_t i,
347 std::unordered_map<std::string, configTarget> &targets );
348
349//+++++++++++++++++++++++++++++++++++++
350
351template int appConfigurator::get<char>( char &v, const std::string &name, size_t i );
352
353template int appConfigurator::get<signed char>( signed char &v, const std::string &name, size_t i );
354
355template int appConfigurator::get<short>( short &v, const std::string &name, size_t i );
356
357template int appConfigurator::get<int>( int &v, const std::string &name, size_t i );
358
359template int appConfigurator::get<long>( long &v, const std::string &name, size_t i );
360
361template int appConfigurator::get<long long>( long long &v, const std::string &name, size_t i );
362
363template int appConfigurator::get<unsigned char>( unsigned char &v, const std::string &name, size_t i );
364
365template int appConfigurator::get<unsigned short>( unsigned short &v, const std::string &name, size_t i );
366
367template int appConfigurator::get<unsigned int>( unsigned int &v, const std::string &name, size_t i );
368
369template int appConfigurator::get<unsigned long>( unsigned long &v, const std::string &name, size_t i );
370
371template int appConfigurator::get<unsigned long long>( unsigned long long &v, const std::string &name, size_t i );
372
373template int appConfigurator::get<float>( float &v, const std::string &name, size_t i );
374
375template int appConfigurator::get<double>( double &v, const std::string &name, size_t i );
376
377template int appConfigurator::get<long double>( long double &v, const std::string &name, size_t i );
378
379#ifdef HASQUAD
380template int appConfigurator::get<__float128>( __float128 &v, const std::string &name, size_t i );
381#endif
382
383template int appConfigurator::get<bool>( bool &v, const std::string &name, size_t i );
384
385template int appConfigurator::get<std::string>( std::string &v, const std::string &name, size_t i );
386
387//+++++++++++++++++++++++++++++++++++++
388
389template int
390appConfigurator::get<char>( char &v, const std::string &name, std::unordered_map<std::string, configTarget> &targets );
391
392template int appConfigurator::get<signed char>( signed char &v,
393 const std::string &name,
394 std::unordered_map<std::string, configTarget> &targets );
395
396template int appConfigurator::get<short>( short &v,
397 const std::string &name,
398 std::unordered_map<std::string, configTarget> &targets );
399
400template int
401appConfigurator::get<int>( int &v, const std::string &name, std::unordered_map<std::string, configTarget> &targets );
402
403template int
404appConfigurator::get<long>( long &v, const std::string &name, std::unordered_map<std::string, configTarget> &targets );
405
406template int appConfigurator::get<long long>( long long &v,
407 const std::string &name,
408 std::unordered_map<std::string, configTarget> &targets );
409
410template int appConfigurator::get<unsigned char>( unsigned char &v,
411 const std::string &name,
412 std::unordered_map<std::string, configTarget> &targets );
413
414template int appConfigurator::get<unsigned short>( unsigned short &v,
415 const std::string &name,
416 std::unordered_map<std::string, configTarget> &targets );
417
418template int appConfigurator::get<unsigned int>( unsigned int &v,
419 const std::string &name,
420 std::unordered_map<std::string, configTarget> &targets );
421
422template int appConfigurator::get<unsigned long>( unsigned long &v,
423 const std::string &name,
424 std::unordered_map<std::string, configTarget> &targets );
425
426template int appConfigurator::get<unsigned long long>( unsigned long long &v,
427 const std::string &name,
428 std::unordered_map<std::string, configTarget> &targets );
429
430template int appConfigurator::get<float>( float &v,
431 const std::string &name,
432 std::unordered_map<std::string, configTarget> &targets );
433
434template int appConfigurator::get<double>( double &v,
435 const std::string &name,
436 std::unordered_map<std::string, configTarget> &targets );
437
438template int appConfigurator::get<long double>( long double &v,
439 const std::string &name,
440 std::unordered_map<std::string, configTarget> &targets );
441
442#ifdef HASQUAD
443template int appConfigurator::get<__float128>( __float128 &v,
444 const std::string &name,
445 std::unordered_map<std::string, configTarget> &targets );
446#endif
447
448template int
449appConfigurator::get<bool>( bool &v, const std::string &name, std::unordered_map<std::string, configTarget> &targets );
450
451template int appConfigurator::get<std::string>( std::string &v,
452 const std::string &name,
453 std::unordered_map<std::string, configTarget> &targets );
454
455//+++++++++++++++++++++++++++++++++++++
456
457template int appConfigurator::get<char>( char &v, const std::string &name );
458
459template int appConfigurator::get<signed char>( signed char &v, const std::string &name );
460
461template int appConfigurator::get<short>( short &v, const std::string &name );
462
463template int appConfigurator::get<int>( int &v, const std::string &name );
464
465template int appConfigurator::get<long>( long &v, const std::string &name );
466
467template int appConfigurator::get<long long>( long long &v, const std::string &name );
468
469template int appConfigurator::get<unsigned char>( unsigned char &v, const std::string &name );
470
471template int appConfigurator::get<unsigned short>( unsigned short &v, const std::string &name );
472
473template int appConfigurator::get<unsigned int>( unsigned int &v, const std::string &name );
474
475template int appConfigurator::get<unsigned long>( unsigned long &v, const std::string &name );
476
477template int appConfigurator::get<unsigned long long>( unsigned long long &v, const std::string &name );
478
479template int appConfigurator::get<float>( float &v, const std::string &name );
480
481template int appConfigurator::get<double>( double &v, const std::string &name );
482
483template int appConfigurator::get<long double>( long double &v, const std::string &name );
484
485#ifdef HASQUAD
486template int appConfigurator::get<__float128>( __float128 &v, const std::string &name );
487#endif
488
489template int appConfigurator::get<bool>( bool &v, const std::string &name );
490
491template int appConfigurator::get<std::string>( std::string &v, const std::string &name );
492
493//++++++++++++++++++++++++++++++++++++++++++++++
494
495template int appConfigurator::get<char>( std::vector<char> &v,
496 const std::string &name,
497 size_t i,
498 std::unordered_map<std::string, configTarget> &targets );
499
500template int appConfigurator::get<signed char>( std::vector<signed char> &v,
501 const std::string &name,
502 size_t i,
503 std::unordered_map<std::string, configTarget> &targets );
504
505template int appConfigurator::get<short>( std::vector<short> &v,
506 const std::string &name,
507 size_t i,
508 std::unordered_map<std::string, configTarget> &targets );
509
510template int appConfigurator::get<int>( std::vector<int> &v,
511 const std::string &name,
512 size_t i,
513 std::unordered_map<std::string, configTarget> &targets );
514
515template int appConfigurator::get<long>( std::vector<long> &v,
516 const std::string &name,
517 size_t i,
518 std::unordered_map<std::string, configTarget> &targets );
519
520template int appConfigurator::get<long long>( std::vector<long long> &v,
521 const std::string &name,
522 size_t i,
523 std::unordered_map<std::string, configTarget> &targets );
524
525template int appConfigurator::get<unsigned char>( std::vector<unsigned char> &v,
526 const std::string &name,
527 size_t i,
528 std::unordered_map<std::string, configTarget> &targets );
529
530template int appConfigurator::get<unsigned short>( std::vector<unsigned short> &v,
531 const std::string &name,
532 size_t i,
533 std::unordered_map<std::string, configTarget> &targets );
534
535template int appConfigurator::get<unsigned int>( std::vector<unsigned int> &v,
536 const std::string &name,
537 size_t i,
538 std::unordered_map<std::string, configTarget> &targets );
539
540template int appConfigurator::get<unsigned long>( std::vector<unsigned long> &v,
541 const std::string &name,
542 size_t i,
543 std::unordered_map<std::string, configTarget> &targets );
544
545template int appConfigurator::get<unsigned long long>( std::vector<unsigned long long> &v,
546 const std::string &name,
547 size_t i,
548 std::unordered_map<std::string, configTarget> &targets );
549
550template int appConfigurator::get<float>( std::vector<float> &v,
551 const std::string &name,
552 size_t i,
553 std::unordered_map<std::string, configTarget> &targets );
554
555template int appConfigurator::get<double>( std::vector<double> &v,
556 const std::string &name,
557 size_t i,
558 std::unordered_map<std::string, configTarget> &targets );
559
560template int appConfigurator::get<long double>( std::vector<long double> &v,
561 const std::string &name,
562 size_t i,
563 std::unordered_map<std::string, configTarget> &targets );
564
565#ifdef HASQUAD
566template int appConfigurator::get<__float128>( std::vector<__float128> &v,
567 const std::string &name,
568 size_t i,
569 std::unordered_map<std::string, configTarget> &targets );
570#endif
571
572template int appConfigurator::get<bool>( std::vector<bool> &v,
573 const std::string &name,
574 size_t i,
575 std::unordered_map<std::string, configTarget> &targets );
576
577template int appConfigurator::get<std::string>( std::vector<std::string> &v,
578 const std::string &name,
579 size_t i,
580 std::unordered_map<std::string, configTarget> &targets );
581
582//+++++++++++++++++++++++++++++++++++++
583
584template int appConfigurator::get<char>( std::vector<char> &v, const std::string &name, size_t i );
585
586template int appConfigurator::get<signed char>( std::vector<signed char> &v, const std::string &name, size_t i );
587
588template int appConfigurator::get<short>( std::vector<short> &v, const std::string &name, size_t i );
589
590template int appConfigurator::get<int>( std::vector<int> &v, const std::string &name, size_t i );
591
592template int appConfigurator::get<long>( std::vector<long> &v, const std::string &name, size_t i );
593
594template int appConfigurator::get<long long>( std::vector<long long> &v, const std::string &name, size_t i );
595
596template int appConfigurator::get<unsigned char>( std::vector<unsigned char> &v, const std::string &name, size_t i );
597
598template int appConfigurator::get<unsigned short>( std::vector<unsigned short> &v, const std::string &name, size_t i );
599
600template int appConfigurator::get<unsigned int>( std::vector<unsigned int> &v, const std::string &name, size_t i );
601
602template int appConfigurator::get<unsigned long>( std::vector<unsigned long> &v, const std::string &name, size_t i );
603
604template int
605appConfigurator::get<unsigned long long>( std::vector<unsigned long long> &v, const std::string &name, size_t i );
606
607template int appConfigurator::get<float>( std::vector<float> &v, const std::string &name, size_t i );
608
609template int appConfigurator::get<double>( std::vector<double> &v, const std::string &name, size_t i );
610
611template int appConfigurator::get<long double>( std::vector<long double> &v, const std::string &name, size_t i );
612
613#ifdef HASQUAD
614template int appConfigurator::get<__float128>( std::vector<__float128> &v, const std::string &name, size_t i );
615#endif
616
617template int appConfigurator::get<bool>( std::vector<bool> &v, const std::string &name, size_t i );
618
619template int appConfigurator::get<std::string>( std::vector<std::string> &v, const std::string &name, size_t i );
620
621//+++++++++++++++++++++++++++++++++++++++++++++++
622template int appConfigurator::get<char>( std::vector<char> &v,
623 const std::string &name,
624 std::unordered_map<std::string, configTarget> &targets );
625
626template int appConfigurator::get<signed char>( std::vector<signed char> &v,
627 const std::string &name,
628 std::unordered_map<std::string, configTarget> &targets );
629
630template int appConfigurator::get<short>( std::vector<short> &v,
631 const std::string &name,
632 std::unordered_map<std::string, configTarget> &targets );
633
634template int appConfigurator::get<int>( std::vector<int> &v,
635 const std::string &name,
636 std::unordered_map<std::string, configTarget> &targets );
637
638template int appConfigurator::get<long>( std::vector<long> &v,
639 const std::string &name,
640 std::unordered_map<std::string, configTarget> &targets );
641
642template int appConfigurator::get<long long>( std::vector<long long> &v,
643 const std::string &name,
644 std::unordered_map<std::string, configTarget> &targets );
645
646template int appConfigurator::get<unsigned char>( std::vector<unsigned char> &v,
647 const std::string &name,
648 std::unordered_map<std::string, configTarget> &targets );
649
650template int appConfigurator::get<unsigned short>( std::vector<unsigned short> &v,
651 const std::string &name,
652 std::unordered_map<std::string, configTarget> &targets );
653
654template int appConfigurator::get<unsigned int>( std::vector<unsigned int> &v,
655 const std::string &name,
656 std::unordered_map<std::string, configTarget> &targets );
657
658template int appConfigurator::get<unsigned long>( std::vector<unsigned long> &v,
659 const std::string &name,
660 std::unordered_map<std::string, configTarget> &targets );
661
662template int appConfigurator::get<unsigned long long>( std::vector<unsigned long long> &v,
663 const std::string &name,
664 std::unordered_map<std::string, configTarget> &targets );
665
666template int appConfigurator::get<float>( std::vector<float> &v,
667 const std::string &name,
668 std::unordered_map<std::string, configTarget> &targets );
669
670template int appConfigurator::get<double>( std::vector<double> &v,
671 const std::string &name,
672 std::unordered_map<std::string, configTarget> &targets );
673
674template int appConfigurator::get<long double>( std::vector<long double> &v,
675 const std::string &name,
676 std::unordered_map<std::string, configTarget> &targets );
677
678#ifdef HASQUAD
679template int appConfigurator::get<__float128>( std::vector<__float128> &v,
680 const std::string &name,
681 std::unordered_map<std::string, configTarget> &targets );
682#endif
683
684template int appConfigurator::get<bool>( std::vector<bool> &v,
685 const std::string &name,
686 std::unordered_map<std::string, configTarget> &targets );
687
688template int appConfigurator::get<std::string>( std::vector<std::string> &v,
689 const std::string &name,
690 std::unordered_map<std::string, configTarget> &targets );
691//+++++++++++++++++++++++++++++++++++++
692
693template int appConfigurator::get<char>( std::vector<char> &v, const std::string &name );
694
695template int appConfigurator::get<signed char>( std::vector<signed char> &v, const std::string &name );
696
697template int appConfigurator::get<short>( std::vector<short> &v, const std::string &name );
698
699template int appConfigurator::get<int>( std::vector<int> &v, const std::string &name );
700
701template int appConfigurator::get<long>( std::vector<long> &v, const std::string &name );
702
703template int appConfigurator::get<long long>( std::vector<long long> &v, const std::string &name );
704
705template int appConfigurator::get<unsigned char>( std::vector<unsigned char> &v, const std::string &name );
706
707template int appConfigurator::get<unsigned short>( std::vector<unsigned short> &v, const std::string &name );
708
709template int appConfigurator::get<unsigned int>( std::vector<unsigned int> &v, const std::string &name );
710
711template int appConfigurator::get<unsigned long>( std::vector<unsigned long> &v, const std::string &name );
712
713template int appConfigurator::get<unsigned long long>( std::vector<unsigned long long> &v, const std::string &name );
714
715template int appConfigurator::get<float>( std::vector<float> &v, const std::string &name );
716
717template int appConfigurator::get<double>( std::vector<double> &v, const std::string &name );
718
719template int appConfigurator::get<long double>( std::vector<long double> &v, const std::string &name );
720
721#ifdef HASQUAD
722template int appConfigurator::get<__float128>( std::vector<__float128> &v, const std::string &name );
723#endif
724
725template int appConfigurator::get<bool>( std::vector<bool> &v, const std::string &name );
726
727template int appConfigurator::get<std::string>( std::vector<std::string> &v, const std::string &name );
728
729//+++++++++++++++++++++++++++++++++++++++
730
731template int appConfigurator::operator()<char>( char &v, const std::string &name );
732
733template int appConfigurator::operator()<signed char>( signed char &v, const std::string &name );
734
735template int appConfigurator::operator()<short>( short &v, const std::string &name );
736
737template int appConfigurator::operator()<int>( int &v, const std::string &name );
738
739template int appConfigurator::operator()<long>( long &v, const std::string &name );
740
741template int appConfigurator::operator()<long long>( long long &v, const std::string &name );
742
743template int appConfigurator::operator()<unsigned char>( unsigned char &v, const std::string &name );
744
745template int appConfigurator::operator()<unsigned short>( unsigned short &v, const std::string &name );
746
747template int appConfigurator::operator()<unsigned int>( unsigned int &v, const std::string &name );
748
749template int appConfigurator::operator()<unsigned long>( unsigned long &v, const std::string &name );
750
751template int appConfigurator::operator()<unsigned long long>( unsigned long long &v, const std::string &name );
752
753template int appConfigurator::operator()<float>( float &v, const std::string &name );
754
755template int appConfigurator::operator()<double>( double &v, const std::string &name );
756
757template int appConfigurator::operator()<long double>( long double &v, const std::string &name );
758
759#ifdef HASQUAD
760template int appConfigurator::operator()<__float128>( __float128 &v, const std::string &name );
761#endif
762
763template int appConfigurator::operator()<bool>( bool &v, const std::string &name );
764
765template int appConfigurator::operator()<std::string>( std::string &v, const std::string &name );
766
767//++++++++++++++++++++++++++++++++++++++++++++++
768
769template int appConfigurator::configUnused<char>( char &v, const std::string &key );
770
771template int appConfigurator::configUnused<signed char>( signed char &v, const std::string &key );
772
773template int appConfigurator::configUnused<short>( short &v, const std::string &key );
774
775template int appConfigurator::configUnused<int>( int &v, const std::string &key );
776
777template int appConfigurator::configUnused<long>( long &v, const std::string &key );
778
779template int appConfigurator::configUnused<long long>( long long &v, const std::string &key );
780
781template int appConfigurator::configUnused<unsigned char>( unsigned char &v, const std::string &key );
782
783template int appConfigurator::configUnused<unsigned short>( unsigned short &v, const std::string &key );
784
785template int appConfigurator::configUnused<unsigned int>( unsigned int &v, const std::string &key );
786
787template int appConfigurator::configUnused<unsigned long>( unsigned long &v, const std::string &key );
788
789template int appConfigurator::configUnused<unsigned long long>( unsigned long long &v, const std::string &key );
790
791template int appConfigurator::configUnused<float>( float &v, const std::string &key );
792
793template int appConfigurator::configUnused<double>( double &v, const std::string &key );
794
795template int appConfigurator::configUnused<long double>( long double &v, const std::string &key );
796
797#ifdef HASQUAD
798template int appConfigurator::configUnused<__float128>( __float128 &v, const std::string &key );
799#endif
800
801template int appConfigurator::configUnused<bool>( bool &v, const std::string &key );
802
803template int appConfigurator::configUnused<std::string>( std::string &v, const std::string &key );
804
805//+++++++++++++++++++++++++++++++++++++++++++++++++++++
806
807template int appConfigurator::configUnused<char>( char &v, const std::string &section, const std::string &keyword );
808
809template int
810appConfigurator::configUnused<signed char>( signed char &v, const std::string &section, const std::string &keyword );
811
812template int appConfigurator::configUnused<short>( short &v, const std::string &section, const std::string &keyword );
813
814template int appConfigurator::configUnused<int>( int &v, const std::string &section, const std::string &keyword );
815
816template int appConfigurator::configUnused<long>( long &v, const std::string &section, const std::string &keyword );
817
818template int
819appConfigurator::configUnused<long long>( long long &v, const std::string &section, const std::string &keyword );
820
821template int appConfigurator::configUnused<unsigned char>( unsigned char &v,
822 const std::string &section,
823 const std::string &keyword );
824
825template int appConfigurator::configUnused<unsigned short>( unsigned short &v,
826 const std::string &section,
827 const std::string &keyword );
828
829template int
830appConfigurator::configUnused<unsigned int>( unsigned int &v, const std::string &section, const std::string &keyword );
831
832template int appConfigurator::configUnused<unsigned long>( unsigned long &v,
833 const std::string &section,
834 const std::string &keyword );
835
836template int appConfigurator::configUnused<unsigned long long>( unsigned long long &v,
837 const std::string &section,
838 const std::string &keyword );
839
840template int appConfigurator::configUnused<float>( float &v, const std::string &section, const std::string &keyword );
841
842template int appConfigurator::configUnused<double>( double &v, const std::string &section, const std::string &keyword );
843
844template int
845appConfigurator::configUnused<long double>( long double &v, const std::string &section, const std::string &keyword );
846
847#ifdef HASQUAD
848template int
849appConfigurator::configUnused<__float128>( __float128 &v, const std::string &section, const std::string &keyword );
850#endif
851
852template int appConfigurator::configUnused<bool>( bool &v, const std::string &section, const std::string &keyword );
853
854template int
855appConfigurator::configUnused<std::string>( std::string &v, const std::string &section, const std::string &keyword );
856
857//+++++++++++++++++++++++++++++++++++++
858
859int appConfigurator::unusedSections( std::vector<std::string> &sections )
860{
861 sections.clear();
862
863 // Wind through all the targets
864 for( auto it = m_unusedConfigs.begin(); it != m_unusedConfigs.end(); ++it )
865 {
866 std::string sect = it->second.section;
867
868 bool add = true;
869
870 // Check if this section is already in the vector -- is there a std::algorithms way to do this?
871 for( size_t i = 0; i < sections.size(); ++i )
872 {
873 if( sections[i] == sect )
874 {
875 add = false;
876 break;
877 }
878 }
879
880 // Add it if it wasn't found.
881 if( add )
882 sections.push_back( sect );
883 }
884
885 return 0;
886}
887
888int appConfigurator::isSetUnused( const std::string &name )
889{
890 return isSet( name, m_unusedConfigs );
891}
892
893void writeConfigFile( const std::string &fname,
894 const std::vector<std::string> &sections,
895 const std::vector<std::string> &keywords,
896 const std::vector<std::string> &values )
897{
898 std::ofstream fout;
899
900 fout.open( fname );
901
902 std::string lastSection;
903 for( size_t i = 0; i < sections.size(); ++i )
904 {
905 std::string currSection = sections[i];
906
907 if( currSection != lastSection && currSection != "" )
908 {
909 fout << "\n[" << currSection << "]\n";
910 }
911
912 if( keywords.size() >= i && values.size() >= i )
913 {
914 if( keywords[i] != "" )
915 {
916 fout << keywords[i] << "=" << values[i] << "\n";
917 }
918 }
919 lastSection = currSection;
920 }
921
922 fout.close();
923
924 return;
925}
926
927} // namespace app
928} // namespace mx
An application configuration manager.
void writeConfigFile(const std::string &fname, const std::vector< std::string > &sections, const std::vector< std::string > &keywords, const std::vector< std::string > &values)
A simple config file writing function, useful for testing.
@ filenotfound
The file was not found.
@ parseerr
A parsing error occurred.
@ allocerr
An error occurred during memory allocation.
error_t mxlib_error_report(const error_t &code, const std::string &expl, const std::source_location &loc=std::source_location::current())
Print a report to stderr given an mxlib error_t code and explanation and return the code.
Definition error.hpp:331
The mxlib c++ namespace.
Definition mxlib.hpp:37
std::unordered_map< std::string, configTarget > m_targets
The targets are stored in an unordered_map for fast access by key.
int readConfig(const std::string &fname, bool reportFileNotFound=true)
Read and parse a config/ini file, updating the targets.
void add(const configTarget &tgt)
Add a configTarget.
bool m_sources
Flag controlling whether or not to record config sources.
std::vector< std::string > nonOptions
Non-option arguments from the command line.
int verbosity(const std::string &name, std::unordered_map< std::string, configTarget > &targets)
Get the command line verbosity count for this option.
std::unordered_map< std::string, configTarget >::iterator targetIterator
Iterator for the targets unordered_map.
int isSetUnused(const std::string &name)
Check if a target has been set in the unused configuration.
bool isSet(const std::string &name, std::unordered_map< std::string, configTarget > &targets)
Check if a target has been set by the configuration.
void clear()
Clear the containers and free up the associated memory.
int unusedSections(std::vector< std::string > &sections)
Get the unique sections in the unused config targets.
std::list< configTarget > clOnlyTargets
Targets which are only for the command line are stored separately in a list.
int count(const std::string &name, std::unordered_map< std::string, configTarget > &targets)
Get the number of different values set for the specified config target.
void parseCommandLine(int argc, char **argv, const std::string &oneTarget="")
Parse the command line, updating the targets.
int nAdded
Running count of options added, used to track order.
std::unordered_map< std::string, configTarget > m_unusedConfigs
std::list< configTarget >::iterator clOnlyTargetIterator
Iterator for the clOnlyTargets list.
Command line options parser.
Definition clOptions.hpp:59
void parse(int argc, char **argv, std::vector< std::string > *nonOptions=0)
Parse the command line.
Definition clOptions.cpp:99
int numUnknown()
Get the number of unknown options found by the parser.
void add(const std::string &optName, const char *const shortOpt, const char *const longOpt, int argT)
Add a command line option target.
Definition clOptions.cpp:71
int count(const std::string &key)
Get the number of times the option was set on the command line.
unsigned int nOpts
The number of options added.
Definition clOptions.hpp:70
void getAll(std::vector< std::string > &args, const std::string &key)
Fill a vector of strings with the arguments supplied for key, last to first.
int unknown(std::vector< std::string > &unk)
Get a vector of the unknown options found by the parser.
bool optSet(const std::string &key)
Test whether this option was set.
A configuration target.
std::string keyword
The config file keyword, read in a "keyword=value" pair.
std::string section
The config file section name, can be empty "".
std::string name
The name of the target.
A wrapper for the ini functions.
Definition iniFile.hpp:47
size_t count(const std::string &section, const std::string &name)
Get the number of entries for the given section and name.
Definition iniFile.hpp:142
int erase(const std::string &section, const std::string &name)
Erase the entry for the given section and name.
Definition iniFile.hpp:154
nameMapT names
The map of section=name keys to values.
Definition iniFile.hpp:50
static int parseKey(std::string &section, std::string &name, const std::string &key)
Parse a key into its section and name consituents.
Definition iniFile.hpp:70
int parse(const std::string &fname)
Calls the inih parse function with this->handler.
Definition iniFile.hpp:95