LOGIN / SIGN UP
Start on @template syntax for configuration files, not working yet.
2008-10-05 19:31 fe61e..f2545
    Data seems to be copied over just fine but overwriting does not work
    yet, should fine to use for things such as defining @BORDER for decors
    and the like.

src/CfgParser.cc
 
45 @@ -45,24 +45,48 @@
45 {
46 }
47
48 /**
49 * Copy Entry together with the content.
50 */
51 CfgParser::Entry::Entry(const CfgParser::Entry &entry)
52 : _name(entry._name), _value(entry._value),
53 _line(entry._line), _source_name(_source_name)
54 {
55 if (entry._entry_next) {
56 _entry_next = new Entry(*entry._entry_next);
57 }
58 if (entry._section) {
59 _section = new Entry(*entry._section);
60 }
61 }
62
63 //! @brief CfgParser::Entry destructor.
64 CfgParser::Entry::~Entry(void)
65 {
66 }
67
68 //! @brief Adds Entry to the end of Entry list at current depth.
69 /**
70 * Append Entry to the end of Entry list at current depth.
71 */
72 CfgParser::Entry*
73 CfgParser::Entry::add_entry(const std::string &source_name, int line,
74 const std::string &name, const std::string &value)
75 CfgParser::Entry::add_entry(CfgParser::Entry *entry)
76 {
77 if (_entry_next) {
78 return _entry_next->add_entry(source_name, line, name, value);
79 return _entry_next->add_entry(entry);
80 } else {
81 _entry_next = new Entry(source_name, line, name, value);
82 _entry_next = entry;
83 return _entry_next;
84 }
85 }
86
87 //! @brief Adds Entry to the end of Entry list at current depth.
88 CfgParser::Entry*
89 CfgParser::Entry::add_entry(const std::string &source_name, int line,
90 const std::string &name, const std::string &value)
91 {
92 return add_entry(new Entry(source_name, line, name, value));
93 }
94
95 //! @brief Gets next entry that has a sub section.
96 CfgParser::Entry*
97 CfgParser::Entry::get_section_next(void)
...
156 @@ -132,6 +156,40 @@
156 }
157 }
158
159 /**
160 * Copy tree into current entry, overwrite entries if overwrite is
161 * true.
162 */
163 void
164 CfgParser::Entry::copy_tree_into(CfgParser::Entry *from, bool overwrite)
165 {
166 CfgParser::Entry *it;
167 for (it = from; it; it = it->_entry_next) {
168 if (! overwrite) {
169 add_entry(new Entry(*it));
170 continue;
171 }
172
173 // Check for section, if one exists either copy into existing
174 // or create new copy.
175 if (it->get_section()) {
176 CfgParser::Entry *section = find_section(it->get_section()->get_name());
177 if (section) {
178 section->copy_tree_into(it->get_section(), overwrite);
179 } else {
180 add_entry(new Entry(*section));
181 }
182 }
183
184 CfgParser::Entry *entry = find_entry(it->get_name());
185 if (entry) {
186 entry->_name = it->get_value();
187 } else {
188 add_entry(it->get_source_name(), it->get_line(), it->get_name(), it->get_value());
189 }
190 }
191 }
192
193 //! @brief Frees Entry tree.
194 void
195 CfgParser::Entry::free_tree(void)
...
235 @@ -177,6 +235,11 @@
235 CfgParser::~CfgParser(void)
236 {
237 _root_entry.free_tree();
238
239 map<string, CfgParser::Entry*>::iterator it(_section_map.begin());
240 for (; it != _section_map.end(); ++it) {
241 delete it->second;
242 }
243 }
244
245 //! @brief Parses source and fills root section with data.
...
276 @@ -213,7 +276,7 @@
276 break;
277 case '{':
278 if (parse_name(buf)) {
216 parse_section_finish (buf, value);
280 parse_section_finish(buf, value);
281 } else {
282 cerr << _("Ignoring section as name is empty.\n");
283 }
...
474 @@ -411,15 +474,25 @@
474 void
475 CfgParser::parse_entry_finish(std::string &buf, std::string &value)
476 {
414 if (! value.size()) {
478 if (value.size()) {
479 parse_entry_finish_standard(buf, value);
480 } else {
481 // Template handling, expand or define template.
482 if (buf.size() && parse_name(buf) && buf[0] == '@') {
483 parse_entry_finish_template(buf);
484 }
485 buf.clear();
423 return;
487 }
425
489 }
490 /**
491 * Finish standard entry.
492 */
493 void
494 CfgParser::parse_entry_finish_standard(std::string &buf, std::string &value)
495 {
496 if (parse_name(buf)) {
497 if (buf[0] == '$') {
498 variable_define(buf, value);
436
500 } else {
501 variable_expand(value);
502
...
512 @@ -439,6 +512,21 @@
512 buf.clear();
513 }
514
515 /**
516 * Finish template entry, copy data into current section.
517 */
518 void
519 CfgParser::parse_entry_finish_template(std::string &name)
520 {
521 map<string, CfgParser::Entry*>::iterator it(_section_map.find(name.c_str() + 1));
522 if (it == _section_map.end()) {
523 cerr << " *** WARNING: No such template " << name << endl;
524 return;
525 }
526
527 _entry->copy_tree_into(it->second);
528 }
529
530 //! @brief Creates new Section on {
531 void
532 CfgParser::parse_section_finish(std::string &buf, std::string &value)
...
534 @@ -446,9 +534,22 @@
534 _entry = _entry->add_entry(_source->get_name(), _source->get_line(), buf, value);
535 _entry_list.push_back(_entry);
536
449 // Create Entry representing Section and point to it.
538 // Create Entry representing Section
539 Entry *section = new Entry(_source->get_name(), _source->get_line(), buf, value);
452 _entry->set_section(section);
541 if (buf.size() == 6 && strcasecmp(buf.c_str(), "DEFINE") == 0) {
542 // Look for define section, started with Define = "Name" {
543 map<string, CfgParser::Entry*>::iterator it(_section_map.find(value));
544 if (it != _section_map.end()) {
545 delete it->second;
546 _section_map.erase(it);
547 }
548
549 _section_map[value] = section;
550 } else {
551 // Set section to current entry, if it is a Define section
552 // resource handling is done by the _section_map
553 _entry->set_section(section);
554 }
555
556 // Set current Entry to newly created Section.
557 _entry = section;
...
571 @@ -470,7 +571,7 @@
571
572 //! @brief Parses Source until */ is found.
573 void
473 CfgParser::parse_comment_c (CfgParserSource *source)
575 CfgParser::parse_comment_c(CfgParserSource *source)
576 {
577 int c;
578 while ((c = source->getc()) != EOF) {
...

src/CfgParser.hh
 
45 @@ -45,6 +45,7 @@
45 public:
46 Entry(const std::string &source_name, int line,
47 const std::string &name, const std::string &value);
48 Entry(const Entry &entry);
49 ~Entry(void);
50
51 //! @brief Returns the name.
...
57 @@ -56,6 +57,7 @@
57 //! @brief Returns the name of the source this was parsed.
58 const std::string &get_source_name(void) const { return _source_name; }
59
60 Entry *add_entry(Entry *entry);
61 Entry *add_entry(const std::string &source_name, int line,
62 const std::string &name, const std::string &value);
63
...
76 @@ -74,7 +76,7 @@
76 void parse_key_values(std::list<CfgParserKey*>::iterator begin,
77 std::list<CfgParserKey*>::iterator end);
78
77 void print_tree(int level);
80 void copy_tree_into(CfgParser::Entry *from, bool overwrite=true);
81 void free_tree(void);
82
83 //! @brief Matches Entry name agains op_rhs.
...
111 @@ -109,6 +111,8 @@
111 bool parse_name(std::string &buf);
112 bool parse_value(CfgParserSource *source, std::string &value);
113 void parse_entry_finish(std::string &buf, std::string &value);
114 void parse_entry_finish_standard(std::string &buf, std::string &value);
115 void parse_entry_finish_template(std::string &name);
116 void parse_section_finish(std::string &buf, std::string &value);
117 void parse_comment_line(CfgParserSource *source);
118 void parse_comment_c(CfgParserSource *source);
...
132 @@ -128,6 +132,7 @@
132 std::list<Entry*> _entry_list; //!< List of Entries with sections, for recursive parsing.
133
134 std::map<std::string, std::string> _var_map; //!< Map of $VARS
135 std::map<std::string, CfgParser::Entry*> _section_map; //!< Map of Define = ... sections
136
137 Entry _root_entry; //!< Root Entry.
138 Entry *_entry; //!< Current Entry.
...