AttributeTree.cpp
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 // This file is part of FZIs ic_workspace.
5 //
6 // This program is free software licensed under the LGPL
7 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
8 // You can find a copy of this license in LICENSE folder in the top
9 // directory of the source code.
10 //
11 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
12 //
13 // -- END LICENSE BLOCK ------------------------------------------------
14 
15 //----------------------------------------------------------------------
23 //----------------------------------------------------------------------
24 #include <assert.h>
25 #include <ctype.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #ifdef _SYSTEM_WIN32_
31 #include <direct.h>
32 #endif
33 
34 #include "icl_core/os_string.h"
36 
37 using namespace std;
38 
39 #define LOCAL_PRINTF printf
40 
41 namespace icl_core {
42 namespace config {
43 
44 #ifdef _SYSTEM_WIN32_
45 const char DSEP = '\\';
46 const char DSEP_OTHER = '/';
47 #else
48 const char DSEP = '/';
49 const char DSEP_OTHER = '\\';
50 #endif
51 
52 const char *comment_end_str = "}_COMMENT_";
53 const char *comment_str = comment_end_str + 1;
54 const char *include_str = "_INCLUDE_";
55 const char *AttributeTree::m_file_path_str = "_ATTRIBUTE_TREE_FILE_PATH_";
56 const char *AttributeTree::m_file_name_str = "_ATTRIBUTE_TREE_FILE_NAME_";
59 const int INCLUDE_OFFSET = 10;
60 
61 static char buffer[2000];
62 
63 void readNextLineInBuffer(istream &in)
64 {
65  in.getline(buffer, 1998);
66  // Window/Unix
67  int line_length=strlen(buffer);
68  if (line_length > 0 && buffer[line_length-1]=='\r')
69  {
70  buffer[line_length-1]=0;
71  }
72 }
73 
74 // ===============================================================
75 // FilePath
76 // ===============================================================
77 
78 icl_core::String FilePath::absolutePath(const icl_core::String& filename) const
79 {
80  if (isRelativePath(filename))
81  {
82  return normalizePath(currentDir() + DSEP + filename);
83  }
84  else
85  {
86  return normalizePath(filename);
87  }
88 }
89 
90 bool FilePath::isRelativePath(const icl_core::String& filename)
91 {
92  if (filename.empty())
93  {
94  return true;
95  }
96 #ifdef _SYSTEM_WIN32_
97  //directory??
98  return (filename.length() < 2 || filename[1] != ':');
99 #else
100  return filename[0] != DSEP;
101 #endif
102 }
103 
104 icl_core::String FilePath::normalizePath(const icl_core::String& _filename)
105 {
106  if (_filename.empty())
107  {
108  return _filename;
109  }
110  string filename(_filename);
111 
112  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::normalizePath(%s)\n", filename.c_str());
113 
114  // Replace directory separators.
115  string::size_type slash_before_dot;
116  string::size_type dot_start = 0;
117 
118  dot_start = filename.find(DSEP_OTHER, 0);
119  while (dot_start != string::npos)
120  {
121  filename[dot_start] = DSEP;
122 
123  dot_start = filename.find(DSEP_OTHER, dot_start);
124  }
125  dot_start = 0;
126 
127  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::normalizePath>> status '%s'\n", filename.c_str());
128 
129  // Search for single dots at the beginning.
130  while (!filename.find(string(".") + DSEP))
131  {
132  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::normalizePath>> SingleDots at begin '%s'\n",
133  // filename.c_str());
134  string temp_filename(filename, 2, string::npos);
135  temp_filename.swap(filename);
136  }
137 #ifdef _SYSTEM_WIN32_
138  // Search for single dots after the drive letter at the beginning.
139  if (filename.find(string(":.") + DSEP) == 1)
140  {
141  string temp_filename;
142  temp_filename.append(filename, 0, 2);
143  dot_start += 3;
144  temp_filename.append(filename, dot_start, filename.length() - dot_start);
145  temp_filename.swap(filename);
146  dot_start = 0;
147  }
148 #endif
149  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::normalizePath>> status '%s'\n", filename.c_str());
150 
151  // Search for single dots inside.
152  dot_start = filename.find(string(1, DSEP) + "." + DSEP, 0);
153  while (dot_start != string::npos)
154  {
155  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::normalizePath>> SingleDots inside '%s'\n",
156  // filename.c_str());
157  string temp_filename(filename, 0, dot_start);
158  temp_filename.append(filename, dot_start + 2, filename.length() - dot_start - 2);
159  temp_filename.swap(filename);
160 
161  dot_start = filename.find(string(1, DSEP) + "." + DSEP, dot_start);
162  }
163  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::normalizePath>> status '%s'\n", filename.c_str());
164 
165  // Search for double dots.
166  dot_start = filename.find(string(1, DSEP) + ".." + DSEP, 0);
167  while (dot_start != string::npos)
168  {
169  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::normalizePath>> DoubleDots '%s' found at %i\n",
170  // filename.c_str(), dot_start);
171 
172  // Check if we can shorten the path.
173  slash_before_dot = filename.rfind(DSEP, dot_start - 1);
174  if (slash_before_dot != string::npos)
175  {
176  // OK to shorten?
177  if (filename[slash_before_dot+1] != DSEP && filename[slash_before_dot+1] != '.' &&
178  (slash_before_dot >= 1) ? filename[slash_before_dot-1] != ':' : 1)
179  {
180  dot_start += 3;
181  string temp_filename(filename, 0, slash_before_dot);
182  temp_filename.append(filename, dot_start, filename.length() - dot_start);
183  temp_filename.swap(filename);
184  }
185  else
186  {
187  break;
188  }
189 
190  dot_start = slash_before_dot;
191  }
192  else if (dot_start > 0)
193  {
194  string temp_filename;
195 
196 #ifdef _SYSTEM_WIN32_
197  // Add drive letter?
198  if (filename[1] = ':')
199  {
200  temp_filename.append(filename, 0, 2);
201  }
202 #endif
203  // Really??
204  dot_start += 2;
205  temp_filename.append(filename, dot_start, filename.length() - dot_start);
206  temp_filename.swap(filename);
207  dot_start = 0;
208  }
209  else
210  {
211  break;
212  }
213 
214  dot_start = filename.find(string(1, DSEP) + ".." + DSEP, dot_start);
215  }
216  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::normalizePath>> status '%s'\n", filename.c_str());
217  // Search again for single dots at the beginning.
218  while (!filename.find(string(".") + DSEP))
219  {
220  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::normalizePath>> SingleDots at begin '%s'\n",
221  // filename.c_str());
222  string temp_filename(filename, 2, string::npos);
223  temp_filename.swap(filename);
224  }
225 #ifdef _SYSTEM_WIN32_
226  dot_start = 0;
227  // Search again for single dots after the drive letter at the
228  // beginning.
229  if ((filename.find(string(":.") + DSEP) == 1))
230  {
231  string temp_filename;
232  temp_filename.append(filename, 0, 2);
233  dot_start += 3;
234  temp_filename.append(filename, dot_start, filename.length() - dot_start);
235  temp_filename.swap(filename);
236  dot_start = 0;
237  }
238 #endif
239  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::normalizePath>> Return '%s'\n", filename.c_str());
240  return filename;
241 }
242 
243 icl_core::String FilePath::exchangeSeparators(const icl_core::String& _filename)
244 {
245  if (_filename.empty())
246  {
247  return _filename;
248  }
249  string filename(_filename);
250 
251  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::exchangeSeparators(%s)\n", filename.c_str());
252 
253  for (unsigned i = 0;i < filename.length();++i)
254  {
255  if (filename[i] == DSEP_OTHER)
256  {
257  filename[i] = DSEP;
258  }
259  }
260 
261  return filename;
262 }
263 
264 icl_core::String FilePath::getEnvironment(const icl_core::String& var_name)
265 {
266  const char* get_env = getenv(var_name.c_str());
267  if (get_env == NULL)
268  {
269  return var_name;
270  }
271  else
272  {
273  return string(get_env);
274  }
275 }
276 
277 icl_core::String FilePath::replaceEnvironment(const icl_core::String& _filename)
278 {
279  if (_filename.empty())
280  {
281  return _filename;
282  }
283  string filename(_filename);
284 
285  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::replaceEnvironment(%s)\n", filename.c_str());
286 
287  string::size_type dot_start = filename.find("${");
288  while (dot_start != string::npos)
289  {
290  dot_start += 2;
291  string::size_type dot_end = filename.find("}", dot_start);
292  if (dot_end == string::npos)
293  {
294  printf("tFilePath::replaceEnvironment(%s)>> Failure on matching closing bracket "
295  "'}' in substring '%s'\n", (const char*) _filename.c_str(),
296  (const char*) string(filename, dot_start, string::npos).c_str());
297  return _filename;
298  }
299  string var_name(filename, dot_start, dot_end - dot_start);
300  string temp_filename(filename, 0, dot_start - 2);
301  temp_filename += getEnvironment(var_name);
302  temp_filename += string(filename, dot_end + 1, string::npos);
303  filename.swap(temp_filename);
304 
305  dot_start = filename.find("${");
306  }
307 
308  //DEBUGMSG(DD_SYSTEM, DL_VERBOSE, "FilePath::replaceEnvironment(%s) done (%s)\n",
309  // _filename.c_str(), filename.c_str());
310  return filename;
311 }
312 
313 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
314 
318  icl_core::String FilePath::Path() const
319  {
320  return path();
321  }
322 
326  icl_core::String FilePath::Name() const
327  {
328  return name();
329  }
330 
334  icl_core::String FilePath::AbsoluteName() const
335  {
336  return absoluteName();
337  }
338 
342  icl_core::String FilePath::CurrentDir() const
343  {
344  return currentDir();
345  }
346 
350  icl_core::String FilePath::Extension() const
351  {
352  return extension();
353  }
354 
358  icl_core::String FilePath::AbsolutePath(const icl_core::String& filename) const
359  {
360  return absolutePath(filename);
361  }
362 
366  bool FilePath::IsRelativePath(const icl_core::String& filename)
367  {
368  return isRelativePath(filename);
369  }
370 
374  bool FilePath::IsRelativePath() const
375  {
376  return isRelativePath();
377  }
378 
382  icl_core::String FilePath::NormalizePath(const icl_core::String& filename)
383  {
384  return normalizePath(filename);
385  }
386 
392  icl_core::String FilePath::ExchangeSeparators(const icl_core::String& filename)
393  {
394  return exchangeSeparators(filename);
395  }
396 
400  icl_core::String FilePath::GetEnvironment(const icl_core::String& var_name)
401  {
402  return getEnvironment(var_name);
403  }
404 
408  icl_core::String FilePath::ReplaceEnvironment(const icl_core::String& filename)
409  {
410  return replaceEnvironment(filename);
411  }
412 
413 #endif
414 
416 
417 void FilePath::init(const char* filename)
418 {
419  // Get the current directory.
420 #ifdef _SYSTEM_WIN32_
421  {
422  char* buffer = new char[1000];
423  if (_getcwd(buffer, 1000) != NULL)
424  {
425  buffer[999] = 0; // Safety precaution
426  m_pwd = buffer;
427  }
428  else
429  {
430  m_pwd = "";
431  }
432  delete[] buffer;
433  }
434 #else
435  char* tmp;
436  tmp = getenv("PWD");
437  if (tmp != NULL)
438  {
439  m_pwd = tmp;
440  }
441  else
442  {
443  m_pwd = "";
444  }
445 #endif
446  m_pwd = normalizePath(m_pwd);
447 
448  m_file = normalizePath(absolutePath(exchangeSeparators(string(filename))));
449 
450  // Search the last directory.
451  string::size_type last_directory_separator = m_file.rfind(DSEP);
452  if (last_directory_separator < m_file.length())
453  {
454  m_file_path_name_split = last_directory_separator + 1;
455  }
456  // Didn't find anything?
457  else
458  {
459  m_file_path_name_split = 0;
460  }
461 
462  m_file_name_extension_split = m_file.rfind('.');
463 }
464 
465 
466 // ===============================================================
467 // SubTreeList
468 // ===============================================================
469 SubTreeList::SubTreeList(AttributeTree *sub_tree, SubTreeList *next)
470  : m_next(next),
471  m_sub_tree(sub_tree)
472 {
473 }
474 
476 {
477  if (m_sub_tree)
478  {
479  // parent auf 0 damit unlink nicht wieder diesen Destruktor aufruft (cycle!)
480  m_sub_tree->m_parent = 0;
481  delete m_sub_tree;
482  }
483  delete m_next;
484 }
485 
487 {
488  assert(parent != NULL
489  && "SubTreeList::copy() called with NULL parent! Allocated attribute tree would be lost!");
490 
491  SubTreeList *loop = this;
492  while (loop)
493  {
494  new AttributeTree(*loop->m_sub_tree, parent);
495  loop = loop->m_next;
496  }
497 }
498 
500 {
501  SubTreeList *loop = this;
502  while (loop)
503  {
504  if (loop->m_sub_tree)
505  {
506  loop->m_sub_tree->m_parent = 0;
507  }
508  loop = loop->m_next;
509  }
510 }
511 
512 void SubTreeList::unlink(AttributeTree *obsolete_tree)
513 {
514  SubTreeList *loop = this;
515  SubTreeList *prev = 0;
516  while (loop)
517  {
518  if (loop->m_sub_tree == obsolete_tree)
519  {
520  if (prev)
521  {
522  prev->m_next = loop->m_next;
523  }
524  loop->m_next = 0;
525  loop->m_sub_tree = 0;
526  delete loop;
527  return;
528  }
529  prev = loop;
530  loop = loop->m_next;
531  }
532  // nicht gefunden? Dann machen wir gar nichts!
533 }
534 
535 AttributeTree* SubTreeList::subTree(const char *description)
536 {
537  SubTreeList *loop = this;
538  while (loop)
539  {
540  if (loop->m_sub_tree && loop->m_sub_tree->getDescription()
541  && !strcmp(loop->m_sub_tree->getDescription(), description))
542  {
543  return loop->m_sub_tree;
544  }
545  loop = loop->m_next;
546  }
547  return 0;
548 }
549 
551 {
552  int ret = 0;
553  SubTreeList *loop = this;
554  while (loop)
555  {
556  ret += loop->m_sub_tree->contains();
557  loop = loop->m_next;
558  }
559  return ret;
560 }
561 
562 void SubTreeList::printSubTree(ostream& out, int change_style_depth, char *upper_description)
563 {
564  SubTreeList *loop = this;
565  while (loop)
566  {
567  loop->m_sub_tree->printSubTree(out, change_style_depth, upper_description);
568  loop = loop->m_next;
569  }
570 }
571 
572 AttributeTree* SubTreeList::search(const char *description, const char *attribute)
573 {
574  SubTreeList *loop = this;
575  while (loop)
576  {
577  AttributeTree* search = loop->m_sub_tree->search(description, attribute);
578  if (search)
579  {
580  return search;
581  }
582  loop = loop->m_next;
583  }
584  return NULL;
585 }
586 
588 {
589  SubTreeList *loop = this;
590  while (loop)
591  {
592  if (loop->m_sub_tree->changed())
593  {
594  return true;
595  }
596  loop = loop->m_next;
597  }
598  return false;
599 }
600 
602 {
603  SubTreeList *loop = this;
604  while (loop)
605  {
606  if (loop->m_sub_tree == prev)
607  {
608  if (loop->m_next)
609  {
610  return loop->m_next->m_sub_tree;
611  }
612  }
613  loop = loop->m_next;
614  }
615  return 0;
616 }
617 
619 {
620  SubTreeList *loop = this;
621  while (loop)
622  {
623  loop->m_sub_tree->unmarkChanges();
624  loop = loop->m_next;
625  }
626 }
627 
629 {
630  SubTreeList* ret = this;
631  if (m_sub_tree)
632  {
634  }
635  if (m_next)
636  {
637  ret = m_next->revertOrder(this);
638  }
639  m_next = new_next;
640  return ret;
641 }
642 
644 {
645  SubTreeList *loop;
646  // loop through all next ones
647  for (loop = this; loop->m_next && loop->m_sub_tree != after; loop = loop->m_next)
648  { }
649  // and insert the new
650  loop->m_next = new SubTreeList(new_tree, loop->m_next);
651 }
652 
654 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
655 
659  SubTreeList *SubTreeList::RevertOrder(SubTreeList *new_next)
660  {
661  return revertOrder(new_next);
662  }
663 
668  void SubTreeList::NewSubTreeList(AttributeTree *new_tree, AttributeTree *after)
669  {
670  return newSubTreeList(new_tree, after);
671  }
672 
673 #endif
674 
676 // ===============================================================
677 // AttributeTree
678 // ===============================================================
679 
680 AttributeTree::AttributeTree(const char *description, AttributeTree *parent)
681  : m_parent(parent),
682  m_subtree_list(NULL)
683 {
684  file_path_str_len = strlen(m_file_path_str);
685  file_name_str_len = strlen(m_file_name_str);
686  if (description)
687  {
689  }
690  else
691  {
692  m_this_description = 0;
693  }
694  m_this_attribute = 0;
695  m_changed = false;
696 
697  // Beim Parent in die Liste einfügen
698  if (m_parent)
699  {
701  }
702 }
703 
705  : m_parent(NULL),
706  m_subtree_list(NULL)
707 {
708  file_path_str_len = strlen(m_file_path_str);
709  file_name_str_len = strlen(m_file_name_str);
710 
711  if (&tree)
712  {
713  if (tree.m_this_description)
714  {
716  }
717  else
718  {
719  m_this_description = 0;
720  }
721  if (tree.m_this_attribute)
722  {
724  }
725  else
726  {
727  m_this_attribute = 0;
728  }
729  if (tree.m_subtree_list)
730  {
731  tree.m_subtree_list->copy(this);
732  }
733  }
734  else
735  {
736  m_this_description = 0;
737  m_this_attribute = 0;
738  }
739 
740  m_changed = false;
741 }
742 
744  : m_parent(parent),
745  m_subtree_list(NULL)
746 {
747  file_path_str_len = strlen(m_file_path_str);
748  file_name_str_len = strlen(m_file_name_str);
749 
750  if (&tree)
751  {
752  if (tree.m_this_description)
753  {
755  }
756  else
757  {
758  m_this_description = 0;
759  }
760  if (tree.m_this_attribute)
761  {
763  }
764  else
765  {
766  m_this_attribute = 0;
767  }
768  if (tree.m_subtree_list)
769  {
770  tree.m_subtree_list->copy(this);
771  }
772  }
773  else
774  {
775  m_this_description = 0;
776  m_this_attribute = 0;
777  }
778  // Beim Parent in die Liste einfügen
779  if (m_parent)
780  {
782  }
783 
784  m_changed = false;
785 }
786 
788 {
789  // DEBUGMSG(-3, "AttributeTree::~ >> Deleting ...\n");
790  if (m_this_description)
791  {
792  // DEBUGMSG(-3, "\t descr(%p)='%s'\n", this, m_this_description);
793  free(m_this_description);
794  m_this_description = 0;
795  }
796  if (m_this_attribute)
797  {
798  // DEBUGMSG(-3, "\t attr=%s\n", m_this_attribute);
799  free(m_this_attribute);
800  m_this_attribute = 0;
801  }
802  // subtree wird komplett ausgelöscht
803  if (m_subtree_list)
804  {
805  // DEBUGMSG(-3, "Entering sub (%p)...\n", this);
806  delete m_subtree_list;
807  m_subtree_list = 0;
808  // DEBUGMSG(-3, "Leaving sub (%p) ...\n", this);
809  }
810 
811  unlink();
812 }
813 
815 {
816  if (m_subtree_list)
817  {
818  // die parent-Zeiger der Unterbäume auf 0 setzen
820  // den Unterbaumzeiger auf 0
821  m_subtree_list = 0;
822  }
823 }
824 
826 {
827  if (m_parent)
828  {
829  SubTreeList *first_entry = m_parent->m_subtree_list;
830  if (first_entry->m_sub_tree == this)
831  {
832  m_parent->m_subtree_list = first_entry->m_next;
833  }
834 
835  first_entry->unlink(this);
836  m_parent->m_changed = true;
837  }
838  m_parent = 0;
839 }
840 
841 
842 void AttributeTree::setDescription(const char *description)
843 {
844  free(m_this_description);
845  if (description)
846  {
848  }
849  else
850  {
851  m_this_description = 0;
852  }
853 }
854 
856 {
857  //printf("Change Attribute:%s %s\n",m_this_attribute,attribute);
858  if (!m_this_attribute || !attribute || strcmp(attribute, m_this_attribute))
859  {
860  free(m_this_attribute);
861  if (attribute)
862  {
864  }
865  else
866  {
867  m_this_attribute = 0;
868  }
869  m_changed = true;
870  }
871 }
872 
873 
874 AttributeTree* AttributeTree::subTree(const char *description)
875 {
876  AttributeTree *m_sub_tree = getSubTree(description);
877  if (m_sub_tree != NULL)
878  {
879  // Gibt's schon einen, geben wir diesen zurück
880  return m_sub_tree;
881  }
882  else
883  {
884  // Ansonsten erzeugen wir einen:
885  return new AttributeTree(description, this);
886  }
887 }
888 
889 AttributeTree* AttributeTree::getSubTree(const char *description)
890 {
891  AttributeTree *m_sub_tree;
892  // Erstmal suchen, obs schon einen gibt:
893  if (m_subtree_list)
894  {
895  m_sub_tree = m_subtree_list->subTree(description);
896  if (m_sub_tree)
897  {
898  return m_sub_tree;
899  }
900  }
901  // Ansonsten geben wir NULL zurück
902  return NULL;
903 }
904 
905 
906 AttributeTree *AttributeTree::setAttribute(const char *param_description, const char *attribute)
907 {
908  if (param_description)
909  {
910  char *description = icl_core::os::strdup(param_description);
911  //printf("a:%s:%s\n",description,attribute);
912  char *subdescription;
913  split(description, subdescription);
914  //printf("b:%s--%p\n",description,subdescription);
915  AttributeTree *ret = setAttribute(description, subdescription, attribute);
916  free(description);
917  //printf("c:%p \n",ret);
918  return ret;
919  }
920  setAttribute(attribute);
921  return this;
922 }
923 
924 AttributeTree* AttributeTree::setAttribute(const char *description, const char *subdescription,
925  const char *attribute)
926 {
927  // printf("%p---%s,%s,%s\n",this,description,subdescription,attribute);
928  if (!description || !*description)
929  {
930  // Keine Description -> Wir sind am Endknoten -> Eintrag machen
931  // printf("set attribute: %s :%s\n",m_this_description,attribute);
932  setAttribute(attribute);
933 
934  return this;
935  }
936 
937  //printf("1--%p\n",m_this_description);
938  // Ansonsten müssen wir weiter nach unten suchen:
939  AttributeTree *subtree = 0;
940  if (m_subtree_list)
941  {
942  subtree = m_subtree_list->subTree(description);
943  }
944 
945  //printf("2--\n");
946  if (subtree)
947  {
948  return subtree->setAttribute(subdescription, attribute);
949  }
950 
951  // Kein passender Eintrag gefunden -> neuen Sub-Baum erzeugen:
952  AttributeTree *new_subtree = new AttributeTree(description, this);
953  //printf("3--:%p\n",new_subtree);
954 
955  return new_subtree->setAttribute(subdescription, attribute);
956 }
957 
958 
959 char *AttributeTree::getSpecialAttribute(const char *description, AttributeTree **subtree)
960 {
961  // search recursive to the root for that attribute
962  AttributeTree *at_path_parent = this;
963  AttributeTree *at_path = at_path_parent->m_subtree_list->subTree(description);
964  while (at_path_parent && at_path == NULL)
965  {
966  at_path = at_path_parent->m_subtree_list->subTree(description);
967  at_path_parent = at_path_parent->parentTree();
968  }
969 
970  // found
971  if (at_path && at_path->m_this_attribute)
972  {
973  //DEBUGMSG(DD_AT, DL_DEBUG, "AttributeTree::getSpecialAttribute>> found special attribute %s with %s\n",
974  // m_file_path_str, at_path->m_this_attribute);
975  if (subtree)
976  {
977  (*subtree) = at_path;
978  }
979  return at_path->m_this_attribute;
980  }
981  return NULL;
982 }
983 
984 char *AttributeTree::getAttribute(const char *param_description, const char *default_attribute,
985  AttributeTree **subtree)
986 {
987  char*ret = 0;
988  if (param_description)
989  {
990  char *description = icl_core::os::strdup(param_description);
991  if (description)
992  {
993  AttributeTree* at = this;
994  // check for 'm_file_path_str' and 'm_file_name_str'
995  int len = strlen(description);
996  if (len >= file_path_str_len
997  && !strncmp(description + (len - file_path_str_len), m_file_path_str, file_path_str_len))
998  {
999  ret = getSpecialAttribute(m_file_path_str, subtree);
1000  }
1001  else if (len >= file_name_str_len
1002  && !strncmp(description + (len - file_name_str_len), m_file_name_str, file_name_str_len))
1003  {
1004  ret = getSpecialAttribute(m_file_name_str, subtree);
1005  }
1006 
1007  // not found yet ... trying the standard search
1008  if (!ret)
1009  {
1010  char *description_part = description;
1011  // go into the attribute tree structure
1012  for (; at && description_part;)
1013  {
1014  // save the begin of the description
1015  char *next_description = description_part;
1016  // searching for further dots
1017  description_part = strchr(description_part, '.');
1018  if (description_part)
1019  {
1020  *description_part = 0;
1021  description_part++;
1022  }
1023  at = at->m_subtree_list->subTree(next_description);
1024  }
1025  // now we are at the inner attribute tree
1026  // is there an attribute
1027  if (at && at->m_this_attribute)
1028  {
1029  //DEBUGMSG(DD_AT, DL_DEBUG, "AttributeTree::getAttribute>> found %s\n", at->m_this_attribute);
1030  if (subtree)
1031  {
1032  (*subtree) = at;
1033  }
1034  ret = at->m_this_attribute;
1035  }
1036  }
1037  free(description);
1038  }
1039  }
1040  // didn't find anything
1041  if (!ret)
1042  {
1043  if (subtree)
1044  {
1045  (*subtree) = 0;
1046  }
1047  //DEBUGMSG(DD_AT, DL_DEBUG, "AttributeTree::getAttribute>> nothing found. Return default %s\n",
1048  // default_attribute ? default_attribute : "(null)");
1049  ret = const_cast<char*>(default_attribute);
1050  }
1051 
1052  return ret;
1053 }
1054 
1055 char* AttributeTree::getOrSetDefault(const char *description, const char *default_attribute)
1056 {
1057  char *attribute = getAttribute(description, 0);
1058  if (!attribute)
1059  {
1060  setAttribute(description, default_attribute);
1061  attribute = const_cast<char*>(default_attribute);
1062  }
1063  return attribute;
1064 }
1065 
1066 char *AttributeTree::newSubNodeDescription(const char *base_description)
1067 {
1068  int base_len = strlen(base_description);
1069  char *description = (char*)malloc(base_len + 6);
1070  assert(description != NULL); // Just abort if we are out of memory.
1071  strcpy(description, base_description);
1072  int i = 1;
1073  int j = 0;
1074 
1075  // find the maxima length of number in base_description
1076  if (base_len>0)
1077  {
1078  while (base_len>=j-1 &&
1079  sscanf(description+base_len-j-1, "%i", &i)==1)
1080  {
1081  j++;
1082  }
1083  if (j!=0)
1084  {
1085  i++;
1086  }
1087  }
1088 
1089  sprintf(description + base_len - j, "%i", i);
1090 
1091  while (m_subtree_list->subTree(description) && i < 100000)
1092  {
1093  i++;
1094  sprintf(description + base_len - j, "%i", i);
1095  }
1096  return description;
1097 }
1098 
1099 
1101 {
1102  char *name = newSubNodeDescription();
1103  AttributeTree *ret = setAttribute(name, 0);
1104  free(name);
1105  return ret;
1106 }
1107 
1108 
1110 {
1111  if (tree)
1112  {
1114  {
1115  char *new_description = newSubNodeDescription(tree->m_this_description);
1116  free(tree->m_this_description);
1117  tree->m_this_description = new_description;
1118  }
1119 
1120  if (after == NULL)
1121  {
1123  }
1124  else
1125  {
1126  m_subtree_list->newSubTreeList(tree, after);
1127  }
1128 
1129  tree->m_parent = this;
1130  return tree;
1131  }
1132  else
1133  {
1134  return NULL;
1135  }
1136 }
1137 
1138 void AttributeTree::printSubTree(ostream& out, int change_style_depth, const char *upper_description)
1139 {
1140  // virtual attributes are not stored !
1142  || !strcmp(m_this_description, m_file_name_str)))
1143  {
1144  return;
1145  }
1146 
1147  char *the_upper_description = strdup(upper_description ? upper_description : "");
1148  char *t_description = strdup(m_this_description ? m_this_description : "");
1149  assert(the_upper_description != NULL);
1150  assert(t_description != NULL);
1151 
1152  // is this the comment attribute tree ?
1153  if (isMultilineComment())
1154  {
1155  out << the_upper_description << comment_str << '{' << endl;
1156  out << m_this_attribute << endl;
1157  out << the_upper_description << '}' << comment_str << endl;
1158 
1159  free(the_upper_description);
1160  free(t_description);
1161 
1162  return;
1163  }
1164 
1165  int contents = contains();
1166  if (contents >= change_style_depth || hasMultilineComment())
1167  {
1168  out << the_upper_description << t_description << '{' << endl;
1169  if (m_this_attribute && strcmp(m_this_attribute, ""))
1170  {
1171  out << the_upper_description << ':' << m_this_attribute << endl;
1172  }
1173 
1174  if (m_subtree_list)
1175  {
1176  char *tab = (char*)malloc(strlen(the_upper_description) + 2);
1177  assert(tab != NULL); // Just abort if we are out of memory.
1178  strcat(strcpy(tab, the_upper_description), " ");
1179  m_subtree_list->printSubTree(out, change_style_depth, tab);
1180  free(tab);
1181  }
1182 
1183  out << the_upper_description << '}' << t_description << endl;
1184  }
1185  else
1186  {
1187  size_t tud_len = strlen(the_upper_description);
1188  size_t len = strlen(t_description) + tud_len + 1;
1189  char *description = static_cast<char*>(malloc(len + 1));
1190  assert(description != NULL); // Just abort if we are out of memory.
1191  memset(description, 0, len + 1);
1192 
1193  if ((tud_len > 0) && (the_upper_description[tud_len-1] == ' '))
1194  {
1195  strcat(strcpy(description, the_upper_description), t_description);
1196  }
1197  else
1198  {
1199  strcat(strcat(strcpy(description, the_upper_description), "."), t_description);
1200  }
1201 
1202  if (m_this_attribute)
1203  {
1204  out << description << ':' << m_this_attribute << endl;
1205  }
1206 
1207  if (m_subtree_list)
1208  {
1209  m_subtree_list->printSubTree(out, change_style_depth, description);
1210  }
1211  free(description);
1212  }
1213 
1214  free(the_upper_description);
1215  free(t_description);
1216 }
1217 
1218 int AttributeTree::save(const char *filename, int change_style_depth, bool unmark_changes)
1219 {
1220  /*
1221  if (!m_this_description)
1222  return eEMPTY_TREE;
1223  */
1224  ofstream out(filename);
1225  if (!out)
1226  {
1227  return eFILE_SAVE_ERROR;
1228  }
1229  printSubTree(out, change_style_depth, "");
1230 
1231  if (unmark_changes)
1232  {
1233  unmarkChanges();
1234  }
1235 
1236  return eOK;
1237 }
1238 
1239 int AttributeTree::load(const char *filename, bool unmark_changes, bool process_include,
1240  bool load_comments, bool preserve_order)
1241 {
1242  if (filename == NULL || strcmp(filename, "") == 0)
1243  {
1244  printf("tAttributeTree >> Trying to load an empty configuration file.\n");
1245  return eFILE_LOAD_ERROR;
1246  }
1247 
1248  icl_core::config::FilePath at_file(filename);
1249  //LOCAL_PRINTF("AttributeTree >> Loading %s\n", at_file.AbsoluteName().c_str());
1250  if (this == root() && !getAttribute(m_file_path_str))
1251  {
1252  //LOCAL_PRINTF("AttributeTree >> Setting Virtual Attributes Path(%s) Name(%s)\n",
1253  // at_file.Path().c_str(), at_file.Name().c_str());
1254  setAttribute(m_file_path_str, at_file.path().c_str());
1255  setAttribute(m_file_name_str, at_file.name().c_str());
1256  }
1257 
1258  int error;
1259  ifstream in(at_file.absoluteName().c_str());
1260  if (!in)
1261  {
1262  printf("tAttributeTree >> Could not open file '%s'\n", (const char*)at_file.absoluteName().c_str());
1263  return eFILE_LOAD_ERROR;
1264  }
1265 
1266  error = get(in, process_include, load_comments, &at_file);
1267  if (error >= 0)
1268  {
1269  printf("Error in line %i while reading AttributeTree %s\n", error,
1270  (const char*) at_file.absoluteName().c_str());
1271  return eFILE_LOAD_ERROR;
1272  }
1273 
1274 
1275  if (unmark_changes)
1276  {
1277  unmarkChanges();
1278  }
1279  if (preserve_order)
1280  {
1281  revertOrder();
1282  }
1283  //DEBUGMSG(DD_AT, DL_DEBUG, "AttributeTree >> Loading successful\n");
1284 
1285  return eOK;
1286 }
1287 
1288 int AttributeTree::get(istream &in, bool process_include, bool load_comments,
1289  const class FilePath *file_path)
1290 {
1291  // save stack memory on reccursive calls!
1292  // without static in the insmod call for the RTL-module we crash !
1293  buffer[1999] = 0;
1294  char *attribute, *line;
1295  AttributeTree *at = this;
1296  int lineno = 1;
1297 
1299 
1300  do
1301  {
1302  //LOCAL_PRINTF("get next line %i\n",lineno);
1303  lineno++;
1304  line = buffer;
1305  while (isspace(*line))
1306  {
1307  line++;
1308  }
1309  //LOCAL_PRINTF("%s\n",line);
1310  if (line[0] != '#')
1311  {
1312  attribute = strchr(line, ':');
1313  if (attribute)
1314  {
1315  *attribute = 0;
1316  if (!line[0])
1317  {
1318  //LOCAL_PRINTF("AttributeTree::get >> found ':%s'\n", attribute+1);
1319  at->setAttribute(attribute + 1);
1320  }
1321  else
1322  {
1323  if (!strcmp(line, include_str))
1324  {
1325  if (process_include)
1326  {
1327  string include_filename(line + INCLUDE_OFFSET);
1328  include_filename = FilePath::exchangeSeparators(FilePath::replaceEnvironment(include_filename));
1329  if (FilePath::isRelativePath(include_filename))
1330  {
1331  string absolute_include_filename(file_path ? file_path->path() : getFilePath());
1332  absolute_include_filename += include_filename;
1333  include_filename = FilePath::normalizePath(absolute_include_filename);
1334  }
1335  if (at->load(include_filename.c_str(), false, process_include, load_comments) != eOK)
1336  {
1337  printf("error loading include file %s\n", (const char*)include_filename.c_str());
1338  }
1339  }
1340  else
1341  {
1342  // falls nicht includen: als "normalen" Eintrag speichern
1343  (new AttributeTree(include_str, at))->setAttribute(line + INCLUDE_OFFSET);
1344  }
1345  }
1346  else if (!strstr(line, comment_str) || load_comments)
1347  {
1348  //LOCAL_PRINTF("AttributeTree::get >> found '%s:%s'\n", line, attribute+1);
1349  at->setAttribute(line, attribute + 1);
1350  }
1351  }
1352  }
1353  else
1354  {
1355  attribute = strchr(line, '{');
1356  if (attribute)
1357  {
1358  *attribute = 0;
1359  //LOCAL_PRINTF("AttributeTree::get >> found '%s{'\n", line);
1360  // multiline comments
1361  if (!strcmp(line, comment_str))
1362  {
1363  AttributeTree *at_c = 0;
1364  bool comment_end = false;
1365  if (load_comments)
1366  {
1367  at_c = new AttributeTree(comment_str, at);
1368  }
1369  do
1370  {
1371  lineno++;
1373  line = buffer;
1374  char *line_end = buffer + strlen(buffer);
1375  line_end--;
1376  while (isspace(*line))
1377  {
1378  line++;
1379  }
1380  while (line_end >= buffer && isspace(*line_end))
1381  {
1382  line_end--;
1383  }
1384  *(line_end + 1) = 0;
1385  comment_end = (strstr(line, comment_end_str) != NULL);
1386 
1387  if (load_comments && !comment_end)
1388  {
1389  at_c->appendAttribute(line, "\n");
1390  }
1391  }
1392  while (!comment_end);
1393  }
1394  else
1395  {
1396  at = at->setAttribute(line, 0);
1397  }
1398  }
1399  else
1400  {
1401  attribute = strchr(line, '}');
1402  if (attribute)
1403  {
1404  if (at == this)
1405  {
1406  //LOCAL_PRINTF("AttributeTree::get >> found last '}'\n");
1407  return -1;
1408  }
1409  else
1410  {
1411  //LOCAL_PRINTF("AttributeTree::get >> found '}'\n");
1412  if (!at->parentTree())
1413  {
1414  return lineno;
1415  }
1416  at = at->parentTree();
1417  }
1418  }
1419  else
1420  {
1421  if (!in.eof() && line[0])
1422  {
1423  //LOCAL_PRINTF("AttributeTree::get >> found '%s' and could not interpret\n", line);
1424  return lineno;
1425  }
1426  }
1427  }
1428  }
1429  }
1431  }
1432  while (!in.eof());
1433  return -1;
1434 }
1435 
1436 void AttributeTree::split(char *&description, char *&subdescription)
1437 {
1438  subdescription = strchr(description, '.');
1439  if (subdescription)
1440  {
1441  *subdescription = 0;
1442  subdescription++;
1443  }
1444 }
1445 
1446 AttributeTree* AttributeTree::search(const char *description, const char *attribute)
1447 {
1448  if (description)
1449  {
1450  if ((m_this_description && (!strcmp(description, m_this_description))) &&
1451  (attribute == 0 || (m_this_attribute && (!strcmp(attribute, m_this_attribute)))))
1452  {
1453  return this;
1454  }
1455  if (m_subtree_list)
1456  {
1457  return m_subtree_list->search(description, attribute);
1458  }
1459  }
1460  return NULL;
1461 }
1462 
1463 bool AttributeTree::isAttribute(const char *description, const char *attribute)
1464 {
1465  char *content = getAttribute(description, 0);
1466 
1467  if (attribute)
1468  {
1469  if (content)
1470  {
1471  return !strcmp(content, attribute);
1472  }
1473  return false;
1474  }
1475  else
1476  {
1477  return content != NULL;
1478  }
1479 }
1480 
1482 {
1483  if (m_changed)
1484  {
1485  return true;
1486  }
1487  if (m_subtree_list)
1488  {
1489  return m_subtree_list->changed();
1490  }
1491  return false;
1492 }
1493 
1495 {
1496  m_changed = false;
1497  if (m_subtree_list)
1498  {
1500  }
1501 }
1502 
1504 {
1505  int ret = 0;
1506  if (m_this_attribute)
1507  {
1508  ret++;
1509  }
1510  if (m_subtree_list)
1511  {
1512  ret += m_subtree_list->contains();
1513  }
1514  return ret;
1515 }
1516 
1517 void AttributeTree::appendString(char *& dest, const char *src, const char *additional_separator)
1518 {
1519  if (!src)
1520  {
1521  return;
1522  }
1523  if (!additional_separator)
1524  {
1525  additional_separator = "";
1526  }
1527  if (dest)
1528  {
1529  int old_len = strlen(dest);
1530  int additional_len = strlen(additional_separator);
1531  int whole_len = old_len + additional_len + strlen(src);
1532  char *new_attr = static_cast<char*>(malloc(whole_len + 1));
1533  assert(new_attr != NULL); // Just abort if out of memory!
1534  strcpy(new_attr, dest);
1535  strcpy(new_attr + old_len, additional_separator);
1536  strcpy(new_attr + old_len + additional_len, src);
1537  free(dest);
1538  dest = new_attr;
1539  }
1540  else
1541  {
1542  dest = icl_core::os::strdup(src);
1543  }
1544  m_changed = true;
1545 }
1546 
1548 {
1549  AttributeTree *loop = firstSubTree();
1550  while (loop)
1551  {
1552  if (loop->isComment() && loop->attribute())
1553  {
1554  return loop;
1555  }
1556  loop = nextSubTree(loop);
1557  }
1558  return NULL;
1559 }
1560 
1562 {
1563  return m_this_description && !strcmp(m_this_description, comment_str);
1564 }
1565 
1567 {
1568  return isComment() && (strchr(attribute(), '\n') != NULL);
1569 }
1570 
1572 {
1573  AttributeTree* sub_comment = commentAttributeTree();
1574  if (sub_comment)
1575  {
1576  return sub_comment->attribute();
1577  }
1578  else
1579  {
1580  return "";
1581  }
1582 }
1583 
1585 {
1586  return strchr(comment(), '\n') != NULL;
1587 }
1588 
1590 {
1591  setAttribute(comment_str, comment);
1592 }
1593 
1595 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
1596 
1600  void AttributeTree::Unlink()
1601  {
1602  unlink();
1603  }
1604 
1608  void AttributeTree::UnlinkSub()
1609  {
1610  unlinkSub();
1611  }
1612 
1616  AttributeTree *AttributeTree::SetAttribute(const char *description,
1617  const char *attribute)
1618  {
1619  return setAttribute(description, attribute);
1620  }
1621 
1626  AttributeTree *AttributeTree::SetAttribute(const char *description,
1627  const char *subdescription,
1628  const char *attribute)
1629  {
1630  return setAttribute(description, subdescription, attribute);
1631  }
1632 
1636  char *AttributeTree::GetAttribute()
1637  {
1638  return getAttribute();
1639  }
1640 
1644  char *AttributeTree::GetAttribute(const char *description,
1645  const char *default_attribute,
1646  AttributeTree **subtree)
1647  {
1648  return getAttribute(description, default_attribute, subtree);
1649  }
1650 
1654  char *AttributeTree::GetOrSetDefault(const char *description,
1655  const char *default_attribute)
1656  {
1657  return getOrSetDefault(description, default_attribute);
1658  }
1659 
1663  int AttributeTree::Save(const char *filename, int change_style_depth,
1664  bool unmark_changes)
1665  {
1666  return save(filename, change_style_depth, unmark_changes);
1667  }
1668 
1672  int AttributeTree::Load(const char *filename, bool unmark_changes,
1673  bool process_include, bool load_comments,
1674  bool preserve_order)
1675  {
1676  return load(filename, unmark_changes, process_include, load_comments, preserve_order);
1677  }
1678 
1682  int AttributeTree::Get(std::istream &in, bool process_include,
1683  bool load_comments, const FilePath *file_path)
1684  {
1685  return get(in, process_include, load_comments, file_path);
1686  }
1687 
1691  char *AttributeTree::NewSubNodeDescription(const char *base_description)
1692  {
1693  return newSubNodeDescription(base_description);
1694  }
1695 
1699  AttributeTree *AttributeTree::AddNewSubTree()
1700  {
1701  return addNewSubTree();
1702  }
1703 
1707  void AttributeTree::PrintSubTree(std::ostream &out,
1708  int change_style_depth,
1709  const char *upper_description)
1710  {
1711  printSubTree(out, change_style_depth, upper_description);
1712  }
1713 
1717  const char *AttributeTree::Description() const
1718  {
1719  return getDescription();
1720  }
1721 
1725  const char *AttributeTree::Attribute() const
1726  {
1727  return attribute();
1728  }
1729 
1733  void AttributeTree::SetDescription(const char *description)
1734  {
1735  setDescription(description);
1736  }
1737 
1741  void AttributeTree::SetAttribute(const char *attribute)
1742  {
1743  setAttribute(attribute);
1744  }
1745 
1749  void AttributeTree::SetComment(const char *comment)
1750  {
1751  setComment(comment);
1752  }
1753 
1757  AttributeTree *AttributeTree::SubTree(const char *description)
1758  {
1759  return subTree(description);
1760  }
1761 
1765  AttributeTree *AttributeTree::GetSubTree(const char *description)
1766  {
1767  return getSubTree(description);
1768  }
1769 
1773  AttributeTree *AttributeTree::FirstSubTree()
1774  {
1775  return firstSubTree();
1776  }
1777 
1781  AttributeTree *AttributeTree::NextSubTree(AttributeTree *subtree)
1782  {
1783  return nextSubTree(subtree);
1784  }
1785 
1789  AttributeTree *AttributeTree::ParentTree()
1790  {
1791  return parentTree();
1792  }
1793 
1797  AttributeTree *AttributeTree::AddSubTree(AttributeTree *subtree)
1798  {
1799  return addSubTree(subtree);
1800  }
1801 
1805  AttributeTree *AttributeTree::AddNextTree(AttributeTree *nexttree)
1806  {
1807  return addNextTree(nexttree);
1808  }
1809 
1815  AttributeTree *AttributeTree::Search(const char *description, const char *attribute)
1816  {
1817  return search(description, attribute);
1818  }
1819 
1824  bool AttributeTree::IsAttribute(const char *description, const char *attribute)
1825  {
1826  return isAttribute(description, attribute);
1827  }
1828 
1833  bool AttributeTree::Changed()
1834  {
1835  return changed();
1836  }
1837 
1841  void AttributeTree::UnmarkChanges()
1842  {
1843  return unmarkChanges();
1844  }
1845 
1849  int AttributeTree::Contains()
1850  {
1851  return contains();
1852  }
1853 
1857  AttributeTree *AttributeTree::Parent()
1858  {
1859  return parent();
1860  }
1861 
1865  AttributeTree *AttributeTree::Root()
1866  {
1867  return root();
1868  }
1869 
1873  const char *AttributeTree::Comment()
1874  {
1875  return comment();
1876  }
1877 
1881  bool AttributeTree::HasComment()
1882  {
1883  return hasComment();
1884  }
1885 
1889  bool AttributeTree::IsComment()
1890  {
1891  return isComment();
1892  }
1893 
1897  bool AttributeTree::HasMultilineComment()
1898  {
1899  return hasMultilineComment();
1900  }
1901 
1905  bool AttributeTree::IsMultilineComment()
1906  {
1907  return isMultilineComment();
1908  }
1909 
1913  AttributeTree *AttributeTree::CommentAttributeTree()
1914  {
1915  return commentAttributeTree();
1916  }
1917 
1921  void AttributeTree::AppendAttribute(const char *attribute, const char *separator)
1922  {
1923  appendAttribute(attribute, separator);
1924  }
1925 
1929  void AttributeTree::AppendDescription(const char *description, const char *separator)
1930  {
1931  appendDescription(description, separator);
1932  }
1933 
1937  void AttributeTree::RevertOrder()
1938  {
1939  revertOrder();
1940  }
1941 
1946  const char *AttributeTree::GetFilePath()
1947  {
1948  return getFilePath();
1949  }
1950 
1955  const char *AttributeTree::FileName()
1956  {
1957  return fileName();
1958  }
1959 
1960 #endif
1961 
1963 }
1964 }
AttributeTree * search(const char *description, const char *attribute)
AttributeTree * next(AttributeTree *prev)
char * newSubNodeDescription(const char *base_description="")
const int INCLUDE_OFFSET
AttributeTree * search(const char *description, const char *attribute)
bool isAttribute(const char *description, const char *attribute=0)
AttributeTree * commentAttributeTree()
Contains global functions for string manipulation, encapsulated into the icl_core::os namespace...
static icl_core::String replaceEnvironment(const icl_core::String &filename)
char * strdup(const char *s)
void appendDescription(const char *description, const char *separator="")
const char * getDescription() const
int load(const char *filename, bool unmark_changes=true, bool process_include=true, bool load_comments=false, bool preserve_order=false)
void copy(AttributeTree *parent)
int save(const char *filename, int change_style_depth=3, bool unmark_changes=true)
void printSubTree(std::ostream &out, int change_style_depth=3, const char *upper_description=0)
AttributeTree(const char *description=0, AttributeTree *parent=0)
const char DSEP_OTHER
SubTreeList(AttributeTree *sub_tree=0, SubTreeList *next=0)
static const char * m_file_name_str
AttributeTree * nextSubTree(AttributeTree *subtree)
void newSubTreeList(AttributeTree *new_tree, AttributeTree *after)
static icl_core::String normalizePath(const icl_core::String &filename)
AttributeTree * addSubTree(AttributeTree *subtree)
void readNextLineInBuffer(istream &in)
void unlink(AttributeTree *obsolete_tree)
ThreadStream & endl(ThreadStream &stream)
Definition: ThreadStream.h:249
AttributeTree * addNextTree(AttributeTree *nexttree)
char * getSpecialAttribute(const char *description, AttributeTree **subtree=NULL)
static char buffer[2000]
void setDescription(const char *description)
char * getOrSetDefault(const char *description, const char *default_attribute)
std::string String
Definition: BaseTypes.h:43
const char * include_str
AttributeTree * getSubTree(const char *description)
char * strdup(const char *s)
Definition: os_string.h:52
const char * comment_str
static const char * m_file_path_str
void printSubTree(std::ostream &out, int change_style_depth, char *upper_description)
void appendString(char *&dest, const char *src, const char *separator)
void * memset(void *dest, int c, size_t count)
Definition: os_mem.h:46
icl_core::String absoluteName() const
Definition: AttributeTree.h:77
const char * attribute() const
AttributeTree * subTree(const char *description)
icl_core::String path() const
Definition: AttributeTree.h:63
void appendAttribute(const char *attribute, const char *separator="")
AttributeTree * setAttribute(const char *description, const char *attribute)
icl_core::String name() const
Definition: AttributeTree.h:70
bool Get(const icl_core::String &key, typename icl_core::ConvertToRef< T >::ToRef value) ICL_CORE_GCC_DEPRECATE_STYLE
Definition: Config.h:648
void split(char *&description, char *&sub_description)
AttributeTree * subTree(const char *description)
Reads a configuration file in the old MCA attribute tree format.
static icl_core::String exchangeSeparators(const icl_core::String &filename)
int get(std::istream &in, bool process_include=true, bool load_comments=false, const FilePath *file_path=NULL)
SubTreeList * revertOrder(SubTreeList *new_next=NULL)
void setComment(const char *comment)
const char * comment_end_str


fzi_icl_core
Author(s):
autogenerated on Mon Jun 10 2019 13:17:58