ALMaSS Rabbit ODdox  1.00
The rabbit model description following ODdox protocol
configurator.cpp
Go to the documentation of this file.
1 /*
2 *******************************************************************************************************
3 Copyright (c) 2011, Christopher John Topping, University of Aarhus
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided
7 that the following conditions are met:
8 
9 Redistributions of source code must retain the above copyright notice, this list of conditions and the
10 following disclaimer.
11 Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
12 the following disclaimer in the documentation and/or other materials provided with the distribution.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
15 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
17 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
19 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 ********************************************************************************************************
23 */
24 
25 #define _CRT_SECURE_NO_DEPRECATE
26 
27 #include <stdio.h>
28 #include <iostream>
29 #include <fstream>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 #include "../BatchALMaSS/ALMaSS_Setup.h"
34 #include "configurator.h"
35 #include "maperrormsg.h"
36 
37 #if !(defined __UNIX) & !(defined __BORLANDC__)
38 #include <crtdbg.h>
39 #define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
40 #ifdef _DEBUG
41 #define new DEBUG_NEW
42 #endif
43 #endif
44 
45 using namespace std;
46 
47 extern void FloatToDouble(double&, float);
48 
49 class Configurator *g_cfg = NULL;
50 
51 static CfgBool l_cfg_public_warn_on_set("CFG_PUBLIC_WARN_ON_SET",
52  CFG_CUSTOM, true );
53 static CfgBool l_cfg_public_exit_on_set("CFG_PUBLIC_EXIT_ON_SET",
54  CFG_CUSTOM, true );
55 
56 
57 static const char* CfgSecureStrings[] = {
58  "CFG_CUSTOM",
59  "CFG_PUBLIC",
60  "CFG_PRIVATE"
61 };
62 
63 
64 static const char* CfgTypeStrings[] = {
65  "*none*",
66  "int",
67  "double",
68  "bool",
69  "string"
70 };
71 
72 
73 CfgBase::CfgBase( const char* a_key, CfgSecureLevel a_level )
74 {
75  if ( NULL == g_cfg ) {
76  g_cfg = new Configurator;
77  }
78 
79  m_key = a_key;
80  m_level = a_level;
81  g_cfg->Register( this, a_key );
82 }
83 
84 
85 
87 {
88  ;
89 }
90 
91 
92 
93 CfgInt::CfgInt( const char* a_key,
94  CfgSecureLevel a_level,
95  int a_defval )
96  :CfgBase( a_key, a_level )
97 {
98  m_int = a_defval;
99 }
100 
101 
102 
103 CfgFloat::CfgFloat( const char* a_key,
104  CfgSecureLevel a_level,
105  double a_defval )
106  :CfgBase( a_key, a_level )
107 {
108  m_float = a_defval;
109 }
110 
111 
112 
113 CfgBool::CfgBool( const char* a_key,
114  CfgSecureLevel a_level,
115  bool a_defval )
116  :CfgBase( a_key, a_level )
117 {
118  m_bool = a_defval;
119 }
120 
121 
122 
123 CfgStr::CfgStr( const char* a_key,
124  CfgSecureLevel a_level,
125  const char* a_defval )
126  :CfgBase( a_key, a_level )
127 {
128  m_string = a_defval;
129 }
130 
131 
132 
134 {
135  m_lineno = 0;
136 }
137 
138 
139 
141 {
142  ;
143 }
144 
145 
146 
147 bool Configurator::Register( CfgBase* a_cfgval, const char* a_key )
148 {
149  string l_key = a_key;
150 
151  if ( CfgI.find( l_key ) != CfgI.end() ) {
152  // Couldn't register, already exists.
153  return false;
154  }
155 
156  unsigned int i = (int) CfgVals.size();
157  CfgI[ l_key ] = i;
158  CfgVals.resize( i+1 );
159  CfgVals[ i ] = a_cfgval;
160 
161  return true;
162 }
163 
164 
165 
166 bool Configurator::ReadSymbols( const char *a_cfgfile ) {
167  ifstream cf_file;
168  char cfgline[ CFG_MAX_LINE_LENGTH ];
169  cf_file.open(a_cfgfile,fstream::in);
170  if ( !cf_file.is_open() ) {
171  g_msg->Warn( WARN_FILE, "Configurator::ReadSymbols() Unable to open file for reading: ", a_cfgfile );
172  exit(1);
173  }
174  while ( !cf_file.eof()) {
175  for (unsigned i=0; i< CFG_MAX_LINE_LENGTH; i++) cfgline[i]=' '; // Done to get rid of the rubbish that otherwise messes up the parse
176  cf_file.getline(cfgline,CFG_MAX_LINE_LENGTH);
177  ParseCfgLine( cfgline );
178  m_lineno++;
179  }
180  cf_file.close();
181  return true;
182 }
183 
184 
185 
186 // Caution, modifies original line, and returns a pointer to a
187 // substring of a_line.
188 char* Configurator::ExtractString( char* a_line )
189 {
190  char lineno[ 20 ];
191 
192  // scan for the first double quote or end of line.
193  while ( *a_line != '"' && *a_line != '\0' ) {
194  a_line++;
195  }
196 
197  // The first char in the string had better contain a '"':
198  if ( *a_line != '"' ) {
199  sprintf( lineno, "%d", m_lineno );
200  g_msg->Warn( WARN_FILE, "Configurator::ExtractString()\n"
201  " String not enclosed in double quotes at "
202  "config line ", lineno );
203  exit(1);
204  }
205 
206  char* endline = ++a_line;
207  bool escaped = false, found = false;
208 
209  while ( *endline != '\0' ) {
210  if ( *endline == '\\' ) {
211  escaped = true;
212  endline++;
213 
214  if ( *endline == '"' &&
215  LastDoubleQuote( endline )) {
216  escaped = false;
217  } else {
218  continue;
219  }
220  }
221  if ( *endline == '"' && !escaped ) {
222  // Found end of string, terminate properly and break the loop.
223  *endline++ = '\0';
224  found = true;
225  break;
226  }
227  escaped = false;
228  endline++;
229  }
230 
231  if ( !found ) {
232  sprintf( lineno, "%d", m_lineno );
233  g_msg->Warn( WARN_FILE, "Configurator::ExtractString() "
234  "No ending double quote after string at "
235  "config line ", lineno );
236  exit(1);
237  }
238 
239 
240  // Check for comment if remainder of line isn't empty.
241  if ( sscanf( endline, "%*s" ) == 1 ) {
242  // Non-empty comment line.
243  if ( sscanf( endline, "%*[#]" ) != 1 ) {
244  // But not initiated by '#'.
245  sprintf( lineno, "%d", m_lineno );
246  g_msg->Warn( WARN_FILE, "Configurator::ExtractString() "
247  "Illegal comment at "
248  "config line ", lineno );
249  exit(1);
250  }
251  }
252 
253  return a_line;
254 }
255 
256 
257 bool Configurator::LastDoubleQuote( char* a_rest_of_line )
258 {
259  a_rest_of_line++;
260 
261  while ( *a_rest_of_line != '\0' && *a_rest_of_line != '#' ) {
262  if ( *a_rest_of_line == '"' ) {
263  return false;
264  }
265  a_rest_of_line++;
266  }
267  return true;
268 }
269 
270 
271 
272 void Configurator::ParseCfgLine( char* a_line )
273 {
274  char l_id [ CFG_MAX_LINE_LENGTH ];
275  char l_type[ CFG_MAX_LINE_LENGTH ];
276  char l_sep [ CFG_MAX_LINE_LENGTH ];
277  char l_val [ CFG_MAX_LINE_LENGTH ];
278  char l_comm[ CFG_MAX_LINE_LENGTH ];
279  char lineno[20];
280 
281  if ( sscanf( a_line, "%[#]", l_id ) == 1 ) {
282  // Comment line.
283  return;
284  }
285 
286  if ( sscanf( a_line, "%s", l_id) == EOF ) {
287  // Empty line consisting only of white spaces.
288  return;
289  }
290 
291  //int l_conv = sscanf( a_line, "%[A-Z_] (%[a-z]) %s", l_id, sizeof(l_id),l_type,sizeof(l_type), l_sep,sizeof(l_sep) );
292 int l_conv = sscanf( a_line, "%[A-Z_] (%[a-z]) %s", l_id, l_type, l_sep );
293 
294  if ( l_conv < 3 ) {
295  // Syntax terror.
296  sprintf( lineno, "%d", m_lineno );
297  g_msg->Warn( WARN_FILE, "Configurator::ParseCfgLine() "
298  "Syntax error at config line ",
299  lineno );
300  exit(1);
301  }
302 
303  if ( strcmp( l_sep, "=" ) != 0 ) {
304  // Missing '=' assignment separator.
305  sprintf( lineno, "%d", m_lineno );
306  g_msg->Warn( WARN_FILE, "Configurator::ParseCfgLine() "
307  "Missing '=' assignment operator at config line ",
308  lineno );
309  exit(1);
310  }
311 
312  if ( CfgI.find( l_id ) == CfgI.end() ) {
313  // Key doesn't exists among the predefined, global configuration
314  // variables. Ignore quietly.
315  return;
316  }
317 
318  if ( strlen( l_type ) == 6 &&
319  strncmp( l_type, "string", 6 ) == 0 ) {
320  // We are not yet ready to do the assignment.
321  // If we really have a string enclosed in non-escaped
322  // double quotes at the end of the line, then we need to
323  // extract it first from our input.
324  SetCfgStr( l_id, ExtractString( a_line ));
325  return;
326  }
327 
328  // Not a string, so extract data value and possible comment.
329  l_conv = sscanf( a_line, "%*[A-Z_] (%*[a-z]) %*s %s %s",
330  l_val, l_comm );
331 
332  if ( l_conv == 2 && l_comm[0] != '#' ) {
333  // Illegal comment at end of line.
334  sprintf( lineno, "%d", m_lineno );
335  g_msg->Warn( WARN_FILE, "Configurator::ParseCfgLine() "
336  "Syntax error at end of config line ",
337  lineno );
338  exit(1);
339  }
340 
341  if ( strlen( l_type ) == 5 &&
342  strncmp( l_type, "float", 5 ) == 0 ) {
343  SetCfgFloat( l_id, l_val );
344  return;
345  }
346 
347  if ( strlen( l_type ) == 4 &&
348  strncmp( l_type, "bool", 4 ) == 0 ) {
349  SetCfgBool( l_id, l_val );
350  return;
351  }
352 
353  if ( strlen( l_type ) == 3 &&
354  strncmp( l_type, "int", 3 ) == 0 ) {
355  SetCfgInt( l_id, l_val );
356  return;
357  }
358 
359  sprintf( lineno, "%d", m_lineno );
360  g_msg->Warn( WARN_FILE, "Configurator::ParseCfgLine() "
361  "Unknown type specifier at config line ",
362  lineno );
363  exit(1);
364 }
365 
366 
367 
368 void Configurator::ShowIdType( unsigned int a_i )
369 {
371  "Type for identifier ",
372  CfgVals[ a_i ]->getkey().c_str() );
373  g_msg->WarnAddInfo( WARN_FILE, " is (",
374  CfgTypeStrings[ CfgVals[ a_i ]->gettype() ] );
375  g_msg->WarnAddInfo( WARN_FILE, ")\n", "" );
376 }
377 
378 
379 
380 bool Configurator::SetCfgGatekeeper( const char* a_method,
381  const char* /* a_key */,
382  CfgSecureLevel a_level )
383 {
384  if ( a_level == CFG_PRIVATE ) {
385  // Attempting to set private config variable. Ignore quietly.
386  return true;
387  }
388 
389  if ( a_level == CFG_PUBLIC &&
391  // Attempting to set public config variable. Warn and
392  // possibly exit if this is configured.
393  char lineno[20];
394  sprintf( lineno, "%d", m_lineno );
395  g_msg->Warn( WARN_FILE, a_method, lineno );
396 
398  exit(1);
399  }
400  return true;
401  }
402  return false;
403 }
404 
405 
406 
407 void Configurator::SetCfgInt( char* a_key, char* a_val )
408 {
409  int l_val;
410  char lineno[20];
411  string l_key = a_key;
412 
413  if ( sscanf( a_val, "%d", &l_val ) != 1 ) {
414  sprintf( lineno, "%d", m_lineno );
415  g_msg->Warn( WARN_FILE, "Configurator::SetCfgInt() "
416  "Not an integer data value at config line",
417  lineno );
418  exit(1);
419  }
420 
421  // Check access security.
422  unsigned int i = CfgI[ l_key ];
423  if ( SetCfgGatekeeper( "Configurator::SetCfgInt() "
424  "Attempting to set public config variable in line",
425  a_key,
426  CfgVals[ i ]->getlevel()
427  )) {
428  return;
429  }
430 
431  if ( CfgVals[ i ]->gettype() != CFG_INT ) {
432  sprintf( lineno, "%d", m_lineno );
433  g_msg->Warn( WARN_FILE, "Configurator::SetCfgInt() "
434  "Non-integer identifier specified at config line",
435  lineno );
436  ShowIdType( i );
437  exit(1);
438  }
439 
440  dynamic_cast<CfgInt*>(CfgVals[ i ])->set( l_val );
441 }
442 
443 
444 void Configurator::SetCfgBool( char* a_key, char* a_val )
445 {
446  char lineno[20];
447  string l_key = a_key;
448  bool l_val = false;
449 
450  if ( strcmp ( a_val, "false" ) == 0 ) {
451  ; // l_val defaults to false.
452  } else if ( strcmp ( a_val, "true" ) == 0 ) {
453  l_val = true;
454  } else {
455  sprintf( lineno, "%d", m_lineno );
456  g_msg->Warn( WARN_FILE, "Configurator::SetCfgBool() "
457  "Not a boolean data value at config line",
458  lineno );
459  exit(1);
460  }
461 
462  // Check access security.
463  unsigned int i = CfgI[ l_key ];
464  if ( SetCfgGatekeeper( "Configurator::SetCfgBool() "
465  "Attempting to set public config variable in line",
466  a_key,
467  CfgVals[ i ]->getlevel()
468  )) {
469  return;
470  }
471 
472  if ( CfgVals[ i ]->gettype() != CFG_BOOL ) {
473  sprintf( lineno, "%d", m_lineno );
474  g_msg->Warn( WARN_FILE, "Configurator::SetCfgBool() "
475  "Non-boolean identifier specified at config line",
476  lineno );
477  ShowIdType( i );
478  exit(1);
479  }
480 
481  dynamic_cast<CfgBool*>(CfgVals[ i ])->set( l_val );
482 }
483 
484 
485 
486 void Configurator::SetCfgFloat( char* a_key, char* a_val )
487 {
488  double l_val;
489  float f;
490  char lineno[20];
491  string l_key = a_key;
492 
493  if ( sscanf( a_val, "%f", &f) != 1 ) {
494  sprintf( lineno, "%d", m_lineno );
495  g_msg->Warn( WARN_FILE, "Configurator::SetCfgFloat() "
496  "Not a floating point data value at config line",
497  lineno );
498  exit(1);
499  }
500  FloatToDouble(l_val,f);
501 
502  // Check access security.
503  unsigned int i = CfgI[ l_key ];
504  if ( SetCfgGatekeeper( "Configurator::SetCfgFloat() "
505  "Attempting to set public config variable in line",
506  a_key,
507  CfgVals[ i ]->getlevel()
508  )) {
509  return;
510  }
511 
512  if ( CfgVals[ i ]->gettype() != CFG_FLOAT ) {
513 sprintf( lineno, "%d", m_lineno );
514  g_msg->Warn( WARN_FILE, "Configurator::SetCfgFloat() "
515  "Non-floating point identifier specified at config line",
516  lineno );
517  ShowIdType( i );
518  exit(1);
519  }
520 
521  dynamic_cast<CfgFloat*>(CfgVals[ i ])->set( l_val );
522 }
523 
524 
525 
526 void Configurator::SetCfgStr( char* a_key, char* a_val )
527 {
528  char lineno[20];
529  string l_key = a_key;
530 
531  // Check access security.
532  unsigned int i = CfgI[ l_key ];
533  if ( SetCfgGatekeeper( "Configurator::SetCfgStr() "
534  "Attempting to set public config variable in line",
535  a_key,
536  CfgVals[ i ]->getlevel()
537  )) {
538  return;
539  }
540 
541  if ( CfgVals[ i ]->gettype() != CFG_STRING ) {
542  sprintf( lineno, "%d", m_lineno );
543  g_msg->Warn( WARN_FILE, "Configurator::SetCfgStr() "
544  "Non-string identifier specified at config line",
545  lineno );
546  ShowIdType( i );
547  exit(1);
548  }
549 
550  dynamic_cast<CfgStr*>(CfgVals[ i ])->set( a_val );
551 }
552 
553 
554 
555 void Configurator::DumpPublicSymbols( const char *a_dumpfile,
556  CfgSecureLevel a_level )
557 {
558  if ( a_level > CFG_PUBLIC ) {
559  a_level = CFG_PUBLIC;
560  }
561  DumpSymbols( a_dumpfile, a_level );
562 }
563 
564 
565 
566 void Configurator::DumpAllSymbolsAndExit( const char *a_dumpfile )
567 {
568  DumpSymbols( a_dumpfile, CFG_PRIVATE );
569  exit(1);
570 }
571 
572 
573 void Configurator::DumpSymbols( const char *a_dumpfile,
574  CfgSecureLevel a_level )
575 {
576  FILE *l_dumpfile;
577  char l_oprefix[ CFG_MAX_LINE_LENGTH ] = {""};
578  char l_nprefix[ CFG_MAX_LINE_LENGTH ];
579  const char* l_id;
580  l_dumpfile=fopen( a_dumpfile, "w" );
581  if (!l_dumpfile) {
582  g_msg->Warn( WARN_FILE, "Configurator::DumpSymbols() "
583  "Unable to open file for writing:",
584  a_dumpfile );
585  exit(1);
586  }
587 
588  typedef map<string,unsigned int>::const_iterator MI;
589 
590  for ( MI ii = CfgI.begin(); ii != CfgI.end(); ii++ ) {
591  unsigned int i = ii->second;
592 
593  // Skip 'secret' variables.
594  if ( CfgVals[ i ]->getlevel() > a_level ) {
595  continue;
596  }
597 
598  // Weird hack to separate different groups of
599  // configuration names.
600  string rubbish=CfgVals[ i ]->getkey();
601  l_id=rubbish.c_str();
602  //l_id = CfgVals[ i ]->getkey().c_str();
603  sscanf( l_id, "%[A-Z]", l_nprefix );
604  if ( strcmp( l_oprefix, l_nprefix ) != 0 ) {
605  fprintf( l_dumpfile, "\n" );
606  strcpy( l_oprefix, l_nprefix );
607  }
608 
609  fprintf( l_dumpfile, "%s (%s) = ",
610  l_id,
611  CfgTypeStrings[ CfgVals[ i ]->gettype() ]
612  );
613 
614  switch( CfgVals[ i ]->gettype() ) {
615  case CFG_INT:
616  {
617  CfgInt* l_p = dynamic_cast<CfgInt*>(CfgVals[ i ]);
618  fprintf( l_dumpfile, "%d", l_p->value() );
619  break;
620  }
621  case CFG_FLOAT:
622  {
623  CfgFloat* l_p = dynamic_cast<CfgFloat*>(CfgVals[ i ]);
624  fprintf( l_dumpfile, "%f", l_p->value() );
625  break;
626  }
627  case CFG_BOOL:
628  {
629  CfgBool* l_p = dynamic_cast<CfgBool*>(CfgVals[ i ]);
630  if ( l_p->value() ) {
631  fprintf( l_dumpfile, "true" );
632  } else {
633  fprintf( l_dumpfile, "false" );
634  }
635  break;
636  }
637  case CFG_STRING:
638  {
639  CfgStr* l_p = dynamic_cast<CfgStr*>(CfgVals[ i ]);
640  fprintf( l_dumpfile, "\"%s\"", l_p->value() );
641  break;
642  }
643  default:
644  {
645  char l_errno[20];
646  sprintf( l_errno, "%d", CfgVals[ i ]->gettype() );
647  g_msg->Warn( WARN_FILE, "Configurator::DumpSymbols() "
648  "Unknown symbol type read:",
649  l_errno );
650  exit(1);
651  }
652  }
653  fprintf( l_dumpfile, " # %s\n",
655  );
656  }
657 
658 }
void SetCfgInt(char *a_key, char *a_val)
void SetCfgFloat(char *a_key, char *a_val)
static const char * CfgTypeStrings[]
CfgSecureLevel getlevel(void)
Definition: configurator.h:79
string m_string
Definition: configurator.h:134
Integer configurator entry class.
Definition: configurator.h:85
bool m_bool
Definition: configurator.h:118
bool LastDoubleQuote(char *a_rest_of_line)
double value(void)
Definition: configurator.h:107
bool ReadSymbols(const char *a_cfgfile)
A class to provide standard parameter entry facilities.
Definition: configurator.h:148
static const char * CfgSecureStrings[]
void WarnAddInfo(MapErrorState a_level, std::string a_add1, std::string a_add2)
void DumpSymbols(const char *a_dumpfile, CfgSecureLevel a_level)
void SetCfgStr(char *a_key, char *a_val)
void DumpAllSymbolsAndExit(const char *a_dumpfile)
const char * value(void)
Definition: configurator.h:139
int m_int
Definition: configurator.h:87
unsigned int m_lineno
Definition: configurator.h:154
class MapErrorMsg * g_msg
Definition: maperrormsg.cpp:38
static CfgBool l_cfg_public_warn_on_set("CFG_PUBLIC_WARN_ON_SET", CFG_CUSTOM, true)
bool value(void)
Definition: configurator.h:123
void ParseCfgLine(char *a_line)
virtual CfgType gettype(void)
Definition: configurator.h:141
CfgBool(const char *a_key, CfgSecureLevel a_level, bool a_defval)
CfgBase(const char *a_key, CfgSecureLevel a_level)
class Configurator * g_cfg
CfgSecureLevel
Definition: configurator.h:59
bool SetCfgGatekeeper(const char *a_method, const char *a_key, CfgSecureLevel a_level)
vector< CfgBase * > CfgVals
Definition: configurator.h:151
CfgInt(const char *a_key, CfgSecureLevel a_level, int a_defval)
String configurator entry class.
Definition: configurator.h:132
Bool configurator entry class.
Definition: configurator.h:116
#define CFG_MAX_LINE_LENGTH
Definition: configurator.h:46
double m_float
Definition: configurator.h:102
Base class for a configurator entry.
Definition: configurator.h:69
const string getkey(void)
Definition: configurator.h:77
static CfgBool l_cfg_public_exit_on_set("CFG_PUBLIC_EXIT_ON_SET", CFG_CUSTOM, true)
int value(void)
Definition: configurator.h:92
void Warn(MapErrorState a_level, std::string a_msg1, std::string a_msg2)
Definition: maperrormsg.cpp:56
void SetCfgBool(char *a_key, char *a_val)
virtual ~CfgBase(void)
void FloatToDouble(double &, float)
char * ExtractString(char *a_line)
CfgFloat(const char *a_key, CfgSecureLevel a_level, double a_defval)
Double configurator entry class.
Definition: configurator.h:100
void DumpPublicSymbols(const char *a_dumpfile, CfgSecureLevel a_level)
map< string, unsigned int > CfgI
Definition: configurator.h:150
void ShowIdType(unsigned int a_i)
CfgStr(const char *a_key, CfgSecureLevel a_level, const char *a_defval)
bool Register(CfgBase *a_cfgval, const char *a_key)