root/library/bdm/base/libconfig_mex.cpp @ 952

Revision 789, 109.6 kB (checked in by mido, 14 years ago)

libconfig_mex.cpp and libconfig_mex.h added (but that is all is done at the moment)
the documentation of root::to_setting(), root::from_setting() and root::validate() was extended

Line 
1/* ----------------------------------------------------------------------------
2
3        THE FILE IS UNDER THE CONSTRUCTION!
4
5   This file is a mex clone of libconfigcpp.cc originally found
6   in the libconfig library which was desgigned by Mark A Lindner.
7   
8   ----------------------------------------------------------------------------
9*/
10
11
12#include "libconfig_mex.h"
13
14#ifdef _MSC_VER
15#pragma warning (disable: 4996)
16#endif
17
18//#include "wincompat.h"
19
20#include <cstring>
21#include <cstdlib>
22#include <sstream>
23
24namespace libconfig {
25
26        /*
27// ---------------------------------------------------------------------------
28
29ParseException::ParseException(const char *file, int line, const char *error)
30  : _file(strdup(file)), _line(line), _error(error)
31{
32}
33
34// ---------------------------------------------------------------------------
35
36ParseException::~ParseException() throw()
37{
38  free((void *)_file);
39}
40
41// ---------------------------------------------------------------------------
42
43const char *ParseException::what() const throw()
44{
45  return("ParseException");
46}
47
48// ---------------------------------------------------------------------------
49
50static int __toTypeCode(Setting::Type type)
51{
52  int typecode;
53
54  switch(type)
55  {
56    case Setting::TypeGroup:
57      typecode = CONFIG_TYPE_GROUP;
58      break;
59
60    case Setting::TypeInt:
61      typecode = CONFIG_TYPE_INT;
62      break;
63
64    case Setting::TypeInt64:
65      typecode = CONFIG_TYPE_INT64;
66      break;
67
68    case Setting::TypeFloat:
69      typecode = CONFIG_TYPE_FLOAT;
70      break;
71
72    case Setting::TypeString:
73      typecode = CONFIG_TYPE_STRING;
74      break;
75
76    case Setting::TypeBoolean:
77      typecode = CONFIG_TYPE_BOOL;
78      break;
79
80    case Setting::TypeArray:
81      typecode = CONFIG_TYPE_ARRAY;
82      break;
83
84    case Setting::TypeList:
85      typecode = CONFIG_TYPE_LIST;
86      break;
87
88    default:
89      typecode = CONFIG_TYPE_NONE;
90  }
91
92  return(typecode);
93}
94
95// ---------------------------------------------------------------------------
96
97static void __constructPath(const Setting &setting,
98                            std::stringstream &path)
99{
100  // head recursion to print path from root to target
101
102  if(! setting.isRoot())
103  {
104    __constructPath(setting.getParent(), path);
105    if(path.tellp() > 0)
106      path << '.';
107
108    const char *name = setting.getName();
109    if(name)
110      path << name;
111    else
112      path << '[' << setting.getIndex() << ']';
113  }
114}
115
116// ---------------------------------------------------------------------------
117
118SettingException::SettingException(const Setting &setting)
119{
120  std::stringstream sstr;
121  __constructPath(setting, sstr);
122
123  _path = ::strdup(sstr.str().c_str());
124}
125
126// ---------------------------------------------------------------------------
127
128SettingException::SettingException(const Setting &setting, int idx)
129{
130  std::stringstream sstr;
131  __constructPath(setting, sstr);
132  sstr << ".[" << idx << "]";
133
134  _path = ::strdup(sstr.str().c_str());
135}
136
137// ---------------------------------------------------------------------------
138
139SettingException::SettingException(const Setting &setting, const char *name)
140{
141  std::stringstream sstr;
142  __constructPath(setting, sstr);
143  sstr << '.' << name;
144
145  _path = ::strdup(sstr.str().c_str());
146}
147
148// ---------------------------------------------------------------------------
149
150SettingException::SettingException(const char *path)
151{
152  _path = ::strdup(path);
153}
154
155// ---------------------------------------------------------------------------
156
157const char *SettingException::getPath() const
158{
159  return(_path);
160}
161
162// ---------------------------------------------------------------------------
163
164SettingException::SettingException(const SettingException &other)
165{
166  _path = ::strdup(other._path);
167}
168
169// ---------------------------------------------------------------------------
170
171SettingException &SettingException::operator=(const SettingException &other)
172{
173  ::free(_path);
174  _path = ::strdup(other._path);
175
176  return(*this);
177}
178
179// ---------------------------------------------------------------------------
180
181const char *SettingException::what() const throw()
182{
183  return("SettingException");
184}
185
186// ---------------------------------------------------------------------------
187
188SettingException::~SettingException() throw()
189{
190  ::free(_path);
191}
192
193// ---------------------------------------------------------------------------
194
195SettingTypeException::SettingTypeException(const Setting &setting)
196  : SettingException(setting)
197{
198}
199
200// ---------------------------------------------------------------------------
201
202SettingTypeException::SettingTypeException(const Setting &setting, int idx)
203  : SettingException(setting, idx)
204{
205}
206
207// ---------------------------------------------------------------------------
208
209SettingTypeException::SettingTypeException(const Setting &setting,
210                                           const char *name)
211  : SettingException(setting, name)
212{
213}
214
215// ---------------------------------------------------------------------------
216
217const char *SettingTypeException::what() const throw()
218{
219  return("SettingTypeException");
220}
221
222// ---------------------------------------------------------------------------
223
224SettingNotFoundException::SettingNotFoundException(const Setting &setting,
225                                                   int idx)
226  : SettingException(setting, idx)
227{
228}
229
230// ---------------------------------------------------------------------------
231
232SettingNotFoundException::SettingNotFoundException(const Setting &setting,
233                                                   const char *name)
234  : SettingException(setting, name)
235{
236}
237
238// ---------------------------------------------------------------------------
239
240SettingNotFoundException::SettingNotFoundException(const char *path)
241  : SettingException(path)
242{
243}
244
245// ---------------------------------------------------------------------------
246
247const char *SettingNotFoundException::what() const throw()
248{
249  return("SettingNotFoundException");
250}
251
252// ---------------------------------------------------------------------------
253
254SettingNameException::SettingNameException(const Setting &setting,
255                                           const char *name)
256  : SettingException(setting, name)
257{
258}
259
260// ---------------------------------------------------------------------------
261
262const char *SettingNameException::what() const throw()
263{
264  return("SettingNameException");
265}
266
267// ---------------------------------------------------------------------------
268
269const char *FileIOException::what() const throw()
270{
271  return("FileIOException");
272}
273
274// ---------------------------------------------------------------------------
275
276void Config::ConfigDestructor(void *arg)
277{
278  delete reinterpret_cast<Setting *>(arg);
279}
280
281// ---------------------------------------------------------------------------
282
283Config::Config()
284{
285  _config = new config_t;
286  config_init(_config);
287  config_set_destructor(_config, ConfigDestructor);
288}
289
290// ---------------------------------------------------------------------------
291
292Config::~Config()
293{
294  config_destroy(_config);
295  delete _config;
296}
297
298// ---------------------------------------------------------------------------
299
300void Config::setAutoConvert(bool flag)
301{
302  config_set_auto_convert(_config, (flag ? CONFIG_TRUE : CONFIG_FALSE));
303}
304
305// ---------------------------------------------------------------------------
306
307bool Config::getAutoConvert() const
308{
309  return(config_get_auto_convert(_config) != CONFIG_FALSE);
310}
311
312// ---------------------------------------------------------------------------
313
314void Config::setTabWidth(unsigned short width) throw()
315{
316  config_set_tab_width(_config, width);
317}
318
319// ---------------------------------------------------------------------------
320
321unsigned short Config::getTabWidth() const throw()
322{
323  return(config_get_tab_width(_config));
324}
325
326// ---------------------------------------------------------------------------
327
328void Config::handleError() const
329{
330  switch(config_error_type(_config))
331  {
332    case CONFIG_ERR_NONE:
333      break;
334   
335    case CONFIG_ERR_PARSE:
336      throw ParseException(config_error_file(_config),
337                           config_error_line(_config),
338                           config_error_text(_config));
339      break;
340
341    case CONFIG_ERR_FILE_IO:
342    default:
343      throw FileIOException();
344  }
345}
346
347// ---------------------------------------------------------------------------
348
349void Config::read(FILE *stream) throw(ParseException)
350{
351  if(! config_read(_config, stream))
352    handleError();
353}
354
355// ---------------------------------------------------------------------------
356
357void Config::readString(const char *str) throw(ParseException)
358{
359  if(! config_read_string(_config, str))
360    handleError();
361}
362
363// ---------------------------------------------------------------------------
364
365void Config::write(FILE *stream) const
366{
367  config_write(_config, stream);
368}
369
370// ---------------------------------------------------------------------------
371
372void Config::readFile(const char *filename) throw(FileIOException,
373                                                  ParseException)
374{
375  if(! config_read_file(_config, filename))
376    handleError();
377}
378
379// ---------------------------------------------------------------------------
380
381void Config::writeFile(const char *filename) throw(FileIOException)
382{
383  if(! config_write_file(_config, filename))
384    handleError();
385}
386
387// ---------------------------------------------------------------------------
388
389Setting & Config::lookup(const char *path) const
390  throw(SettingNotFoundException)
391{
392  config_setting_t *s = config_lookup(_config, path);
393  if(! s)
394    throw SettingNotFoundException(path);
395
396  return(Setting::wrapSetting(s));
397}
398
399// ---------------------------------------------------------------------------
400
401bool Config::exists(const char *path) const throw()
402{
403  config_setting_t *s = config_lookup(_config, path);
404
405  return(s != NULL);
406}
407
408// ---------------------------------------------------------------------------
409
410#define CONFIG_LOOKUP_NO_EXCEPTIONS(P, T, V)    \
411  try                                           \
412  {                                             \
413    Setting &s = lookup(P);                     \
414    V = (T)s;                                   \
415    return(true);                               \
416  }                                             \
417  catch(ConfigException)                        \
418  {                                             \
419    return(false);                              \
420  }
421
422// ---------------------------------------------------------------------------
423
424bool Config::lookupValue(const char *path, bool &value) const throw()
425{
426  CONFIG_LOOKUP_NO_EXCEPTIONS(path, bool, value);
427}
428
429// ---------------------------------------------------------------------------
430
431bool Config::lookupValue(const char *path, int &value) const throw()
432{
433  CONFIG_LOOKUP_NO_EXCEPTIONS(path, int, value);
434}
435
436// ---------------------------------------------------------------------------
437
438bool Config::lookupValue(const char *path, unsigned int &value) const throw()
439{
440  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned int, value);
441}
442
443// ---------------------------------------------------------------------------
444
445bool Config::lookupValue(const char *path, long long &value) const throw()
446{
447  CONFIG_LOOKUP_NO_EXCEPTIONS(path, long long, value);
448}
449
450// ---------------------------------------------------------------------------
451
452bool Config::lookupValue(const char *path, unsigned long long &value)
453  const throw()
454{
455  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned long long, value);
456}
457
458// ---------------------------------------------------------------------------
459
460bool Config::lookupValue(const char *path, double &value) const throw()
461{
462  CONFIG_LOOKUP_NO_EXCEPTIONS(path, double, value);
463}
464
465// ---------------------------------------------------------------------------
466
467bool Config::lookupValue(const char *path, float &value) const throw()
468{
469  CONFIG_LOOKUP_NO_EXCEPTIONS(path, float, value);
470}
471
472// ---------------------------------------------------------------------------
473
474bool Config::lookupValue(const char *path, const char *&value) const throw()
475{
476  CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
477}
478
479// ---------------------------------------------------------------------------
480
481bool Config::lookupValue(const char *path, std::string &value) const throw()
482{
483  CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
484}
485
486// ---------------------------------------------------------------------------
487
488Setting & Config::getRoot() const
489{
490  return(Setting::wrapSetting(config_root_setting(_config)));
491}
492
493// ---------------------------------------------------------------------------
494
495Setting::Setting(config_setting_t *setting)
496  : _setting(setting)
497{
498  switch(config_setting_type(setting))
499  {
500    case CONFIG_TYPE_GROUP:
501      _type = TypeGroup;
502      break;
503
504    case CONFIG_TYPE_INT:
505      _type = TypeInt;
506      break;
507
508    case CONFIG_TYPE_INT64:
509      _type = TypeInt64;
510      break;
511
512    case CONFIG_TYPE_FLOAT:
513      _type = TypeFloat;
514      break;
515
516    case CONFIG_TYPE_STRING:
517      _type = TypeString;
518      break;
519
520    case CONFIG_TYPE_BOOL:
521      _type = TypeBoolean;
522      break;
523
524    case CONFIG_TYPE_ARRAY:
525      _type = TypeArray;
526      break;
527
528    case CONFIG_TYPE_LIST:
529      _type = TypeList;
530      break;
531
532    case CONFIG_TYPE_NONE:
533    default:
534      _type = TypeNone;
535      break;
536  }
537
538  switch(config_setting_get_format(setting))
539  {
540    case CONFIG_FORMAT_HEX:
541      _format = FormatHex;
542      break;
543
544    case CONFIG_FORMAT_DEFAULT:
545    default:
546      _format = FormatDefault;
547      break;
548  }
549}
550
551// ---------------------------------------------------------------------------
552
553Setting::~Setting() throw()
554{
555  _setting = NULL;
556}
557
558// ---------------------------------------------------------------------------
559
560void Setting::setFormat(Format format) throw()
561{
562  if((_type == TypeInt) || (_type == TypeInt64))
563  {
564    if(format == FormatHex)
565      _format = FormatHex;
566    else
567      _format = FormatDefault;
568  }
569  else
570    _format = FormatDefault;
571
572  config_setting_set_format(_setting, static_cast<short>(_format));
573}
574
575// ---------------------------------------------------------------------------
576
577Setting::operator bool() const throw(SettingTypeException)
578{
579  assertType(TypeBoolean);
580
581  return(config_setting_get_bool(_setting) ? true : false);
582}
583
584// ---------------------------------------------------------------------------
585
586Setting::operator int() const throw(SettingTypeException)
587{
588  assertType(TypeInt);
589
590  return(config_setting_get_int(_setting));
591}
592
593// ---------------------------------------------------------------------------
594
595Setting::operator unsigned int() const throw(SettingTypeException)
596{
597  assertType(TypeInt);
598
599  int v = config_setting_get_int(_setting);
600
601  if(v < 0)
602    v = 0;
603
604  return(static_cast<unsigned int>(v));
605}
606
607// ---------------------------------------------------------------------------
608
609Setting::operator long() const throw(SettingTypeException)
610{
611  if(sizeof(long) == sizeof(long long))
612    return operator long long();
613  else
614    return operator int();
615}
616
617// ---------------------------------------------------------------------------
618
619Setting::operator unsigned long() const throw(SettingTypeException)
620{
621  if(sizeof(long) == sizeof(long long))
622    return operator unsigned long long();
623  else
624    return operator unsigned int();
625}
626
627// ---------------------------------------------------------------------------
628
629Setting::operator long long() const throw(SettingTypeException)
630{
631  assertType(TypeInt64);
632
633  return(config_setting_get_int64(_setting));
634}
635
636// ---------------------------------------------------------------------------
637
638Setting::operator unsigned long long() const throw(SettingTypeException)
639{
640  assertType(TypeInt64);
641
642  long long v = config_setting_get_int64(_setting);
643
644  if(v < INT64_CONST(0))
645    v = INT64_CONST(0);
646
647  return(static_cast<unsigned long long>(v));
648}
649
650// ---------------------------------------------------------------------------
651
652Setting::operator double() const throw(SettingTypeException)
653{
654  assertType(TypeFloat);
655
656  return(config_setting_get_float(_setting));
657}
658
659// ---------------------------------------------------------------------------
660
661Setting::operator float() const throw(SettingTypeException)
662{
663  assertType(TypeFloat);
664
665  // may cause loss of precision:
666  return(static_cast<float>(config_setting_get_float(_setting)));
667}
668
669// ---------------------------------------------------------------------------
670
671Setting::operator const char *() const throw(SettingTypeException)
672{
673  assertType(TypeString);
674
675  return(config_setting_get_string(_setting));
676}
677
678// ---------------------------------------------------------------------------
679
680Setting::operator std::string() const throw(SettingTypeException)
681{
682  assertType(TypeString);
683
684  const char *s = config_setting_get_string(_setting);
685
686  std::string str;
687  if(s)
688    str = s;
689
690  return(str);
691}
692
693// ---------------------------------------------------------------------------
694
695Setting & Setting::operator=(bool value) throw(SettingTypeException)
696{
697  assertType(TypeBoolean);
698
699  config_setting_set_bool(_setting, value);
700
701  return(*this);
702}
703
704// ---------------------------------------------------------------------------
705
706Setting & Setting::operator=(int value) throw(SettingTypeException)
707{
708  assertType(TypeInt);
709
710  config_setting_set_int(_setting, value);
711
712  return(*this);
713}
714
715// ---------------------------------------------------------------------------
716
717Setting & Setting::operator=(long value) throw(SettingTypeException)
718{
719  if(sizeof(long) == sizeof(long long))
720    return(operator=(static_cast<long long>(value)));
721  else
722    return(operator=(static_cast<int>(value)));
723}
724
725// ---------------------------------------------------------------------------
726
727Setting & Setting::operator=(const long long &value)
728  throw(SettingTypeException)
729{
730  assertType(TypeInt64);
731
732  config_setting_set_int64(_setting, value);
733
734  return(*this);
735}
736
737// ---------------------------------------------------------------------------
738
739Setting & Setting::operator=(const double &value) throw(SettingTypeException)
740{
741  assertType(TypeFloat);
742
743  config_setting_set_float(_setting, value);
744
745  return(*this);
746}
747
748// ---------------------------------------------------------------------------
749
750Setting & Setting::operator=(float value) throw(SettingTypeException)
751{
752  assertType(TypeFloat);
753
754  double cvalue = static_cast<double>(value);
755
756  config_setting_set_float(_setting, cvalue);
757
758  return(*this);
759}
760
761// ---------------------------------------------------------------------------
762
763Setting & Setting::operator=(const char *value) throw(SettingTypeException)
764{
765  assertType(TypeString);
766
767  config_setting_set_string(_setting, value);
768
769  return(*this);
770}
771
772// ---------------------------------------------------------------------------
773
774Setting & Setting::operator=(const std::string &value)
775  throw(SettingTypeException)
776{
777  assertType(TypeString);
778
779  config_setting_set_string(_setting, value.c_str());
780
781  return(*this);
782}
783
784// ---------------------------------------------------------------------------
785
786Setting & Setting::operator[](int i) const
787  throw(SettingTypeException, SettingNotFoundException)
788{
789  if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
790    throw SettingTypeException(*this, i);
791
792  config_setting_t *setting = config_setting_get_elem(_setting, i);
793
794  if(! setting)
795    throw SettingNotFoundException(*this, i);
796
797  return(wrapSetting(setting));
798}
799
800// ---------------------------------------------------------------------------
801
802Setting & Setting::operator[](const char *key) const
803  throw(SettingTypeException, SettingNotFoundException)
804{
805  assertType(TypeGroup);
806
807  config_setting_t *setting = config_setting_get_member(_setting, key);
808
809  if(! setting)
810    throw SettingNotFoundException(*this, key);
811
812  return(wrapSetting(setting));
813}
814
815// ---------------------------------------------------------------------------
816
817#define SETTING_LOOKUP_NO_EXCEPTIONS(K, T, V)   \
818  try                                           \
819  {                                             \
820    Setting &s = operator[](K);                 \
821    V = (T)s;                                   \
822    return(true);                               \
823  }                                             \
824  catch(ConfigException)                        \
825  {                                             \
826    return(false);                              \
827  }
828
829// ---------------------------------------------------------------------------
830
831bool Setting::lookupValue(const char *name, bool &value) const throw()
832{
833  SETTING_LOOKUP_NO_EXCEPTIONS(name, bool, value);
834}
835
836// ---------------------------------------------------------------------------
837
838bool Setting::lookupValue(const char *name, int &value) const throw()
839{
840  SETTING_LOOKUP_NO_EXCEPTIONS(name, int, value);
841}
842
843// ---------------------------------------------------------------------------
844
845bool Setting::lookupValue(const char *name, unsigned int &value)
846  const throw()
847{
848  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned int, value);
849}
850
851// ---------------------------------------------------------------------------
852
853bool Setting::lookupValue(const char *name, long long &value) const throw()
854{
855  SETTING_LOOKUP_NO_EXCEPTIONS(name, long long, value);
856}
857
858// ---------------------------------------------------------------------------
859
860bool Setting::lookupValue(const char *name, unsigned long long &value)
861  const throw()
862{
863  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned long long, value);
864}
865
866// ---------------------------------------------------------------------------
867
868bool Setting::lookupValue(const char *name, double &value) const throw()
869{
870  SETTING_LOOKUP_NO_EXCEPTIONS(name, double, value);
871}
872
873// ---------------------------------------------------------------------------
874
875bool Setting::lookupValue(const char *name, float &value) const throw()
876{
877  SETTING_LOOKUP_NO_EXCEPTIONS(name, float, value);
878}
879
880// ---------------------------------------------------------------------------
881
882bool Setting::lookupValue(const char *name, const char *&value) const throw()
883{
884  SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
885}
886
887// ---------------------------------------------------------------------------
888
889bool Setting::lookupValue(const char *name, std::string &value) const throw()
890{
891  SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
892}
893
894// ---------------------------------------------------------------------------
895
896bool Setting::exists(const char *name) const throw()
897{
898  if(_type != TypeGroup)
899    return(false);
900
901  config_setting_t *setting = config_setting_get_member(_setting, name);
902
903  return(setting != NULL);
904}
905
906// ---------------------------------------------------------------------------
907
908int Setting::getLength() const throw()
909{
910  return(config_setting_length(_setting));
911}
912
913// ---------------------------------------------------------------------------
914
915const char * Setting::getName() const throw()
916{
917  return(config_setting_name(_setting));
918}
919
920// ---------------------------------------------------------------------------
921
922std::string Setting::getPath() const
923{
924  std::stringstream path;
925
926  __constructPath(*this, path);
927
928  return(path.str());
929}
930
931// ---------------------------------------------------------------------------
932
933const Setting & Setting::getParent() const throw(SettingNotFoundException)
934{
935  config_setting_t *setting = config_setting_parent(_setting);
936
937  if(! setting)
938    throw SettingNotFoundException(NULL);
939
940  return(wrapSetting(setting));
941}
942
943// ---------------------------------------------------------------------------
944
945Setting & Setting::getParent() throw(SettingNotFoundException)
946{
947  config_setting_t *setting = config_setting_parent(_setting);
948
949  if(! setting)
950    throw SettingNotFoundException(NULL);
951
952  return(wrapSetting(setting));
953}
954
955// ---------------------------------------------------------------------------
956
957unsigned int Setting::getSourceLine() const throw()
958{
959  return(config_setting_source_line(_setting));
960}
961
962// ---------------------------------------------------------------------------
963
964const char *Setting::getSourceFile() const throw()
965{
966  return(config_setting_source_file(_setting));
967}
968
969// ---------------------------------------------------------------------------
970
971bool Setting::isRoot() const throw()
972{
973  return(config_setting_is_root(_setting));
974}
975
976// ---------------------------------------------------------------------------
977
978int Setting::getIndex() const throw()
979{
980  return(config_setting_index(_setting));
981}
982
983// ---------------------------------------------------------------------------
984
985void Setting::remove(const char *name)
986  throw(SettingTypeException, SettingNotFoundException)
987{
988  assertType(TypeGroup);
989
990  if(! config_setting_remove(_setting, name))
991    throw SettingNotFoundException(*this, name);
992}
993
994// ---------------------------------------------------------------------------
995
996void Setting::remove(unsigned int idx)
997  throw(SettingTypeException, SettingNotFoundException)
998{
999  if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
1000    throw SettingTypeException(*this, idx);
1001
1002  if(! config_setting_remove_elem(_setting, idx))
1003    throw SettingNotFoundException(*this, idx);
1004}
1005
1006// ---------------------------------------------------------------------------
1007
1008Setting & Setting::add(const char *name, Setting::Type type)
1009  throw(SettingNameException, SettingTypeException)
1010{
1011  assertType(TypeGroup);
1012
1013  int typecode = __toTypeCode(type);
1014
1015  if(typecode == CONFIG_TYPE_NONE)
1016    throw SettingTypeException(*this, name);
1017
1018  config_setting_t *setting = config_setting_add(_setting, name, typecode);
1019
1020  if(! setting)
1021    throw SettingNameException(*this, name);
1022
1023  return(wrapSetting(setting));
1024}
1025
1026// ---------------------------------------------------------------------------
1027
1028Setting & Setting::add(Setting::Type type) throw(SettingTypeException)
1029{
1030  if((_type != TypeArray) && (_type != TypeList))
1031    throw SettingTypeException(*this);
1032
1033  if(_type == TypeArray)
1034  {
1035    int idx = getLength();
1036
1037    if(idx > 0)
1038    {
1039      Setting::Type atype = operator[](0).getType();
1040      if(type != atype)
1041        throw SettingTypeException(*this, idx);
1042    }
1043    else
1044    {
1045      if((type != TypeInt) && (type != TypeFloat) && (type != TypeString)
1046         && (type != TypeBoolean))
1047        throw SettingTypeException(*this, idx);
1048    }
1049  }
1050
1051  int typecode = __toTypeCode(type);
1052  config_setting_t *s = config_setting_add(_setting, NULL, typecode);
1053
1054  Setting &ns = wrapSetting(s);
1055
1056  switch(type)
1057  {
1058    case TypeInt:
1059      ns = 0;
1060      break;
1061
1062    case TypeInt64:
1063      ns = INT64_CONST(0);
1064      break;
1065
1066    case TypeFloat:
1067      ns = 0.0;
1068      break;
1069
1070    case TypeString:
1071      ns = (char *)NULL;
1072      break;
1073
1074    case TypeBoolean:
1075      ns = false;
1076      break;
1077
1078    default:
1079      // won't happen
1080      break;
1081  }
1082
1083  return(ns);
1084}
1085
1086// ---------------------------------------------------------------------------
1087
1088void Setting::assertType(Setting::Type type) const throw(SettingTypeException)
1089{
1090  if(type != _type)
1091  {
1092    if(!(isNumber() && config_get_auto_convert(_setting->config)
1093         && ((type == TypeInt) || (type == TypeFloat))))
1094      throw SettingTypeException(*this);
1095  }
1096}
1097
1098// ---------------------------------------------------------------------------
1099
1100Setting & Setting::wrapSetting(config_setting_t *s)
1101{
1102  Setting *setting = NULL;
1103
1104  void *hook = config_setting_get_hook(s);
1105  if(! hook)
1106  {
1107    setting = new Setting(s);
1108    config_setting_set_hook(s, reinterpret_cast<void *>(setting));
1109  }
1110  else
1111    setting = reinterpret_cast<Setting *>(hook);
1112
1113  return(*setting);
1114}
1115
1116// ---------------------------------------------------------------------------
1117
1118*/
1119
1120}; // namespace libconfig
1121
1122
1123/* ----------------------------------------------------------------------------
1124
1125   This file is a mex clone of libconfigcpp.cc originally found
1126   in the libconfig library which was desgigned by Mark A Lindner.
1127   
1128   ----------------------------------------------------------------------------
1129*/
1130
1131
1132#include "libconfig_mex.h"
1133
1134#ifdef _MSC_VER
1135#pragma warning (disable: 4996)
1136#endif
1137
1138//#include "wincompat.h"
1139
1140#include <cstring>
1141#include <cstdlib>
1142#include <sstream>
1143
1144namespace libconfig {
1145
1146        /*
1147// ---------------------------------------------------------------------------
1148
1149ParseException::ParseException(const char *file, int line, const char *error)
1150  : _file(strdup(file)), _line(line), _error(error)
1151{
1152}
1153
1154// ---------------------------------------------------------------------------
1155
1156ParseException::~ParseException() throw()
1157{
1158  free((void *)_file);
1159}
1160
1161// ---------------------------------------------------------------------------
1162
1163const char *ParseException::what() const throw()
1164{
1165  return("ParseException");
1166}
1167
1168// ---------------------------------------------------------------------------
1169
1170static int __toTypeCode(Setting::Type type)
1171{
1172  int typecode;
1173
1174  switch(type)
1175  {
1176    case Setting::TypeGroup:
1177      typecode = CONFIG_TYPE_GROUP;
1178      break;
1179
1180    case Setting::TypeInt:
1181      typecode = CONFIG_TYPE_INT;
1182      break;
1183
1184    case Setting::TypeInt64:
1185      typecode = CONFIG_TYPE_INT64;
1186      break;
1187
1188    case Setting::TypeFloat:
1189      typecode = CONFIG_TYPE_FLOAT;
1190      break;
1191
1192    case Setting::TypeString:
1193      typecode = CONFIG_TYPE_STRING;
1194      break;
1195
1196    case Setting::TypeBoolean:
1197      typecode = CONFIG_TYPE_BOOL;
1198      break;
1199
1200    case Setting::TypeArray:
1201      typecode = CONFIG_TYPE_ARRAY;
1202      break;
1203
1204    case Setting::TypeList:
1205      typecode = CONFIG_TYPE_LIST;
1206      break;
1207
1208    default:
1209      typecode = CONFIG_TYPE_NONE;
1210  }
1211
1212  return(typecode);
1213}
1214
1215// ---------------------------------------------------------------------------
1216
1217static void __constructPath(const Setting &setting,
1218                            std::stringstream &path)
1219{
1220  // head recursion to print path from root to target
1221
1222  if(! setting.isRoot())
1223  {
1224    __constructPath(setting.getParent(), path);
1225    if(path.tellp() > 0)
1226      path << '.';
1227
1228    const char *name = setting.getName();
1229    if(name)
1230      path << name;
1231    else
1232      path << '[' << setting.getIndex() << ']';
1233  }
1234}
1235
1236// ---------------------------------------------------------------------------
1237
1238SettingException::SettingException(const Setting &setting)
1239{
1240  std::stringstream sstr;
1241  __constructPath(setting, sstr);
1242
1243  _path = ::strdup(sstr.str().c_str());
1244}
1245
1246// ---------------------------------------------------------------------------
1247
1248SettingException::SettingException(const Setting &setting, int idx)
1249{
1250  std::stringstream sstr;
1251  __constructPath(setting, sstr);
1252  sstr << ".[" << idx << "]";
1253
1254  _path = ::strdup(sstr.str().c_str());
1255}
1256
1257// ---------------------------------------------------------------------------
1258
1259SettingException::SettingException(const Setting &setting, const char *name)
1260{
1261  std::stringstream sstr;
1262  __constructPath(setting, sstr);
1263  sstr << '.' << name;
1264
1265  _path = ::strdup(sstr.str().c_str());
1266}
1267
1268// ---------------------------------------------------------------------------
1269
1270SettingException::SettingException(const char *path)
1271{
1272  _path = ::strdup(path);
1273}
1274
1275// ---------------------------------------------------------------------------
1276
1277const char *SettingException::getPath() const
1278{
1279  return(_path);
1280}
1281
1282// ---------------------------------------------------------------------------
1283
1284SettingException::SettingException(const SettingException &other)
1285{
1286  _path = ::strdup(other._path);
1287}
1288
1289// ---------------------------------------------------------------------------
1290
1291SettingException &SettingException::operator=(const SettingException &other)
1292{
1293  ::free(_path);
1294  _path = ::strdup(other._path);
1295
1296  return(*this);
1297}
1298
1299// ---------------------------------------------------------------------------
1300
1301const char *SettingException::what() const throw()
1302{
1303  return("SettingException");
1304}
1305
1306// ---------------------------------------------------------------------------
1307
1308SettingException::~SettingException() throw()
1309{
1310  ::free(_path);
1311}
1312
1313// ---------------------------------------------------------------------------
1314
1315SettingTypeException::SettingTypeException(const Setting &setting)
1316  : SettingException(setting)
1317{
1318}
1319
1320// ---------------------------------------------------------------------------
1321
1322SettingTypeException::SettingTypeException(const Setting &setting, int idx)
1323  : SettingException(setting, idx)
1324{
1325}
1326
1327// ---------------------------------------------------------------------------
1328
1329SettingTypeException::SettingTypeException(const Setting &setting,
1330                                           const char *name)
1331  : SettingException(setting, name)
1332{
1333}
1334
1335// ---------------------------------------------------------------------------
1336
1337const char *SettingTypeException::what() const throw()
1338{
1339  return("SettingTypeException");
1340}
1341
1342// ---------------------------------------------------------------------------
1343
1344SettingNotFoundException::SettingNotFoundException(const Setting &setting,
1345                                                   int idx)
1346  : SettingException(setting, idx)
1347{
1348}
1349
1350// ---------------------------------------------------------------------------
1351
1352SettingNotFoundException::SettingNotFoundException(const Setting &setting,
1353                                                   const char *name)
1354  : SettingException(setting, name)
1355{
1356}
1357
1358// ---------------------------------------------------------------------------
1359
1360SettingNotFoundException::SettingNotFoundException(const char *path)
1361  : SettingException(path)
1362{
1363}
1364
1365// ---------------------------------------------------------------------------
1366
1367const char *SettingNotFoundException::what() const throw()
1368{
1369  return("SettingNotFoundException");
1370}
1371
1372// ---------------------------------------------------------------------------
1373
1374SettingNameException::SettingNameException(const Setting &setting,
1375                                           const char *name)
1376  : SettingException(setting, name)
1377{
1378}
1379
1380// ---------------------------------------------------------------------------
1381
1382const char *SettingNameException::what() const throw()
1383{
1384  return("SettingNameException");
1385}
1386
1387// ---------------------------------------------------------------------------
1388
1389const char *FileIOException::what() const throw()
1390{
1391  return("FileIOException");
1392}
1393
1394// ---------------------------------------------------------------------------
1395
1396void Config::ConfigDestructor(void *arg)
1397{
1398  delete reinterpret_cast<Setting *>(arg);
1399}
1400
1401// ---------------------------------------------------------------------------
1402
1403Config::Config()
1404{
1405  _config = new config_t;
1406  config_init(_config);
1407  config_set_destructor(_config, ConfigDestructor);
1408}
1409
1410// ---------------------------------------------------------------------------
1411
1412Config::~Config()
1413{
1414  config_destroy(_config);
1415  delete _config;
1416}
1417
1418// ---------------------------------------------------------------------------
1419
1420void Config::setAutoConvert(bool flag)
1421{
1422  config_set_auto_convert(_config, (flag ? CONFIG_TRUE : CONFIG_FALSE));
1423}
1424
1425// ---------------------------------------------------------------------------
1426
1427bool Config::getAutoConvert() const
1428{
1429  return(config_get_auto_convert(_config) != CONFIG_FALSE);
1430}
1431
1432// ---------------------------------------------------------------------------
1433
1434void Config::setTabWidth(unsigned short width) throw()
1435{
1436  config_set_tab_width(_config, width);
1437}
1438
1439// ---------------------------------------------------------------------------
1440
1441unsigned short Config::getTabWidth() const throw()
1442{
1443  return(config_get_tab_width(_config));
1444}
1445
1446// ---------------------------------------------------------------------------
1447
1448void Config::handleError() const
1449{
1450  switch(config_error_type(_config))
1451  {
1452    case CONFIG_ERR_NONE:
1453      break;
1454   
1455    case CONFIG_ERR_PARSE:
1456      throw ParseException(config_error_file(_config),
1457                           config_error_line(_config),
1458                           config_error_text(_config));
1459      break;
1460
1461    case CONFIG_ERR_FILE_IO:
1462    default:
1463      throw FileIOException();
1464  }
1465}
1466
1467// ---------------------------------------------------------------------------
1468
1469void Config::read(FILE *stream) throw(ParseException)
1470{
1471  if(! config_read(_config, stream))
1472    handleError();
1473}
1474
1475// ---------------------------------------------------------------------------
1476
1477void Config::readString(const char *str) throw(ParseException)
1478{
1479  if(! config_read_string(_config, str))
1480    handleError();
1481}
1482
1483// ---------------------------------------------------------------------------
1484
1485void Config::write(FILE *stream) const
1486{
1487  config_write(_config, stream);
1488}
1489
1490// ---------------------------------------------------------------------------
1491
1492void Config::readFile(const char *filename) throw(FileIOException,
1493                                                  ParseException)
1494{
1495  if(! config_read_file(_config, filename))
1496    handleError();
1497}
1498
1499// ---------------------------------------------------------------------------
1500
1501void Config::writeFile(const char *filename) throw(FileIOException)
1502{
1503  if(! config_write_file(_config, filename))
1504    handleError();
1505}
1506
1507// ---------------------------------------------------------------------------
1508
1509Setting & Config::lookup(const char *path) const
1510  throw(SettingNotFoundException)
1511{
1512  config_setting_t *s = config_lookup(_config, path);
1513  if(! s)
1514    throw SettingNotFoundException(path);
1515
1516  return(Setting::wrapSetting(s));
1517}
1518
1519// ---------------------------------------------------------------------------
1520
1521bool Config::exists(const char *path) const throw()
1522{
1523  config_setting_t *s = config_lookup(_config, path);
1524
1525  return(s != NULL);
1526}
1527
1528// ---------------------------------------------------------------------------
1529
1530#define CONFIG_LOOKUP_NO_EXCEPTIONS(P, T, V)    \
1531  try                                           \
1532  {                                             \
1533    Setting &s = lookup(P);                     \
1534    V = (T)s;                                   \
1535    return(true);                               \
1536  }                                             \
1537  catch(ConfigException)                        \
1538  {                                             \
1539    return(false);                              \
1540  }
1541
1542// ---------------------------------------------------------------------------
1543
1544bool Config::lookupValue(const char *path, bool &value) const throw()
1545{
1546  CONFIG_LOOKUP_NO_EXCEPTIONS(path, bool, value);
1547}
1548
1549// ---------------------------------------------------------------------------
1550
1551bool Config::lookupValue(const char *path, int &value) const throw()
1552{
1553  CONFIG_LOOKUP_NO_EXCEPTIONS(path, int, value);
1554}
1555
1556// ---------------------------------------------------------------------------
1557
1558bool Config::lookupValue(const char *path, unsigned int &value) const throw()
1559{
1560  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned int, value);
1561}
1562
1563// ---------------------------------------------------------------------------
1564
1565bool Config::lookupValue(const char *path, long long &value) const throw()
1566{
1567  CONFIG_LOOKUP_NO_EXCEPTIONS(path, long long, value);
1568}
1569
1570// ---------------------------------------------------------------------------
1571
1572bool Config::lookupValue(const char *path, unsigned long long &value)
1573  const throw()
1574{
1575  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned long long, value);
1576}
1577
1578// ---------------------------------------------------------------------------
1579
1580bool Config::lookupValue(const char *path, double &value) const throw()
1581{
1582  CONFIG_LOOKUP_NO_EXCEPTIONS(path, double, value);
1583}
1584
1585// ---------------------------------------------------------------------------
1586
1587bool Config::lookupValue(const char *path, float &value) const throw()
1588{
1589  CONFIG_LOOKUP_NO_EXCEPTIONS(path, float, value);
1590}
1591
1592// ---------------------------------------------------------------------------
1593
1594bool Config::lookupValue(const char *path, const char *&value) const throw()
1595{
1596  CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
1597}
1598
1599// ---------------------------------------------------------------------------
1600
1601bool Config::lookupValue(const char *path, std::string &value) const throw()
1602{
1603  CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
1604}
1605
1606// ---------------------------------------------------------------------------
1607
1608Setting & Config::getRoot() const
1609{
1610  return(Setting::wrapSetting(config_root_setting(_config)));
1611}
1612
1613// ---------------------------------------------------------------------------
1614
1615Setting::Setting(config_setting_t *setting)
1616  : _setting(setting)
1617{
1618  switch(config_setting_type(setting))
1619  {
1620    case CONFIG_TYPE_GROUP:
1621      _type = TypeGroup;
1622      break;
1623
1624    case CONFIG_TYPE_INT:
1625      _type = TypeInt;
1626      break;
1627
1628    case CONFIG_TYPE_INT64:
1629      _type = TypeInt64;
1630      break;
1631
1632    case CONFIG_TYPE_FLOAT:
1633      _type = TypeFloat;
1634      break;
1635
1636    case CONFIG_TYPE_STRING:
1637      _type = TypeString;
1638      break;
1639
1640    case CONFIG_TYPE_BOOL:
1641      _type = TypeBoolean;
1642      break;
1643
1644    case CONFIG_TYPE_ARRAY:
1645      _type = TypeArray;
1646      break;
1647
1648    case CONFIG_TYPE_LIST:
1649      _type = TypeList;
1650      break;
1651
1652    case CONFIG_TYPE_NONE:
1653    default:
1654      _type = TypeNone;
1655      break;
1656  }
1657
1658  switch(config_setting_get_format(setting))
1659  {
1660    case CONFIG_FORMAT_HEX:
1661      _format = FormatHex;
1662      break;
1663
1664    case CONFIG_FORMAT_DEFAULT:
1665    default:
1666      _format = FormatDefault;
1667      break;
1668  }
1669}
1670
1671// ---------------------------------------------------------------------------
1672
1673Setting::~Setting() throw()
1674{
1675  _setting = NULL;
1676}
1677
1678// ---------------------------------------------------------------------------
1679
1680void Setting::setFormat(Format format) throw()
1681{
1682  if((_type == TypeInt) || (_type == TypeInt64))
1683  {
1684    if(format == FormatHex)
1685      _format = FormatHex;
1686    else
1687      _format = FormatDefault;
1688  }
1689  else
1690    _format = FormatDefault;
1691
1692  config_setting_set_format(_setting, static_cast<short>(_format));
1693}
1694
1695// ---------------------------------------------------------------------------
1696
1697Setting::operator bool() const throw(SettingTypeException)
1698{
1699  assertType(TypeBoolean);
1700
1701  return(config_setting_get_bool(_setting) ? true : false);
1702}
1703
1704// ---------------------------------------------------------------------------
1705
1706Setting::operator int() const throw(SettingTypeException)
1707{
1708  assertType(TypeInt);
1709
1710  return(config_setting_get_int(_setting));
1711}
1712
1713// ---------------------------------------------------------------------------
1714
1715Setting::operator unsigned int() const throw(SettingTypeException)
1716{
1717  assertType(TypeInt);
1718
1719  int v = config_setting_get_int(_setting);
1720
1721  if(v < 0)
1722    v = 0;
1723
1724  return(static_cast<unsigned int>(v));
1725}
1726
1727// ---------------------------------------------------------------------------
1728
1729Setting::operator long() const throw(SettingTypeException)
1730{
1731  if(sizeof(long) == sizeof(long long))
1732    return operator long long();
1733  else
1734    return operator int();
1735}
1736
1737// ---------------------------------------------------------------------------
1738
1739Setting::operator unsigned long() const throw(SettingTypeException)
1740{
1741  if(sizeof(long) == sizeof(long long))
1742    return operator unsigned long long();
1743  else
1744    return operator unsigned int();
1745}
1746
1747// ---------------------------------------------------------------------------
1748
1749Setting::operator long long() const throw(SettingTypeException)
1750{
1751  assertType(TypeInt64);
1752
1753  return(config_setting_get_int64(_setting));
1754}
1755
1756// ---------------------------------------------------------------------------
1757
1758Setting::operator unsigned long long() const throw(SettingTypeException)
1759{
1760  assertType(TypeInt64);
1761
1762  long long v = config_setting_get_int64(_setting);
1763
1764  if(v < INT64_CONST(0))
1765    v = INT64_CONST(0);
1766
1767  return(static_cast<unsigned long long>(v));
1768}
1769
1770// ---------------------------------------------------------------------------
1771
1772Setting::operator double() const throw(SettingTypeException)
1773{
1774  assertType(TypeFloat);
1775
1776  return(config_setting_get_float(_setting));
1777}
1778
1779// ---------------------------------------------------------------------------
1780
1781Setting::operator float() const throw(SettingTypeException)
1782{
1783  assertType(TypeFloat);
1784
1785  // may cause loss of precision:
1786  return(static_cast<float>(config_setting_get_float(_setting)));
1787}
1788
1789// ---------------------------------------------------------------------------
1790
1791Setting::operator const char *() const throw(SettingTypeException)
1792{
1793  assertType(TypeString);
1794
1795  return(config_setting_get_string(_setting));
1796}
1797
1798// ---------------------------------------------------------------------------
1799
1800Setting::operator std::string() const throw(SettingTypeException)
1801{
1802  assertType(TypeString);
1803
1804  const char *s = config_setting_get_string(_setting);
1805
1806  std::string str;
1807  if(s)
1808    str = s;
1809
1810  return(str);
1811}
1812
1813// ---------------------------------------------------------------------------
1814
1815Setting & Setting::operator=(bool value) throw(SettingTypeException)
1816{
1817  assertType(TypeBoolean);
1818
1819  config_setting_set_bool(_setting, value);
1820
1821  return(*this);
1822}
1823
1824// ---------------------------------------------------------------------------
1825
1826Setting & Setting::operator=(int value) throw(SettingTypeException)
1827{
1828  assertType(TypeInt);
1829
1830  config_setting_set_int(_setting, value);
1831
1832  return(*this);
1833}
1834
1835// ---------------------------------------------------------------------------
1836
1837Setting & Setting::operator=(long value) throw(SettingTypeException)
1838{
1839  if(sizeof(long) == sizeof(long long))
1840    return(operator=(static_cast<long long>(value)));
1841  else
1842    return(operator=(static_cast<int>(value)));
1843}
1844
1845// ---------------------------------------------------------------------------
1846
1847Setting & Setting::operator=(const long long &value)
1848  throw(SettingTypeException)
1849{
1850  assertType(TypeInt64);
1851
1852  config_setting_set_int64(_setting, value);
1853
1854  return(*this);
1855}
1856
1857// ---------------------------------------------------------------------------
1858
1859Setting & Setting::operator=(const double &value) throw(SettingTypeException)
1860{
1861  assertType(TypeFloat);
1862
1863  config_setting_set_float(_setting, value);
1864
1865  return(*this);
1866}
1867
1868// ---------------------------------------------------------------------------
1869
1870Setting & Setting::operator=(float value) throw(SettingTypeException)
1871{
1872  assertType(TypeFloat);
1873
1874  double cvalue = static_cast<double>(value);
1875
1876  config_setting_set_float(_setting, cvalue);
1877
1878  return(*this);
1879}
1880
1881// ---------------------------------------------------------------------------
1882
1883Setting & Setting::operator=(const char *value) throw(SettingTypeException)
1884{
1885  assertType(TypeString);
1886
1887  config_setting_set_string(_setting, value);
1888
1889  return(*this);
1890}
1891
1892// ---------------------------------------------------------------------------
1893
1894Setting & Setting::operator=(const std::string &value)
1895  throw(SettingTypeException)
1896{
1897  assertType(TypeString);
1898
1899  config_setting_set_string(_setting, value.c_str());
1900
1901  return(*this);
1902}
1903
1904// ---------------------------------------------------------------------------
1905
1906Setting & Setting::operator[](int i) const
1907  throw(SettingTypeException, SettingNotFoundException)
1908{
1909  if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
1910    throw SettingTypeException(*this, i);
1911
1912  config_setting_t *setting = config_setting_get_elem(_setting, i);
1913
1914  if(! setting)
1915    throw SettingNotFoundException(*this, i);
1916
1917  return(wrapSetting(setting));
1918}
1919
1920// ---------------------------------------------------------------------------
1921
1922Setting & Setting::operator[](const char *key) const
1923  throw(SettingTypeException, SettingNotFoundException)
1924{
1925  assertType(TypeGroup);
1926
1927  config_setting_t *setting = config_setting_get_member(_setting, key);
1928
1929  if(! setting)
1930    throw SettingNotFoundException(*this, key);
1931
1932  return(wrapSetting(setting));
1933}
1934
1935// ---------------------------------------------------------------------------
1936
1937#define SETTING_LOOKUP_NO_EXCEPTIONS(K, T, V)   \
1938  try                                           \
1939  {                                             \
1940    Setting &s = operator[](K);                 \
1941    V = (T)s;                                   \
1942    return(true);                               \
1943  }                                             \
1944  catch(ConfigException)                        \
1945  {                                             \
1946    return(false);                              \
1947  }
1948
1949// ---------------------------------------------------------------------------
1950
1951bool Setting::lookupValue(const char *name, bool &value) const throw()
1952{
1953  SETTING_LOOKUP_NO_EXCEPTIONS(name, bool, value);
1954}
1955
1956// ---------------------------------------------------------------------------
1957
1958bool Setting::lookupValue(const char *name, int &value) const throw()
1959{
1960  SETTING_LOOKUP_NO_EXCEPTIONS(name, int, value);
1961}
1962
1963// ---------------------------------------------------------------------------
1964
1965bool Setting::lookupValue(const char *name, unsigned int &value)
1966  const throw()
1967{
1968  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned int, value);
1969}
1970
1971// ---------------------------------------------------------------------------
1972
1973bool Setting::lookupValue(const char *name, long long &value) const throw()
1974{
1975  SETTING_LOOKUP_NO_EXCEPTIONS(name, long long, value);
1976}
1977
1978// ---------------------------------------------------------------------------
1979
1980bool Setting::lookupValue(const char *name, unsigned long long &value)
1981  const throw()
1982{
1983  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned long long, value);
1984}
1985
1986// ---------------------------------------------------------------------------
1987
1988bool Setting::lookupValue(const char *name, double &value) const throw()
1989{
1990  SETTING_LOOKUP_NO_EXCEPTIONS(name, double, value);
1991}
1992
1993// ---------------------------------------------------------------------------
1994
1995bool Setting::lookupValue(const char *name, float &value) const throw()
1996{
1997  SETTING_LOOKUP_NO_EXCEPTIONS(name, float, value);
1998}
1999
2000// ---------------------------------------------------------------------------
2001
2002bool Setting::lookupValue(const char *name, const char *&value) const throw()
2003{
2004  SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
2005}
2006
2007// ---------------------------------------------------------------------------
2008
2009bool Setting::lookupValue(const char *name, std::string &value) const throw()
2010{
2011  SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
2012}
2013
2014// ---------------------------------------------------------------------------
2015
2016bool Setting::exists(const char *name) const throw()
2017{
2018  if(_type != TypeGroup)
2019    return(false);
2020
2021  config_setting_t *setting = config_setting_get_member(_setting, name);
2022
2023  return(setting != NULL);
2024}
2025
2026// ---------------------------------------------------------------------------
2027
2028int Setting::getLength() const throw()
2029{
2030  return(config_setting_length(_setting));
2031}
2032
2033// ---------------------------------------------------------------------------
2034
2035const char * Setting::getName() const throw()
2036{
2037  return(config_setting_name(_setting));
2038}
2039
2040// ---------------------------------------------------------------------------
2041
2042std::string Setting::getPath() const
2043{
2044  std::stringstream path;
2045
2046  __constructPath(*this, path);
2047
2048  return(path.str());
2049}
2050
2051// ---------------------------------------------------------------------------
2052
2053const Setting & Setting::getParent() const throw(SettingNotFoundException)
2054{
2055  config_setting_t *setting = config_setting_parent(_setting);
2056
2057  if(! setting)
2058    throw SettingNotFoundException(NULL);
2059
2060  return(wrapSetting(setting));
2061}
2062
2063// ---------------------------------------------------------------------------
2064
2065Setting & Setting::getParent() throw(SettingNotFoundException)
2066{
2067  config_setting_t *setting = config_setting_parent(_setting);
2068
2069  if(! setting)
2070    throw SettingNotFoundException(NULL);
2071
2072  return(wrapSetting(setting));
2073}
2074
2075// ---------------------------------------------------------------------------
2076
2077unsigned int Setting::getSourceLine() const throw()
2078{
2079  return(config_setting_source_line(_setting));
2080}
2081
2082// ---------------------------------------------------------------------------
2083
2084const char *Setting::getSourceFile() const throw()
2085{
2086  return(config_setting_source_file(_setting));
2087}
2088
2089// ---------------------------------------------------------------------------
2090
2091bool Setting::isRoot() const throw()
2092{
2093  return(config_setting_is_root(_setting));
2094}
2095
2096// ---------------------------------------------------------------------------
2097
2098int Setting::getIndex() const throw()
2099{
2100  return(config_setting_index(_setting));
2101}
2102
2103// ---------------------------------------------------------------------------
2104
2105void Setting::remove(const char *name)
2106  throw(SettingTypeException, SettingNotFoundException)
2107{
2108  assertType(TypeGroup);
2109
2110  if(! config_setting_remove(_setting, name))
2111    throw SettingNotFoundException(*this, name);
2112}
2113
2114// ---------------------------------------------------------------------------
2115
2116void Setting::remove(unsigned int idx)
2117  throw(SettingTypeException, SettingNotFoundException)
2118{
2119  if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
2120    throw SettingTypeException(*this, idx);
2121
2122  if(! config_setting_remove_elem(_setting, idx))
2123    throw SettingNotFoundException(*this, idx);
2124}
2125
2126// ---------------------------------------------------------------------------
2127
2128Setting & Setting::add(const char *name, Setting::Type type)
2129  throw(SettingNameException, SettingTypeException)
2130{
2131  assertType(TypeGroup);
2132
2133  int typecode = __toTypeCode(type);
2134
2135  if(typecode == CONFIG_TYPE_NONE)
2136    throw SettingTypeException(*this, name);
2137
2138  config_setting_t *setting = config_setting_add(_setting, name, typecode);
2139
2140  if(! setting)
2141    throw SettingNameException(*this, name);
2142
2143  return(wrapSetting(setting));
2144}
2145
2146// ---------------------------------------------------------------------------
2147
2148Setting & Setting::add(Setting::Type type) throw(SettingTypeException)
2149{
2150  if((_type != TypeArray) && (_type != TypeList))
2151    throw SettingTypeException(*this);
2152
2153  if(_type == TypeArray)
2154  {
2155    int idx = getLength();
2156
2157    if(idx > 0)
2158    {
2159      Setting::Type atype = operator[](0).getType();
2160      if(type != atype)
2161        throw SettingTypeException(*this, idx);
2162    }
2163    else
2164    {
2165      if((type != TypeInt) && (type != TypeFloat) && (type != TypeString)
2166         && (type != TypeBoolean))
2167        throw SettingTypeException(*this, idx);
2168    }
2169  }
2170
2171  int typecode = __toTypeCode(type);
2172  config_setting_t *s = config_setting_add(_setting, NULL, typecode);
2173
2174  Setting &ns = wrapSetting(s);
2175
2176  switch(type)
2177  {
2178    case TypeInt:
2179      ns = 0;
2180      break;
2181
2182    case TypeInt64:
2183      ns = INT64_CONST(0);
2184      break;
2185
2186    case TypeFloat:
2187      ns = 0.0;
2188      break;
2189
2190    case TypeString:
2191      ns = (char *)NULL;
2192      break;
2193
2194    case TypeBoolean:
2195      ns = false;
2196      break;
2197
2198    default:
2199      // won't happen
2200      break;
2201  }
2202
2203  return(ns);
2204}
2205
2206// ---------------------------------------------------------------------------
2207
2208void Setting::assertType(Setting::Type type) const throw(SettingTypeException)
2209{
2210  if(type != _type)
2211  {
2212    if(!(isNumber() && config_get_auto_convert(_setting->config)
2213         && ((type == TypeInt) || (type == TypeFloat))))
2214      throw SettingTypeException(*this);
2215  }
2216}
2217
2218// ---------------------------------------------------------------------------
2219
2220Setting & Setting::wrapSetting(config_setting_t *s)
2221{
2222  Setting *setting = NULL;
2223
2224  void *hook = config_setting_get_hook(s);
2225  if(! hook)
2226  {
2227    setting = new Setting(s);
2228    config_setting_set_hook(s, reinterpret_cast<void *>(setting));
2229  }
2230  else
2231    setting = reinterpret_cast<Setting *>(hook);
2232
2233  return(*setting);
2234}
2235
2236// ---------------------------------------------------------------------------
2237
2238*/
2239
2240}; // namespace libconfig
2241
2242
2243/* ----------------------------------------------------------------------------
2244
2245   This file is a mex clone of libconfigcpp.cc originally found
2246   in the libconfig library which was desgigned by Mark A Lindner.
2247   
2248   ----------------------------------------------------------------------------
2249*/
2250
2251
2252#include "libconfig_mex.h"
2253
2254#ifdef _MSC_VER
2255#pragma warning (disable: 4996)
2256#endif
2257
2258//#include "wincompat.h"
2259
2260#include <cstring>
2261#include <cstdlib>
2262#include <sstream>
2263
2264namespace libconfig {
2265
2266        /*
2267// ---------------------------------------------------------------------------
2268
2269ParseException::ParseException(const char *file, int line, const char *error)
2270  : _file(strdup(file)), _line(line), _error(error)
2271{
2272}
2273
2274// ---------------------------------------------------------------------------
2275
2276ParseException::~ParseException() throw()
2277{
2278  free((void *)_file);
2279}
2280
2281// ---------------------------------------------------------------------------
2282
2283const char *ParseException::what() const throw()
2284{
2285  return("ParseException");
2286}
2287
2288// ---------------------------------------------------------------------------
2289
2290static int __toTypeCode(Setting::Type type)
2291{
2292  int typecode;
2293
2294  switch(type)
2295  {
2296    case Setting::TypeGroup:
2297      typecode = CONFIG_TYPE_GROUP;
2298      break;
2299
2300    case Setting::TypeInt:
2301      typecode = CONFIG_TYPE_INT;
2302      break;
2303
2304    case Setting::TypeInt64:
2305      typecode = CONFIG_TYPE_INT64;
2306      break;
2307
2308    case Setting::TypeFloat:
2309      typecode = CONFIG_TYPE_FLOAT;
2310      break;
2311
2312    case Setting::TypeString:
2313      typecode = CONFIG_TYPE_STRING;
2314      break;
2315
2316    case Setting::TypeBoolean:
2317      typecode = CONFIG_TYPE_BOOL;
2318      break;
2319
2320    case Setting::TypeArray:
2321      typecode = CONFIG_TYPE_ARRAY;
2322      break;
2323
2324    case Setting::TypeList:
2325      typecode = CONFIG_TYPE_LIST;
2326      break;
2327
2328    default:
2329      typecode = CONFIG_TYPE_NONE;
2330  }
2331
2332  return(typecode);
2333}
2334
2335// ---------------------------------------------------------------------------
2336
2337static void __constructPath(const Setting &setting,
2338                            std::stringstream &path)
2339{
2340  // head recursion to print path from root to target
2341
2342  if(! setting.isRoot())
2343  {
2344    __constructPath(setting.getParent(), path);
2345    if(path.tellp() > 0)
2346      path << '.';
2347
2348    const char *name = setting.getName();
2349    if(name)
2350      path << name;
2351    else
2352      path << '[' << setting.getIndex() << ']';
2353  }
2354}
2355
2356// ---------------------------------------------------------------------------
2357
2358SettingException::SettingException(const Setting &setting)
2359{
2360  std::stringstream sstr;
2361  __constructPath(setting, sstr);
2362
2363  _path = ::strdup(sstr.str().c_str());
2364}
2365
2366// ---------------------------------------------------------------------------
2367
2368SettingException::SettingException(const Setting &setting, int idx)
2369{
2370  std::stringstream sstr;
2371  __constructPath(setting, sstr);
2372  sstr << ".[" << idx << "]";
2373
2374  _path = ::strdup(sstr.str().c_str());
2375}
2376
2377// ---------------------------------------------------------------------------
2378
2379SettingException::SettingException(const Setting &setting, const char *name)
2380{
2381  std::stringstream sstr;
2382  __constructPath(setting, sstr);
2383  sstr << '.' << name;
2384
2385  _path = ::strdup(sstr.str().c_str());
2386}
2387
2388// ---------------------------------------------------------------------------
2389
2390SettingException::SettingException(const char *path)
2391{
2392  _path = ::strdup(path);
2393}
2394
2395// ---------------------------------------------------------------------------
2396
2397const char *SettingException::getPath() const
2398{
2399  return(_path);
2400}
2401
2402// ---------------------------------------------------------------------------
2403
2404SettingException::SettingException(const SettingException &other)
2405{
2406  _path = ::strdup(other._path);
2407}
2408
2409// ---------------------------------------------------------------------------
2410
2411SettingException &SettingException::operator=(const SettingException &other)
2412{
2413  ::free(_path);
2414  _path = ::strdup(other._path);
2415
2416  return(*this);
2417}
2418
2419// ---------------------------------------------------------------------------
2420
2421const char *SettingException::what() const throw()
2422{
2423  return("SettingException");
2424}
2425
2426// ---------------------------------------------------------------------------
2427
2428SettingException::~SettingException() throw()
2429{
2430  ::free(_path);
2431}
2432
2433// ---------------------------------------------------------------------------
2434
2435SettingTypeException::SettingTypeException(const Setting &setting)
2436  : SettingException(setting)
2437{
2438}
2439
2440// ---------------------------------------------------------------------------
2441
2442SettingTypeException::SettingTypeException(const Setting &setting, int idx)
2443  : SettingException(setting, idx)
2444{
2445}
2446
2447// ---------------------------------------------------------------------------
2448
2449SettingTypeException::SettingTypeException(const Setting &setting,
2450                                           const char *name)
2451  : SettingException(setting, name)
2452{
2453}
2454
2455// ---------------------------------------------------------------------------
2456
2457const char *SettingTypeException::what() const throw()
2458{
2459  return("SettingTypeException");
2460}
2461
2462// ---------------------------------------------------------------------------
2463
2464SettingNotFoundException::SettingNotFoundException(const Setting &setting,
2465                                                   int idx)
2466  : SettingException(setting, idx)
2467{
2468}
2469
2470// ---------------------------------------------------------------------------
2471
2472SettingNotFoundException::SettingNotFoundException(const Setting &setting,
2473                                                   const char *name)
2474  : SettingException(setting, name)
2475{
2476}
2477
2478// ---------------------------------------------------------------------------
2479
2480SettingNotFoundException::SettingNotFoundException(const char *path)
2481  : SettingException(path)
2482{
2483}
2484
2485// ---------------------------------------------------------------------------
2486
2487const char *SettingNotFoundException::what() const throw()
2488{
2489  return("SettingNotFoundException");
2490}
2491
2492// ---------------------------------------------------------------------------
2493
2494SettingNameException::SettingNameException(const Setting &setting,
2495                                           const char *name)
2496  : SettingException(setting, name)
2497{
2498}
2499
2500// ---------------------------------------------------------------------------
2501
2502const char *SettingNameException::what() const throw()
2503{
2504  return("SettingNameException");
2505}
2506
2507// ---------------------------------------------------------------------------
2508
2509const char *FileIOException::what() const throw()
2510{
2511  return("FileIOException");
2512}
2513
2514// ---------------------------------------------------------------------------
2515
2516void Config::ConfigDestructor(void *arg)
2517{
2518  delete reinterpret_cast<Setting *>(arg);
2519}
2520
2521// ---------------------------------------------------------------------------
2522
2523Config::Config()
2524{
2525  _config = new config_t;
2526  config_init(_config);
2527  config_set_destructor(_config, ConfigDestructor);
2528}
2529
2530// ---------------------------------------------------------------------------
2531
2532Config::~Config()
2533{
2534  config_destroy(_config);
2535  delete _config;
2536}
2537
2538// ---------------------------------------------------------------------------
2539
2540void Config::setAutoConvert(bool flag)
2541{
2542  config_set_auto_convert(_config, (flag ? CONFIG_TRUE : CONFIG_FALSE));
2543}
2544
2545// ---------------------------------------------------------------------------
2546
2547bool Config::getAutoConvert() const
2548{
2549  return(config_get_auto_convert(_config) != CONFIG_FALSE);
2550}
2551
2552// ---------------------------------------------------------------------------
2553
2554void Config::setTabWidth(unsigned short width) throw()
2555{
2556  config_set_tab_width(_config, width);
2557}
2558
2559// ---------------------------------------------------------------------------
2560
2561unsigned short Config::getTabWidth() const throw()
2562{
2563  return(config_get_tab_width(_config));
2564}
2565
2566// ---------------------------------------------------------------------------
2567
2568void Config::handleError() const
2569{
2570  switch(config_error_type(_config))
2571  {
2572    case CONFIG_ERR_NONE:
2573      break;
2574   
2575    case CONFIG_ERR_PARSE:
2576      throw ParseException(config_error_file(_config),
2577                           config_error_line(_config),
2578                           config_error_text(_config));
2579      break;
2580
2581    case CONFIG_ERR_FILE_IO:
2582    default:
2583      throw FileIOException();
2584  }
2585}
2586
2587// ---------------------------------------------------------------------------
2588
2589void Config::read(FILE *stream) throw(ParseException)
2590{
2591  if(! config_read(_config, stream))
2592    handleError();
2593}
2594
2595// ---------------------------------------------------------------------------
2596
2597void Config::readString(const char *str) throw(ParseException)
2598{
2599  if(! config_read_string(_config, str))
2600    handleError();
2601}
2602
2603// ---------------------------------------------------------------------------
2604
2605void Config::write(FILE *stream) const
2606{
2607  config_write(_config, stream);
2608}
2609
2610// ---------------------------------------------------------------------------
2611
2612void Config::readFile(const char *filename) throw(FileIOException,
2613                                                  ParseException)
2614{
2615  if(! config_read_file(_config, filename))
2616    handleError();
2617}
2618
2619// ---------------------------------------------------------------------------
2620
2621void Config::writeFile(const char *filename) throw(FileIOException)
2622{
2623  if(! config_write_file(_config, filename))
2624    handleError();
2625}
2626
2627// ---------------------------------------------------------------------------
2628
2629Setting & Config::lookup(const char *path) const
2630  throw(SettingNotFoundException)
2631{
2632  config_setting_t *s = config_lookup(_config, path);
2633  if(! s)
2634    throw SettingNotFoundException(path);
2635
2636  return(Setting::wrapSetting(s));
2637}
2638
2639// ---------------------------------------------------------------------------
2640
2641bool Config::exists(const char *path) const throw()
2642{
2643  config_setting_t *s = config_lookup(_config, path);
2644
2645  return(s != NULL);
2646}
2647
2648// ---------------------------------------------------------------------------
2649
2650#define CONFIG_LOOKUP_NO_EXCEPTIONS(P, T, V)    \
2651  try                                           \
2652  {                                             \
2653    Setting &s = lookup(P);                     \
2654    V = (T)s;                                   \
2655    return(true);                               \
2656  }                                             \
2657  catch(ConfigException)                        \
2658  {                                             \
2659    return(false);                              \
2660  }
2661
2662// ---------------------------------------------------------------------------
2663
2664bool Config::lookupValue(const char *path, bool &value) const throw()
2665{
2666  CONFIG_LOOKUP_NO_EXCEPTIONS(path, bool, value);
2667}
2668
2669// ---------------------------------------------------------------------------
2670
2671bool Config::lookupValue(const char *path, int &value) const throw()
2672{
2673  CONFIG_LOOKUP_NO_EXCEPTIONS(path, int, value);
2674}
2675
2676// ---------------------------------------------------------------------------
2677
2678bool Config::lookupValue(const char *path, unsigned int &value) const throw()
2679{
2680  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned int, value);
2681}
2682
2683// ---------------------------------------------------------------------------
2684
2685bool Config::lookupValue(const char *path, long long &value) const throw()
2686{
2687  CONFIG_LOOKUP_NO_EXCEPTIONS(path, long long, value);
2688}
2689
2690// ---------------------------------------------------------------------------
2691
2692bool Config::lookupValue(const char *path, unsigned long long &value)
2693  const throw()
2694{
2695  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned long long, value);
2696}
2697
2698// ---------------------------------------------------------------------------
2699
2700bool Config::lookupValue(const char *path, double &value) const throw()
2701{
2702  CONFIG_LOOKUP_NO_EXCEPTIONS(path, double, value);
2703}
2704
2705// ---------------------------------------------------------------------------
2706
2707bool Config::lookupValue(const char *path, float &value) const throw()
2708{
2709  CONFIG_LOOKUP_NO_EXCEPTIONS(path, float, value);
2710}
2711
2712// ---------------------------------------------------------------------------
2713
2714bool Config::lookupValue(const char *path, const char *&value) const throw()
2715{
2716  CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
2717}
2718
2719// ---------------------------------------------------------------------------
2720
2721bool Config::lookupValue(const char *path, std::string &value) const throw()
2722{
2723  CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
2724}
2725
2726// ---------------------------------------------------------------------------
2727
2728Setting & Config::getRoot() const
2729{
2730  return(Setting::wrapSetting(config_root_setting(_config)));
2731}
2732
2733// ---------------------------------------------------------------------------
2734
2735Setting::Setting(config_setting_t *setting)
2736  : _setting(setting)
2737{
2738  switch(config_setting_type(setting))
2739  {
2740    case CONFIG_TYPE_GROUP:
2741      _type = TypeGroup;
2742      break;
2743
2744    case CONFIG_TYPE_INT:
2745      _type = TypeInt;
2746      break;
2747
2748    case CONFIG_TYPE_INT64:
2749      _type = TypeInt64;
2750      break;
2751
2752    case CONFIG_TYPE_FLOAT:
2753      _type = TypeFloat;
2754      break;
2755
2756    case CONFIG_TYPE_STRING:
2757      _type = TypeString;
2758      break;
2759
2760    case CONFIG_TYPE_BOOL:
2761      _type = TypeBoolean;
2762      break;
2763
2764    case CONFIG_TYPE_ARRAY:
2765      _type = TypeArray;
2766      break;
2767
2768    case CONFIG_TYPE_LIST:
2769      _type = TypeList;
2770      break;
2771
2772    case CONFIG_TYPE_NONE:
2773    default:
2774      _type = TypeNone;
2775      break;
2776  }
2777
2778  switch(config_setting_get_format(setting))
2779  {
2780    case CONFIG_FORMAT_HEX:
2781      _format = FormatHex;
2782      break;
2783
2784    case CONFIG_FORMAT_DEFAULT:
2785    default:
2786      _format = FormatDefault;
2787      break;
2788  }
2789}
2790
2791// ---------------------------------------------------------------------------
2792
2793Setting::~Setting() throw()
2794{
2795  _setting = NULL;
2796}
2797
2798// ---------------------------------------------------------------------------
2799
2800void Setting::setFormat(Format format) throw()
2801{
2802  if((_type == TypeInt) || (_type == TypeInt64))
2803  {
2804    if(format == FormatHex)
2805      _format = FormatHex;
2806    else
2807      _format = FormatDefault;
2808  }
2809  else
2810    _format = FormatDefault;
2811
2812  config_setting_set_format(_setting, static_cast<short>(_format));
2813}
2814
2815// ---------------------------------------------------------------------------
2816
2817Setting::operator bool() const throw(SettingTypeException)
2818{
2819  assertType(TypeBoolean);
2820
2821  return(config_setting_get_bool(_setting) ? true : false);
2822}
2823
2824// ---------------------------------------------------------------------------
2825
2826Setting::operator int() const throw(SettingTypeException)
2827{
2828  assertType(TypeInt);
2829
2830  return(config_setting_get_int(_setting));
2831}
2832
2833// ---------------------------------------------------------------------------
2834
2835Setting::operator unsigned int() const throw(SettingTypeException)
2836{
2837  assertType(TypeInt);
2838
2839  int v = config_setting_get_int(_setting);
2840
2841  if(v < 0)
2842    v = 0;
2843
2844  return(static_cast<unsigned int>(v));
2845}
2846
2847// ---------------------------------------------------------------------------
2848
2849Setting::operator long() const throw(SettingTypeException)
2850{
2851  if(sizeof(long) == sizeof(long long))
2852    return operator long long();
2853  else
2854    return operator int();
2855}
2856
2857// ---------------------------------------------------------------------------
2858
2859Setting::operator unsigned long() const throw(SettingTypeException)
2860{
2861  if(sizeof(long) == sizeof(long long))
2862    return operator unsigned long long();
2863  else
2864    return operator unsigned int();
2865}
2866
2867// ---------------------------------------------------------------------------
2868
2869Setting::operator long long() const throw(SettingTypeException)
2870{
2871  assertType(TypeInt64);
2872
2873  return(config_setting_get_int64(_setting));
2874}
2875
2876// ---------------------------------------------------------------------------
2877
2878Setting::operator unsigned long long() const throw(SettingTypeException)
2879{
2880  assertType(TypeInt64);
2881
2882  long long v = config_setting_get_int64(_setting);
2883
2884  if(v < INT64_CONST(0))
2885    v = INT64_CONST(0);
2886
2887  return(static_cast<unsigned long long>(v));
2888}
2889
2890// ---------------------------------------------------------------------------
2891
2892Setting::operator double() const throw(SettingTypeException)
2893{
2894  assertType(TypeFloat);
2895
2896  return(config_setting_get_float(_setting));
2897}
2898
2899// ---------------------------------------------------------------------------
2900
2901Setting::operator float() const throw(SettingTypeException)
2902{
2903  assertType(TypeFloat);
2904
2905  // may cause loss of precision:
2906  return(static_cast<float>(config_setting_get_float(_setting)));
2907}
2908
2909// ---------------------------------------------------------------------------
2910
2911Setting::operator const char *() const throw(SettingTypeException)
2912{
2913  assertType(TypeString);
2914
2915  return(config_setting_get_string(_setting));
2916}
2917
2918// ---------------------------------------------------------------------------
2919
2920Setting::operator std::string() const throw(SettingTypeException)
2921{
2922  assertType(TypeString);
2923
2924  const char *s = config_setting_get_string(_setting);
2925
2926  std::string str;
2927  if(s)
2928    str = s;
2929
2930  return(str);
2931}
2932
2933// ---------------------------------------------------------------------------
2934
2935Setting & Setting::operator=(bool value) throw(SettingTypeException)
2936{
2937  assertType(TypeBoolean);
2938
2939  config_setting_set_bool(_setting, value);
2940
2941  return(*this);
2942}
2943
2944// ---------------------------------------------------------------------------
2945
2946Setting & Setting::operator=(int value) throw(SettingTypeException)
2947{
2948  assertType(TypeInt);
2949
2950  config_setting_set_int(_setting, value);
2951
2952  return(*this);
2953}
2954
2955// ---------------------------------------------------------------------------
2956
2957Setting & Setting::operator=(long value) throw(SettingTypeException)
2958{
2959  if(sizeof(long) == sizeof(long long))
2960    return(operator=(static_cast<long long>(value)));
2961  else
2962    return(operator=(static_cast<int>(value)));
2963}
2964
2965// ---------------------------------------------------------------------------
2966
2967Setting & Setting::operator=(const long long &value)
2968  throw(SettingTypeException)
2969{
2970  assertType(TypeInt64);
2971
2972  config_setting_set_int64(_setting, value);
2973
2974  return(*this);
2975}
2976
2977// ---------------------------------------------------------------------------
2978
2979Setting & Setting::operator=(const double &value) throw(SettingTypeException)
2980{
2981  assertType(TypeFloat);
2982
2983  config_setting_set_float(_setting, value);
2984
2985  return(*this);
2986}
2987
2988// ---------------------------------------------------------------------------
2989
2990Setting & Setting::operator=(float value) throw(SettingTypeException)
2991{
2992  assertType(TypeFloat);
2993
2994  double cvalue = static_cast<double>(value);
2995
2996  config_setting_set_float(_setting, cvalue);
2997
2998  return(*this);
2999}
3000
3001// ---------------------------------------------------------------------------
3002
3003Setting & Setting::operator=(const char *value) throw(SettingTypeException)
3004{
3005  assertType(TypeString);
3006
3007  config_setting_set_string(_setting, value);
3008
3009  return(*this);
3010}
3011
3012// ---------------------------------------------------------------------------
3013
3014Setting & Setting::operator=(const std::string &value)
3015  throw(SettingTypeException)
3016{
3017  assertType(TypeString);
3018
3019  config_setting_set_string(_setting, value.c_str());
3020
3021  return(*this);
3022}
3023
3024// ---------------------------------------------------------------------------
3025
3026Setting & Setting::operator[](int i) const
3027  throw(SettingTypeException, SettingNotFoundException)
3028{
3029  if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
3030    throw SettingTypeException(*this, i);
3031
3032  config_setting_t *setting = config_setting_get_elem(_setting, i);
3033
3034  if(! setting)
3035    throw SettingNotFoundException(*this, i);
3036
3037  return(wrapSetting(setting));
3038}
3039
3040// ---------------------------------------------------------------------------
3041
3042Setting & Setting::operator[](const char *key) const
3043  throw(SettingTypeException, SettingNotFoundException)
3044{
3045  assertType(TypeGroup);
3046
3047  config_setting_t *setting = config_setting_get_member(_setting, key);
3048
3049  if(! setting)
3050    throw SettingNotFoundException(*this, key);
3051
3052  return(wrapSetting(setting));
3053}
3054
3055// ---------------------------------------------------------------------------
3056
3057#define SETTING_LOOKUP_NO_EXCEPTIONS(K, T, V)   \
3058  try                                           \
3059  {                                             \
3060    Setting &s = operator[](K);                 \
3061    V = (T)s;                                   \
3062    return(true);                               \
3063  }                                             \
3064  catch(ConfigException)                        \
3065  {                                             \
3066    return(false);                              \
3067  }
3068
3069// ---------------------------------------------------------------------------
3070
3071bool Setting::lookupValue(const char *name, bool &value) const throw()
3072{
3073  SETTING_LOOKUP_NO_EXCEPTIONS(name, bool, value);
3074}
3075
3076// ---------------------------------------------------------------------------
3077
3078bool Setting::lookupValue(const char *name, int &value) const throw()
3079{
3080  SETTING_LOOKUP_NO_EXCEPTIONS(name, int, value);
3081}
3082
3083// ---------------------------------------------------------------------------
3084
3085bool Setting::lookupValue(const char *name, unsigned int &value)
3086  const throw()
3087{
3088  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned int, value);
3089}
3090
3091// ---------------------------------------------------------------------------
3092
3093bool Setting::lookupValue(const char *name, long long &value) const throw()
3094{
3095  SETTING_LOOKUP_NO_EXCEPTIONS(name, long long, value);
3096}
3097
3098// ---------------------------------------------------------------------------
3099
3100bool Setting::lookupValue(const char *name, unsigned long long &value)
3101  const throw()
3102{
3103  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned long long, value);
3104}
3105
3106// ---------------------------------------------------------------------------
3107
3108bool Setting::lookupValue(const char *name, double &value) const throw()
3109{
3110  SETTING_LOOKUP_NO_EXCEPTIONS(name, double, value);
3111}
3112
3113// ---------------------------------------------------------------------------
3114
3115bool Setting::lookupValue(const char *name, float &value) const throw()
3116{
3117  SETTING_LOOKUP_NO_EXCEPTIONS(name, float, value);
3118}
3119
3120// ---------------------------------------------------------------------------
3121
3122bool Setting::lookupValue(const char *name, const char *&value) const throw()
3123{
3124  SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
3125}
3126
3127// ---------------------------------------------------------------------------
3128
3129bool Setting::lookupValue(const char *name, std::string &value) const throw()
3130{
3131  SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
3132}
3133
3134// ---------------------------------------------------------------------------
3135
3136bool Setting::exists(const char *name) const throw()
3137{
3138  if(_type != TypeGroup)
3139    return(false);
3140
3141  config_setting_t *setting = config_setting_get_member(_setting, name);
3142
3143  return(setting != NULL);
3144}
3145
3146// ---------------------------------------------------------------------------
3147
3148int Setting::getLength() const throw()
3149{
3150  return(config_setting_length(_setting));
3151}
3152
3153// ---------------------------------------------------------------------------
3154
3155const char * Setting::getName() const throw()
3156{
3157  return(config_setting_name(_setting));
3158}
3159
3160// ---------------------------------------------------------------------------
3161
3162std::string Setting::getPath() const
3163{
3164  std::stringstream path;
3165
3166  __constructPath(*this, path);
3167
3168  return(path.str());
3169}
3170
3171// ---------------------------------------------------------------------------
3172
3173const Setting & Setting::getParent() const throw(SettingNotFoundException)
3174{
3175  config_setting_t *setting = config_setting_parent(_setting);
3176
3177  if(! setting)
3178    throw SettingNotFoundException(NULL);
3179
3180  return(wrapSetting(setting));
3181}
3182
3183// ---------------------------------------------------------------------------
3184
3185Setting & Setting::getParent() throw(SettingNotFoundException)
3186{
3187  config_setting_t *setting = config_setting_parent(_setting);
3188
3189  if(! setting)
3190    throw SettingNotFoundException(NULL);
3191
3192  return(wrapSetting(setting));
3193}
3194
3195// ---------------------------------------------------------------------------
3196
3197unsigned int Setting::getSourceLine() const throw()
3198{
3199  return(config_setting_source_line(_setting));
3200}
3201
3202// ---------------------------------------------------------------------------
3203
3204const char *Setting::getSourceFile() const throw()
3205{
3206  return(config_setting_source_file(_setting));
3207}
3208
3209// ---------------------------------------------------------------------------
3210
3211bool Setting::isRoot() const throw()
3212{
3213  return(config_setting_is_root(_setting));
3214}
3215
3216// ---------------------------------------------------------------------------
3217
3218int Setting::getIndex() const throw()
3219{
3220  return(config_setting_index(_setting));
3221}
3222
3223// ---------------------------------------------------------------------------
3224
3225void Setting::remove(const char *name)
3226  throw(SettingTypeException, SettingNotFoundException)
3227{
3228  assertType(TypeGroup);
3229
3230  if(! config_setting_remove(_setting, name))
3231    throw SettingNotFoundException(*this, name);
3232}
3233
3234// ---------------------------------------------------------------------------
3235
3236void Setting::remove(unsigned int idx)
3237  throw(SettingTypeException, SettingNotFoundException)
3238{
3239  if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
3240    throw SettingTypeException(*this, idx);
3241
3242  if(! config_setting_remove_elem(_setting, idx))
3243    throw SettingNotFoundException(*this, idx);
3244}
3245
3246// ---------------------------------------------------------------------------
3247
3248Setting & Setting::add(const char *name, Setting::Type type)
3249  throw(SettingNameException, SettingTypeException)
3250{
3251  assertType(TypeGroup);
3252
3253  int typecode = __toTypeCode(type);
3254
3255  if(typecode == CONFIG_TYPE_NONE)
3256    throw SettingTypeException(*this, name);
3257
3258  config_setting_t *setting = config_setting_add(_setting, name, typecode);
3259
3260  if(! setting)
3261    throw SettingNameException(*this, name);
3262
3263  return(wrapSetting(setting));
3264}
3265
3266// ---------------------------------------------------------------------------
3267
3268Setting & Setting::add(Setting::Type type) throw(SettingTypeException)
3269{
3270  if((_type != TypeArray) && (_type != TypeList))
3271    throw SettingTypeException(*this);
3272
3273  if(_type == TypeArray)
3274  {
3275    int idx = getLength();
3276
3277    if(idx > 0)
3278    {
3279      Setting::Type atype = operator[](0).getType();
3280      if(type != atype)
3281        throw SettingTypeException(*this, idx);
3282    }
3283    else
3284    {
3285      if((type != TypeInt) && (type != TypeFloat) && (type != TypeString)
3286         && (type != TypeBoolean))
3287        throw SettingTypeException(*this, idx);
3288    }
3289  }
3290
3291  int typecode = __toTypeCode(type);
3292  config_setting_t *s = config_setting_add(_setting, NULL, typecode);
3293
3294  Setting &ns = wrapSetting(s);
3295
3296  switch(type)
3297  {
3298    case TypeInt:
3299      ns = 0;
3300      break;
3301
3302    case TypeInt64:
3303      ns = INT64_CONST(0);
3304      break;
3305
3306    case TypeFloat:
3307      ns = 0.0;
3308      break;
3309
3310    case TypeString:
3311      ns = (char *)NULL;
3312      break;
3313
3314    case TypeBoolean:
3315      ns = false;
3316      break;
3317
3318    default:
3319      // won't happen
3320      break;
3321  }
3322
3323  return(ns);
3324}
3325
3326// ---------------------------------------------------------------------------
3327
3328void Setting::assertType(Setting::Type type) const throw(SettingTypeException)
3329{
3330  if(type != _type)
3331  {
3332    if(!(isNumber() && config_get_auto_convert(_setting->config)
3333         && ((type == TypeInt) || (type == TypeFloat))))
3334      throw SettingTypeException(*this);
3335  }
3336}
3337
3338// ---------------------------------------------------------------------------
3339
3340Setting & Setting::wrapSetting(config_setting_t *s)
3341{
3342  Setting *setting = NULL;
3343
3344  void *hook = config_setting_get_hook(s);
3345  if(! hook)
3346  {
3347    setting = new Setting(s);
3348    config_setting_set_hook(s, reinterpret_cast<void *>(setting));
3349  }
3350  else
3351    setting = reinterpret_cast<Setting *>(hook);
3352
3353  return(*setting);
3354}
3355
3356// ---------------------------------------------------------------------------
3357
3358*/
3359
3360}; // namespace libconfig
3361
3362
3363/* ----------------------------------------------------------------------------
3364
3365   This file is a mex clone of libconfigcpp.cc originally found
3366   in the libconfig library which was desgigned by Mark A Lindner.
3367   
3368   ----------------------------------------------------------------------------
3369*/
3370
3371
3372#include "libconfig_mex.h"
3373
3374#ifdef _MSC_VER
3375#pragma warning (disable: 4996)
3376#endif
3377
3378//#include "wincompat.h"
3379
3380#include <cstring>
3381#include <cstdlib>
3382#include <sstream>
3383
3384namespace libconfig {
3385
3386        /*
3387// ---------------------------------------------------------------------------
3388
3389ParseException::ParseException(const char *file, int line, const char *error)
3390  : _file(strdup(file)), _line(line), _error(error)
3391{
3392}
3393
3394// ---------------------------------------------------------------------------
3395
3396ParseException::~ParseException() throw()
3397{
3398  free((void *)_file);
3399}
3400
3401// ---------------------------------------------------------------------------
3402
3403const char *ParseException::what() const throw()
3404{
3405  return("ParseException");
3406}
3407
3408// ---------------------------------------------------------------------------
3409
3410static int __toTypeCode(Setting::Type type)
3411{
3412  int typecode;
3413
3414  switch(type)
3415  {
3416    case Setting::TypeGroup:
3417      typecode = CONFIG_TYPE_GROUP;
3418      break;
3419
3420    case Setting::TypeInt:
3421      typecode = CONFIG_TYPE_INT;
3422      break;
3423
3424    case Setting::TypeInt64:
3425      typecode = CONFIG_TYPE_INT64;
3426      break;
3427
3428    case Setting::TypeFloat:
3429      typecode = CONFIG_TYPE_FLOAT;
3430      break;
3431
3432    case Setting::TypeString:
3433      typecode = CONFIG_TYPE_STRING;
3434      break;
3435
3436    case Setting::TypeBoolean:
3437      typecode = CONFIG_TYPE_BOOL;
3438      break;
3439
3440    case Setting::TypeArray:
3441      typecode = CONFIG_TYPE_ARRAY;
3442      break;
3443
3444    case Setting::TypeList:
3445      typecode = CONFIG_TYPE_LIST;
3446      break;
3447
3448    default:
3449      typecode = CONFIG_TYPE_NONE;
3450  }
3451
3452  return(typecode);
3453}
3454
3455// ---------------------------------------------------------------------------
3456
3457static void __constructPath(const Setting &setting,
3458                            std::stringstream &path)
3459{
3460  // head recursion to print path from root to target
3461
3462  if(! setting.isRoot())
3463  {
3464    __constructPath(setting.getParent(), path);
3465    if(path.tellp() > 0)
3466      path << '.';
3467
3468    const char *name = setting.getName();
3469    if(name)
3470      path << name;
3471    else
3472      path << '[' << setting.getIndex() << ']';
3473  }
3474}
3475
3476// ---------------------------------------------------------------------------
3477
3478SettingException::SettingException(const Setting &setting)
3479{
3480  std::stringstream sstr;
3481  __constructPath(setting, sstr);
3482
3483  _path = ::strdup(sstr.str().c_str());
3484}
3485
3486// ---------------------------------------------------------------------------
3487
3488SettingException::SettingException(const Setting &setting, int idx)
3489{
3490  std::stringstream sstr;
3491  __constructPath(setting, sstr);
3492  sstr << ".[" << idx << "]";
3493
3494  _path = ::strdup(sstr.str().c_str());
3495}
3496
3497// ---------------------------------------------------------------------------
3498
3499SettingException::SettingException(const Setting &setting, const char *name)
3500{
3501  std::stringstream sstr;
3502  __constructPath(setting, sstr);
3503  sstr << '.' << name;
3504
3505  _path = ::strdup(sstr.str().c_str());
3506}
3507
3508// ---------------------------------------------------------------------------
3509
3510SettingException::SettingException(const char *path)
3511{
3512  _path = ::strdup(path);
3513}
3514
3515// ---------------------------------------------------------------------------
3516
3517const char *SettingException::getPath() const
3518{
3519  return(_path);
3520}
3521
3522// ---------------------------------------------------------------------------
3523
3524SettingException::SettingException(const SettingException &other)
3525{
3526  _path = ::strdup(other._path);
3527}
3528
3529// ---------------------------------------------------------------------------
3530
3531SettingException &SettingException::operator=(const SettingException &other)
3532{
3533  ::free(_path);
3534  _path = ::strdup(other._path);
3535
3536  return(*this);
3537}
3538
3539// ---------------------------------------------------------------------------
3540
3541const char *SettingException::what() const throw()
3542{
3543  return("SettingException");
3544}
3545
3546// ---------------------------------------------------------------------------
3547
3548SettingException::~SettingException() throw()
3549{
3550  ::free(_path);
3551}
3552
3553// ---------------------------------------------------------------------------
3554
3555SettingTypeException::SettingTypeException(const Setting &setting)
3556  : SettingException(setting)
3557{
3558}
3559
3560// ---------------------------------------------------------------------------
3561
3562SettingTypeException::SettingTypeException(const Setting &setting, int idx)
3563  : SettingException(setting, idx)
3564{
3565}
3566
3567// ---------------------------------------------------------------------------
3568
3569SettingTypeException::SettingTypeException(const Setting &setting,
3570                                           const char *name)
3571  : SettingException(setting, name)
3572{
3573}
3574
3575// ---------------------------------------------------------------------------
3576
3577const char *SettingTypeException::what() const throw()
3578{
3579  return("SettingTypeException");
3580}
3581
3582// ---------------------------------------------------------------------------
3583
3584SettingNotFoundException::SettingNotFoundException(const Setting &setting,
3585                                                   int idx)
3586  : SettingException(setting, idx)
3587{
3588}
3589
3590// ---------------------------------------------------------------------------
3591
3592SettingNotFoundException::SettingNotFoundException(const Setting &setting,
3593                                                   const char *name)
3594  : SettingException(setting, name)
3595{
3596}
3597
3598// ---------------------------------------------------------------------------
3599
3600SettingNotFoundException::SettingNotFoundException(const char *path)
3601  : SettingException(path)
3602{
3603}
3604
3605// ---------------------------------------------------------------------------
3606
3607const char *SettingNotFoundException::what() const throw()
3608{
3609  return("SettingNotFoundException");
3610}
3611
3612// ---------------------------------------------------------------------------
3613
3614SettingNameException::SettingNameException(const Setting &setting,
3615                                           const char *name)
3616  : SettingException(setting, name)
3617{
3618}
3619
3620// ---------------------------------------------------------------------------
3621
3622const char *SettingNameException::what() const throw()
3623{
3624  return("SettingNameException");
3625}
3626
3627// ---------------------------------------------------------------------------
3628
3629const char *FileIOException::what() const throw()
3630{
3631  return("FileIOException");
3632}
3633
3634// ---------------------------------------------------------------------------
3635
3636void Config::ConfigDestructor(void *arg)
3637{
3638  delete reinterpret_cast<Setting *>(arg);
3639}
3640
3641// ---------------------------------------------------------------------------
3642
3643Config::Config()
3644{
3645  _config = new config_t;
3646  config_init(_config);
3647  config_set_destructor(_config, ConfigDestructor);
3648}
3649
3650// ---------------------------------------------------------------------------
3651
3652Config::~Config()
3653{
3654  config_destroy(_config);
3655  delete _config;
3656}
3657
3658// ---------------------------------------------------------------------------
3659
3660void Config::setAutoConvert(bool flag)
3661{
3662  config_set_auto_convert(_config, (flag ? CONFIG_TRUE : CONFIG_FALSE));
3663}
3664
3665// ---------------------------------------------------------------------------
3666
3667bool Config::getAutoConvert() const
3668{
3669  return(config_get_auto_convert(_config) != CONFIG_FALSE);
3670}
3671
3672// ---------------------------------------------------------------------------
3673
3674void Config::setTabWidth(unsigned short width) throw()
3675{
3676  config_set_tab_width(_config, width);
3677}
3678
3679// ---------------------------------------------------------------------------
3680
3681unsigned short Config::getTabWidth() const throw()
3682{
3683  return(config_get_tab_width(_config));
3684}
3685
3686// ---------------------------------------------------------------------------
3687
3688void Config::handleError() const
3689{
3690  switch(config_error_type(_config))
3691  {
3692    case CONFIG_ERR_NONE:
3693      break;
3694   
3695    case CONFIG_ERR_PARSE:
3696      throw ParseException(config_error_file(_config),
3697                           config_error_line(_config),
3698                           config_error_text(_config));
3699      break;
3700
3701    case CONFIG_ERR_FILE_IO:
3702    default:
3703      throw FileIOException();
3704  }
3705}
3706
3707// ---------------------------------------------------------------------------
3708
3709void Config::read(FILE *stream) throw(ParseException)
3710{
3711  if(! config_read(_config, stream))
3712    handleError();
3713}
3714
3715// ---------------------------------------------------------------------------
3716
3717void Config::readString(const char *str) throw(ParseException)
3718{
3719  if(! config_read_string(_config, str))
3720    handleError();
3721}
3722
3723// ---------------------------------------------------------------------------
3724
3725void Config::write(FILE *stream) const
3726{
3727  config_write(_config, stream);
3728}
3729
3730// ---------------------------------------------------------------------------
3731
3732void Config::readFile(const char *filename) throw(FileIOException,
3733                                                  ParseException)
3734{
3735  if(! config_read_file(_config, filename))
3736    handleError();
3737}
3738
3739// ---------------------------------------------------------------------------
3740
3741void Config::writeFile(const char *filename) throw(FileIOException)
3742{
3743  if(! config_write_file(_config, filename))
3744    handleError();
3745}
3746
3747// ---------------------------------------------------------------------------
3748
3749Setting & Config::lookup(const char *path) const
3750  throw(SettingNotFoundException)
3751{
3752  config_setting_t *s = config_lookup(_config, path);
3753  if(! s)
3754    throw SettingNotFoundException(path);
3755
3756  return(Setting::wrapSetting(s));
3757}
3758
3759// ---------------------------------------------------------------------------
3760
3761bool Config::exists(const char *path) const throw()
3762{
3763  config_setting_t *s = config_lookup(_config, path);
3764
3765  return(s != NULL);
3766}
3767
3768// ---------------------------------------------------------------------------
3769
3770#define CONFIG_LOOKUP_NO_EXCEPTIONS(P, T, V)    \
3771  try                                           \
3772  {                                             \
3773    Setting &s = lookup(P);                     \
3774    V = (T)s;                                   \
3775    return(true);                               \
3776  }                                             \
3777  catch(ConfigException)                        \
3778  {                                             \
3779    return(false);                              \
3780  }
3781
3782// ---------------------------------------------------------------------------
3783
3784bool Config::lookupValue(const char *path, bool &value) const throw()
3785{
3786  CONFIG_LOOKUP_NO_EXCEPTIONS(path, bool, value);
3787}
3788
3789// ---------------------------------------------------------------------------
3790
3791bool Config::lookupValue(const char *path, int &value) const throw()
3792{
3793  CONFIG_LOOKUP_NO_EXCEPTIONS(path, int, value);
3794}
3795
3796// ---------------------------------------------------------------------------
3797
3798bool Config::lookupValue(const char *path, unsigned int &value) const throw()
3799{
3800  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned int, value);
3801}
3802
3803// ---------------------------------------------------------------------------
3804
3805bool Config::lookupValue(const char *path, long long &value) const throw()
3806{
3807  CONFIG_LOOKUP_NO_EXCEPTIONS(path, long long, value);
3808}
3809
3810// ---------------------------------------------------------------------------
3811
3812bool Config::lookupValue(const char *path, unsigned long long &value)
3813  const throw()
3814{
3815  CONFIG_LOOKUP_NO_EXCEPTIONS(path, unsigned long long, value);
3816}
3817
3818// ---------------------------------------------------------------------------
3819
3820bool Config::lookupValue(const char *path, double &value) const throw()
3821{
3822  CONFIG_LOOKUP_NO_EXCEPTIONS(path, double, value);
3823}
3824
3825// ---------------------------------------------------------------------------
3826
3827bool Config::lookupValue(const char *path, float &value) const throw()
3828{
3829  CONFIG_LOOKUP_NO_EXCEPTIONS(path, float, value);
3830}
3831
3832// ---------------------------------------------------------------------------
3833
3834bool Config::lookupValue(const char *path, const char *&value) const throw()
3835{
3836  CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
3837}
3838
3839// ---------------------------------------------------------------------------
3840
3841bool Config::lookupValue(const char *path, std::string &value) const throw()
3842{
3843  CONFIG_LOOKUP_NO_EXCEPTIONS(path, const char *, value);
3844}
3845
3846// ---------------------------------------------------------------------------
3847
3848Setting & Config::getRoot() const
3849{
3850  return(Setting::wrapSetting(config_root_setting(_config)));
3851}
3852
3853// ---------------------------------------------------------------------------
3854
3855Setting::Setting(config_setting_t *setting)
3856  : _setting(setting)
3857{
3858  switch(config_setting_type(setting))
3859  {
3860    case CONFIG_TYPE_GROUP:
3861      _type = TypeGroup;
3862      break;
3863
3864    case CONFIG_TYPE_INT:
3865      _type = TypeInt;
3866      break;
3867
3868    case CONFIG_TYPE_INT64:
3869      _type = TypeInt64;
3870      break;
3871
3872    case CONFIG_TYPE_FLOAT:
3873      _type = TypeFloat;
3874      break;
3875
3876    case CONFIG_TYPE_STRING:
3877      _type = TypeString;
3878      break;
3879
3880    case CONFIG_TYPE_BOOL:
3881      _type = TypeBoolean;
3882      break;
3883
3884    case CONFIG_TYPE_ARRAY:
3885      _type = TypeArray;
3886      break;
3887
3888    case CONFIG_TYPE_LIST:
3889      _type = TypeList;
3890      break;
3891
3892    case CONFIG_TYPE_NONE:
3893    default:
3894      _type = TypeNone;
3895      break;
3896  }
3897
3898  switch(config_setting_get_format(setting))
3899  {
3900    case CONFIG_FORMAT_HEX:
3901      _format = FormatHex;
3902      break;
3903
3904    case CONFIG_FORMAT_DEFAULT:
3905    default:
3906      _format = FormatDefault;
3907      break;
3908  }
3909}
3910
3911// ---------------------------------------------------------------------------
3912
3913Setting::~Setting() throw()
3914{
3915  _setting = NULL;
3916}
3917
3918// ---------------------------------------------------------------------------
3919
3920void Setting::setFormat(Format format) throw()
3921{
3922  if((_type == TypeInt) || (_type == TypeInt64))
3923  {
3924    if(format == FormatHex)
3925      _format = FormatHex;
3926    else
3927      _format = FormatDefault;
3928  }
3929  else
3930    _format = FormatDefault;
3931
3932  config_setting_set_format(_setting, static_cast<short>(_format));
3933}
3934
3935// ---------------------------------------------------------------------------
3936
3937Setting::operator bool() const throw(SettingTypeException)
3938{
3939  assertType(TypeBoolean);
3940
3941  return(config_setting_get_bool(_setting) ? true : false);
3942}
3943
3944// ---------------------------------------------------------------------------
3945
3946Setting::operator int() const throw(SettingTypeException)
3947{
3948  assertType(TypeInt);
3949
3950  return(config_setting_get_int(_setting));
3951}
3952
3953// ---------------------------------------------------------------------------
3954
3955Setting::operator unsigned int() const throw(SettingTypeException)
3956{
3957  assertType(TypeInt);
3958
3959  int v = config_setting_get_int(_setting);
3960
3961  if(v < 0)
3962    v = 0;
3963
3964  return(static_cast<unsigned int>(v));
3965}
3966
3967// ---------------------------------------------------------------------------
3968
3969Setting::operator long() const throw(SettingTypeException)
3970{
3971  if(sizeof(long) == sizeof(long long))
3972    return operator long long();
3973  else
3974    return operator int();
3975}
3976
3977// ---------------------------------------------------------------------------
3978
3979Setting::operator unsigned long() const throw(SettingTypeException)
3980{
3981  if(sizeof(long) == sizeof(long long))
3982    return operator unsigned long long();
3983  else
3984    return operator unsigned int();
3985}
3986
3987// ---------------------------------------------------------------------------
3988
3989Setting::operator long long() const throw(SettingTypeException)
3990{
3991  assertType(TypeInt64);
3992
3993  return(config_setting_get_int64(_setting));
3994}
3995
3996// ---------------------------------------------------------------------------
3997
3998Setting::operator unsigned long long() const throw(SettingTypeException)
3999{
4000  assertType(TypeInt64);
4001
4002  long long v = config_setting_get_int64(_setting);
4003
4004  if(v < INT64_CONST(0))
4005    v = INT64_CONST(0);
4006
4007  return(static_cast<unsigned long long>(v));
4008}
4009
4010// ---------------------------------------------------------------------------
4011
4012Setting::operator double() const throw(SettingTypeException)
4013{
4014  assertType(TypeFloat);
4015
4016  return(config_setting_get_float(_setting));
4017}
4018
4019// ---------------------------------------------------------------------------
4020
4021Setting::operator float() const throw(SettingTypeException)
4022{
4023  assertType(TypeFloat);
4024
4025  // may cause loss of precision:
4026  return(static_cast<float>(config_setting_get_float(_setting)));
4027}
4028
4029// ---------------------------------------------------------------------------
4030
4031Setting::operator const char *() const throw(SettingTypeException)
4032{
4033  assertType(TypeString);
4034
4035  return(config_setting_get_string(_setting));
4036}
4037
4038// ---------------------------------------------------------------------------
4039
4040Setting::operator std::string() const throw(SettingTypeException)
4041{
4042  assertType(TypeString);
4043
4044  const char *s = config_setting_get_string(_setting);
4045
4046  std::string str;
4047  if(s)
4048    str = s;
4049
4050  return(str);
4051}
4052
4053// ---------------------------------------------------------------------------
4054
4055Setting & Setting::operator=(bool value) throw(SettingTypeException)
4056{
4057  assertType(TypeBoolean);
4058
4059  config_setting_set_bool(_setting, value);
4060
4061  return(*this);
4062}
4063
4064// ---------------------------------------------------------------------------
4065
4066Setting & Setting::operator=(int value) throw(SettingTypeException)
4067{
4068  assertType(TypeInt);
4069
4070  config_setting_set_int(_setting, value);
4071
4072  return(*this);
4073}
4074
4075// ---------------------------------------------------------------------------
4076
4077Setting & Setting::operator=(long value) throw(SettingTypeException)
4078{
4079  if(sizeof(long) == sizeof(long long))
4080    return(operator=(static_cast<long long>(value)));
4081  else
4082    return(operator=(static_cast<int>(value)));
4083}
4084
4085// ---------------------------------------------------------------------------
4086
4087Setting & Setting::operator=(const long long &value)
4088  throw(SettingTypeException)
4089{
4090  assertType(TypeInt64);
4091
4092  config_setting_set_int64(_setting, value);
4093
4094  return(*this);
4095}
4096
4097// ---------------------------------------------------------------------------
4098
4099Setting & Setting::operator=(const double &value) throw(SettingTypeException)
4100{
4101  assertType(TypeFloat);
4102
4103  config_setting_set_float(_setting, value);
4104
4105  return(*this);
4106}
4107
4108// ---------------------------------------------------------------------------
4109
4110Setting & Setting::operator=(float value) throw(SettingTypeException)
4111{
4112  assertType(TypeFloat);
4113
4114  double cvalue = static_cast<double>(value);
4115
4116  config_setting_set_float(_setting, cvalue);
4117
4118  return(*this);
4119}
4120
4121// ---------------------------------------------------------------------------
4122
4123Setting & Setting::operator=(const char *value) throw(SettingTypeException)
4124{
4125  assertType(TypeString);
4126
4127  config_setting_set_string(_setting, value);
4128
4129  return(*this);
4130}
4131
4132// ---------------------------------------------------------------------------
4133
4134Setting & Setting::operator=(const std::string &value)
4135  throw(SettingTypeException)
4136{
4137  assertType(TypeString);
4138
4139  config_setting_set_string(_setting, value.c_str());
4140
4141  return(*this);
4142}
4143
4144// ---------------------------------------------------------------------------
4145
4146Setting & Setting::operator[](int i) const
4147  throw(SettingTypeException, SettingNotFoundException)
4148{
4149  if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
4150    throw SettingTypeException(*this, i);
4151
4152  config_setting_t *setting = config_setting_get_elem(_setting, i);
4153
4154  if(! setting)
4155    throw SettingNotFoundException(*this, i);
4156
4157  return(wrapSetting(setting));
4158}
4159
4160// ---------------------------------------------------------------------------
4161
4162Setting & Setting::operator[](const char *key) const
4163  throw(SettingTypeException, SettingNotFoundException)
4164{
4165  assertType(TypeGroup);
4166
4167  config_setting_t *setting = config_setting_get_member(_setting, key);
4168
4169  if(! setting)
4170    throw SettingNotFoundException(*this, key);
4171
4172  return(wrapSetting(setting));
4173}
4174
4175// ---------------------------------------------------------------------------
4176
4177#define SETTING_LOOKUP_NO_EXCEPTIONS(K, T, V)   \
4178  try                                           \
4179  {                                             \
4180    Setting &s = operator[](K);                 \
4181    V = (T)s;                                   \
4182    return(true);                               \
4183  }                                             \
4184  catch(ConfigException)                        \
4185  {                                             \
4186    return(false);                              \
4187  }
4188
4189// ---------------------------------------------------------------------------
4190
4191bool Setting::lookupValue(const char *name, bool &value) const throw()
4192{
4193  SETTING_LOOKUP_NO_EXCEPTIONS(name, bool, value);
4194}
4195
4196// ---------------------------------------------------------------------------
4197
4198bool Setting::lookupValue(const char *name, int &value) const throw()
4199{
4200  SETTING_LOOKUP_NO_EXCEPTIONS(name, int, value);
4201}
4202
4203// ---------------------------------------------------------------------------
4204
4205bool Setting::lookupValue(const char *name, unsigned int &value)
4206  const throw()
4207{
4208  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned int, value);
4209}
4210
4211// ---------------------------------------------------------------------------
4212
4213bool Setting::lookupValue(const char *name, long long &value) const throw()
4214{
4215  SETTING_LOOKUP_NO_EXCEPTIONS(name, long long, value);
4216}
4217
4218// ---------------------------------------------------------------------------
4219
4220bool Setting::lookupValue(const char *name, unsigned long long &value)
4221  const throw()
4222{
4223  SETTING_LOOKUP_NO_EXCEPTIONS(name, unsigned long long, value);
4224}
4225
4226// ---------------------------------------------------------------------------
4227
4228bool Setting::lookupValue(const char *name, double &value) const throw()
4229{
4230  SETTING_LOOKUP_NO_EXCEPTIONS(name, double, value);
4231}
4232
4233// ---------------------------------------------------------------------------
4234
4235bool Setting::lookupValue(const char *name, float &value) const throw()
4236{
4237  SETTING_LOOKUP_NO_EXCEPTIONS(name, float, value);
4238}
4239
4240// ---------------------------------------------------------------------------
4241
4242bool Setting::lookupValue(const char *name, const char *&value) const throw()
4243{
4244  SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
4245}
4246
4247// ---------------------------------------------------------------------------
4248
4249bool Setting::lookupValue(const char *name, std::string &value) const throw()
4250{
4251  SETTING_LOOKUP_NO_EXCEPTIONS(name, const char *, value);
4252}
4253
4254// ---------------------------------------------------------------------------
4255
4256bool Setting::exists(const char *name) const throw()
4257{
4258  if(_type != TypeGroup)
4259    return(false);
4260
4261  config_setting_t *setting = config_setting_get_member(_setting, name);
4262
4263  return(setting != NULL);
4264}
4265
4266// ---------------------------------------------------------------------------
4267
4268int Setting::getLength() const throw()
4269{
4270  return(config_setting_length(_setting));
4271}
4272
4273// ---------------------------------------------------------------------------
4274
4275const char * Setting::getName() const throw()
4276{
4277  return(config_setting_name(_setting));
4278}
4279
4280// ---------------------------------------------------------------------------
4281
4282std::string Setting::getPath() const
4283{
4284  std::stringstream path;
4285
4286  __constructPath(*this, path);
4287
4288  return(path.str());
4289}
4290
4291// ---------------------------------------------------------------------------
4292
4293const Setting & Setting::getParent() const throw(SettingNotFoundException)
4294{
4295  config_setting_t *setting = config_setting_parent(_setting);
4296
4297  if(! setting)
4298    throw SettingNotFoundException(NULL);
4299
4300  return(wrapSetting(setting));
4301}
4302
4303// ---------------------------------------------------------------------------
4304
4305Setting & Setting::getParent() throw(SettingNotFoundException)
4306{
4307  config_setting_t *setting = config_setting_parent(_setting);
4308
4309  if(! setting)
4310    throw SettingNotFoundException(NULL);
4311
4312  return(wrapSetting(setting));
4313}
4314
4315// ---------------------------------------------------------------------------
4316
4317unsigned int Setting::getSourceLine() const throw()
4318{
4319  return(config_setting_source_line(_setting));
4320}
4321
4322// ---------------------------------------------------------------------------
4323
4324const char *Setting::getSourceFile() const throw()
4325{
4326  return(config_setting_source_file(_setting));
4327}
4328
4329// ---------------------------------------------------------------------------
4330
4331bool Setting::isRoot() const throw()
4332{
4333  return(config_setting_is_root(_setting));
4334}
4335
4336// ---------------------------------------------------------------------------
4337
4338int Setting::getIndex() const throw()
4339{
4340  return(config_setting_index(_setting));
4341}
4342
4343// ---------------------------------------------------------------------------
4344
4345void Setting::remove(const char *name)
4346  throw(SettingTypeException, SettingNotFoundException)
4347{
4348  assertType(TypeGroup);
4349
4350  if(! config_setting_remove(_setting, name))
4351    throw SettingNotFoundException(*this, name);
4352}
4353
4354// ---------------------------------------------------------------------------
4355
4356void Setting::remove(unsigned int idx)
4357  throw(SettingTypeException, SettingNotFoundException)
4358{
4359  if((_type != TypeArray) && (_type != TypeGroup) && (_type != TypeList))
4360    throw SettingTypeException(*this, idx);
4361
4362  if(! config_setting_remove_elem(_setting, idx))
4363    throw SettingNotFoundException(*this, idx);
4364}
4365
4366// ---------------------------------------------------------------------------
4367
4368Setting & Setting::add(const char *name, Setting::Type type)
4369  throw(SettingNameException, SettingTypeException)
4370{
4371  assertType(TypeGroup);
4372
4373  int typecode = __toTypeCode(type);
4374
4375  if(typecode == CONFIG_TYPE_NONE)
4376    throw SettingTypeException(*this, name);
4377
4378  config_setting_t *setting = config_setting_add(_setting, name, typecode);
4379
4380  if(! setting)
4381    throw SettingNameException(*this, name);
4382
4383  return(wrapSetting(setting));
4384}
4385
4386// ---------------------------------------------------------------------------
4387
4388Setting & Setting::add(Setting::Type type) throw(SettingTypeException)
4389{
4390  if((_type != TypeArray) && (_type != TypeList))
4391    throw SettingTypeException(*this);
4392
4393  if(_type == TypeArray)
4394  {
4395    int idx = getLength();
4396
4397    if(idx > 0)
4398    {
4399      Setting::Type atype = operator[](0).getType();
4400      if(type != atype)
4401        throw SettingTypeException(*this, idx);
4402    }
4403    else
4404    {
4405      if((type != TypeInt) && (type != TypeFloat) && (type != TypeString)
4406         && (type != TypeBoolean))
4407        throw SettingTypeException(*this, idx);
4408    }
4409  }
4410
4411  int typecode = __toTypeCode(type);
4412  config_setting_t *s = config_setting_add(_setting, NULL, typecode);
4413
4414  Setting &ns = wrapSetting(s);
4415
4416  switch(type)
4417  {
4418    case TypeInt:
4419      ns = 0;
4420      break;
4421
4422    case TypeInt64:
4423      ns = INT64_CONST(0);
4424      break;
4425
4426    case TypeFloat:
4427      ns = 0.0;
4428      break;
4429
4430    case TypeString:
4431      ns = (char *)NULL;
4432      break;
4433
4434    case TypeBoolean:
4435      ns = false;
4436      break;
4437
4438    default:
4439      // won't happen
4440      break;
4441  }
4442
4443  return(ns);
4444}
4445
4446// ---------------------------------------------------------------------------
4447
4448void Setting::assertType(Setting::Type type) const throw(SettingTypeException)
4449{
4450  if(type != _type)
4451  {
4452    if(!(isNumber() && config_get_auto_convert(_setting->config)
4453         && ((type == TypeInt) || (type == TypeFloat))))
4454      throw SettingTypeException(*this);
4455  }
4456}
4457
4458// ---------------------------------------------------------------------------
4459
4460Setting & Setting::wrapSetting(config_setting_t *s)
4461{
4462  Setting *setting = NULL;
4463
4464  void *hook = config_setting_get_hook(s);
4465  if(! hook)
4466  {
4467    setting = new Setting(s);
4468    config_setting_set_hook(s, reinterpret_cast<void *>(setting));
4469  }
4470  else
4471    setting = reinterpret_cast<Setting *>(hook);
4472
4473  return(*setting);
4474}
4475
4476// ---------------------------------------------------------------------------
4477
4478*/
4479
4480}; // namespace libconfig
4481
Note: See TracBrowser for help on using the browser.