first check-in of feisty meow codebase. many things broken still due to recent
[feisty_meow.git] / core / library / configuration / table_configurator.cpp
1 /*****************************************************************************\
2 *                                                                             *
3 *  Name   : table_configurator                                                *
4 *  Author : Chris Koeritz                                                     *
5 *                                                                             *
6 *******************************************************************************
7 * Copyright (c) 2001-$now By Author.  This program is free software; you can  *
8 * redistribute it and/or modify it under the terms of the GNU General Public  *
9 * License as published by the Free Software Foundation; either version 2 of   *
10 * the License or (at your option) any later version.  This is online at:      *
11 *     http://www.fsf.org/copyleft/gpl.html                                    *
12 * Please send any updates to: fred@gruntose.com                               *
13 \*****************************************************************************/
14
15 #include "table_configurator.h"
16
17 #include <basis/astring.h>
18 #include <basis/functions.h>
19 #include <structures/string_array.h>
20 #include <structures/string_table.h>
21
22 using namespace basis;
23 using namespace structures;
24
25 namespace configuration {
26
27 #undef LOG
28 #define LOG(to_print) printf("%s::%s: %s\n", static_class_name(), func, astring(to_print).s())
29
30 class table_o_string_tables : public symbol_table<string_table>
31 {
32 public:
33 };
34
35 //////////////
36
37 table_configurator::table_configurator(treatment_of_defaults behavior)
38 : configurator(behavior),
39   _real_table(new table_o_string_tables)
40 {}
41
42 table_configurator::table_configurator(const table_configurator &to_copy)
43 : configurator(to_copy.behavior()),
44   _real_table(new table_o_string_tables)
45 { *this = to_copy; }
46
47 table_configurator::~table_configurator()
48 {
49   WHACK(_real_table);
50 }
51
52 table_configurator &table_configurator::operator =
53     (const table_configurator &to_copy)
54 {
55   if (this == &to_copy) return *this;
56   reset();
57   string_array sects;
58   const_cast<table_configurator &>(to_copy).sections(sects);
59   for (int sectindy = 0; sectindy < sects.length(); sectindy++) {
60     // every entry in the current section gets added to our current config.
61     astring curr_section = sects[sectindy];
62     string_table entries;
63         const_cast<table_configurator &>(to_copy).get_section(curr_section, entries);
64     put_section(curr_section, entries);
65   }
66
67   return *this;
68 }
69
70 void table_configurator::reset() { _real_table->reset(); }
71
72 bool table_configurator::section_exists(const astring &section)
73 { return !!_real_table->find(section); }
74
75 void table_configurator::sections(string_array &to_fill)
76 {
77   to_fill.reset();
78   for (int i = 0; i < _real_table->symbols(); i++)
79     to_fill += _real_table->name(i);
80 }
81
82 bool table_configurator::delete_section(const astring &section)
83 { return _real_table->whack(section) == common::OKAY; }
84
85 bool table_configurator::delete_entry(const astring &section,
86     const astring &ent)
87 {
88   string_table *sect = _real_table->find(section);
89   if (!sect) return false;
90   return sect->whack(ent) == common::OKAY;
91 }
92
93 bool table_configurator::put(const astring &section,
94     const astring &entry, const astring &to_store)
95 {
96   if (!to_store.length()) return delete_entry(section, entry);
97   else if (!entry.length()) return delete_section(section);
98   string_table *sect = _real_table->find(section);
99   if (!sect) {
100     // none exists yet, so add one.
101     _real_table->add(section, string_table());
102     sect = _real_table->find(section);
103   }
104   sect->add(entry, to_store);
105   return true;
106 }
107
108 bool table_configurator::get(const astring &section,
109     const astring &entry, astring &found)
110 {
111   found = "";
112   string_table *sect = _real_table->find(section);
113   if (!sect) return false;
114   astring *looked = sect->find(entry);
115   if (!looked) return false;
116   found = *looked;
117   return true;
118 }
119
120 /*
121 scavenge?
122 bool is_comment(char to_check, const char *comment_list)
123 {
124   int len = int(strlen(comment_list));
125   for (int i = 0; i < len; i++) {
126     if (to_check == comment_list[i])
127       return true;
128   }
129   return false;
130 }
131 */
132
133 /* scavenge?
134 //hmmm: could we move the commented and clean_comments methods into
135 //      parser bits?
136 //      yes!  we should move those; they are no longer used here!
137
138 bool table_configurator::commented(const astring &to_check,
139     const char *comment_list)
140 {
141   for (int i = 0; i < to_check.length(); i++) {
142     if (white_space(to_check[i]))
143       continue;  // skip spaces.
144     if (is_comment(to_check[i], comment_list))
145       return true;  // started with a comment.
146     return false;  // we had our chance for a comment, but that wasn't it.
147   }
148   return false;
149 }
150
151 astring table_configurator::clean_comments(const astring &to_clean,
152     const char *comment_list)
153 {
154   FUNCDEF("clean_comments");
155 //LOG(astring("clean in with: ") + to_clean);
156   astring to_return(' ', to_clean.length());  // make a long enough string.
157   to_return.reset();  // keep allocated buffer size, but throw out contents.
158   for (int i = 0; i < to_clean.length(); i++) {
159     if (is_comment(to_clean[i], comment_list)) {
160       // here we go; the rest is commented out.
161       break;
162     }
163     to_return += to_clean[i];
164   }
165 //LOG(astring("clean out with: ") + to_return);
166   return to_return;
167 }
168 */
169
170 bool table_configurator::get_section(const astring &section,
171     string_table &info)
172 {
173 ///  FUNCDEF("get_section");
174   info.reset();
175   string_table *sect = _real_table->find(section);
176   if (!sect) return false;
177   for (int i = 0; i < sect->symbols(); i++)
178     info.add(sect->name(i), (*sect)[i]);
179   return true;
180 }
181
182 bool table_configurator::put_section(const astring &section,
183     const string_table &info)
184 {
185 ///  FUNCDEF("put_section");
186   string_table *sect = _real_table->find(section);
187   if (!sect) {
188     // none exists yet, so add one.
189     _real_table->add(section, string_table());
190     sect = _real_table->find(section);
191   }
192   *sect = info;
193   return true;
194 }
195
196 } //namespace.
197