1 /*****************************************************************************\
3 * Name : system_values *
4 * Author : Chris Koeritz *
6 *******************************************************************************
7 * Copyright (c) 2004-$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 \*****************************************************************************/
15 #include "ini_configurator.h"
16 #include "system_values.h"
18 #include <structures/int_hash.h>
19 #include <structures/string_table.h>
20 #include <textual/list_parsing.h>
21 #include <textual/parser_bits.h>
22 #include "../algorithms/sorts.h"
24 using namespace algorithms;
25 using namespace basis;
26 using namespace structures;
27 using namespace textual;
29 namespace configuration {
31 const int MAX_VALUE_BITS = 8; // we provide 2^n slots in hash.
34 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
41 astring _name; // the name of the value.
42 astring _descrip; // the description of the value.
43 astring _location; // the file defining the value.
45 value_record(const astring &name = astring::empty_string(),
46 const astring &description = astring::empty_string(),
47 const astring &location = astring::empty_string())
48 : _name(name), _descrip(description), _location(location) {}
53 class system_values_lookup_list : public int_hash<value_record>
56 system_values_lookup_list() : int_hash<value_record>(MAX_VALUE_BITS) {}
58 // finds the symbolic "name" in the table, which is not as efficient as
59 // lookin up integers.
60 value_record *text_find(const astring &name, int &value) {
61 // scoot across all of the ids.
62 const int_set &cids = ids();
63 for (int i = 0; i < cids.elements(); i++) {
64 int current_id = cids[i];
65 value_record *curr = find(current_id);
70 if (curr->_name == name) {
71 // this is a match to the name they were seeking.
82 system_values::system_values(const astring §ion_tag)
83 : _tag(new astring(section_tag)),
84 _list(new system_values_lookup_list),
85 _file(new astring(DEFAULT_MANIFEST))
87 FUNCDEF("constructor");
91 system_values::~system_values()
98 const char *system_values::DEFAULT_MANIFEST = "manifest.txt";
99 // this is the default manifest and it is expected to live right in
100 // the folder where the applications are.
102 bool system_values::use_other_manifest(const astring &manifest_file)
104 *_file = manifest_file;
105 return open_values();
108 const char *system_values::OUTCOME_VALUES() { return "DEFINE_OUTCOME"; }
110 const char *system_values::FILTER_VALUES() { return "DEFINE_FILTER"; }
112 const char *system_values::EVENT_VALUES() { return "DEFINE_EVENT"; }
114 bool system_values::open_values()
116 FUNCDEF("open_values");
117 ini_configurator ini(*_file, ini_configurator::RETURN_ONLY,
118 ini_configurator::APPLICATION_DIRECTORY);
120 string_table full_section;
121 bool got_section = ini.get_section(*_tag, full_section);
122 if (!got_section) return false; // nothing there to look up.
123 for (int i = 0; i < full_section.symbols(); i++) {
126 list_parsing::parse_csv_line(full_section.name(i), items);
127 if (items.length() < 4) {
131 value_record *entry = new value_record(items[0], items[2], items[3]);
132 int value = items[1].convert(0);
133 _list->add(value, entry);
139 #define SV_EOL parser_bits::platform_eol_to_chars()
141 //hmmm: it might be nice to have an alternate version sorted by name...
143 astring system_values::text_form() const
145 int_set cids = _list->ids();
147 if (!_tag->equal_to("DEFINE_OUTCOME")) {
148 // sort the list in identifier order.
149 shell_sort(cids.access(), cids.elements());
151 // sort the list in reverse identifier order, since zero is first
152 // for outcomes and then they go negative.
153 shell_sort(cids.access(), cids.elements(), true);
156 astring to_return("values for ");
159 for (int i = 0; i < cids.elements(); i++) {
160 int current_id = cids[i];
161 value_record *curr = _list->find(current_id);
166 to_return += a_sprintf("%d: ", current_id);
167 to_return += curr->_name + " \"" + curr->_descrip + "\" from "
174 bool system_values::lookup(int value, astring &symbolic_name,
175 astring &description, astring &file_location)
177 value_record *found = _list->find(value);
178 if (!found) return false;
179 symbolic_name = found->_name;
180 description = found->_descrip;
181 file_location = found->_location;
185 bool system_values::lookup(const astring &symbolic_name, int &value,
186 astring &description, astring &file_location)
188 value_record *found = _list->text_find(symbolic_name, value);
189 if (!found) return false;
190 description = found->_descrip;
191 file_location = found->_location;
195 int system_values::elements() const { return _list->ids().elements(); }
197 bool system_values::get(int index, astring &symbolic_name, int &value,
198 astring &description, astring &file_location)
200 bounds_return(index, 0, _list->ids().elements() - 1, false); // bad index.
201 value = _list->ids()[index];
202 return lookup(value, symbolic_name, description, file_location);