feisty meow concerns codebase  2.140
system_values.cpp
Go to the documentation of this file.
1 /*****************************************************************************\
2 * *
3 * Name : system_values *
4 * Author : Chris Koeritz *
5 * *
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 \*****************************************************************************/
14 
15 #include "ini_configurator.h"
16 #include "system_values.h"
17 
18 #include <structures/int_hash.h>
20 #include <textual/list_parsing.h>
21 #include <textual/parser_bits.h>
22 #include "../algorithms/sorts.h"
23 
24 using namespace algorithms;
25 using namespace basis;
26 using namespace structures;
27 using namespace textual;
28 
29 namespace configuration {
30 
31 const int MAX_VALUE_BITS = 8; // we provide 2^n slots in hash.
32 
33 #undef LOG
34 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s)
35 
37 
38 class value_record
39 {
40 public:
41  astring _name; // the name of the value.
42  astring _descrip; // the description of the value.
43  astring _location; // the file defining the value.
44 
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) {}
49 };
50 
52 
53 class system_values_lookup_list : public int_hash<value_record>
54 {
55 public:
56  system_values_lookup_list() : int_hash<value_record>(MAX_VALUE_BITS) {}
57 
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);
66  if (!curr) {
67 //serious error.
68  continue;
69  }
70  if (curr->_name == name) {
71  // this is a match to the name they were seeking.
72  value = current_id;
73  return curr;
74  }
75  }
76  return NULL_POINTER;
77  }
78 };
79 
81 
82 system_values::system_values(const astring &section_tag)
83 : _tag(new astring(section_tag)),
84  _list(new system_values_lookup_list),
85  _file(new astring(DEFAULT_MANIFEST))
86 {
87  FUNCDEF("constructor");
88  open_values();
89 }
90 
92 {
93  WHACK(_list);
94  WHACK(_tag);
95  WHACK(_file);
96 }
97 
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.
101 
102 bool system_values::use_other_manifest(const astring &manifest_file)
103 {
104  *_file = manifest_file;
105  return open_values();
106 }
107 
108 const char *system_values::OUTCOME_VALUES() { return "DEFINE_OUTCOME"; }
109 
110 const char *system_values::FILTER_VALUES() { return "DEFINE_FILTER"; }
111 
112 const char *system_values::EVENT_VALUES() { return "DEFINE_EVENT"; }
113 
114 bool system_values::open_values()
115 {
116  FUNCDEF("open_values");
119 
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++) {
124 
125  string_array items;
126  list_parsing::parse_csv_line(full_section.name(i), items);
127  if (items.length() < 4) {
128  continue;
129  }
130 
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);
134  }
135 
136  return true;
137 }
138 
139 #define SV_EOL parser_bits::platform_eol_to_chars()
140 
141 //hmmm: it might be nice to have an alternate version sorted by name...
142 
144 {
145  int_set cids = _list->ids();
146 
147  if (!_tag->equal_to("DEFINE_OUTCOME")) {
148  // sort the list in identifier order.
149  shell_sort(cids.access(), cids.elements());
150  } else {
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);
154  }
155 
156  astring to_return("values for ");
157  to_return += *_tag;
158  to_return += SV_EOL;
159  for (int i = 0; i < cids.elements(); i++) {
160  int current_id = cids[i];
161  value_record *curr = _list->find(current_id);
162  if (!curr) {
163 //serious error.
164  continue;
165  }
166  to_return += a_sprintf("%d: ", current_id);
167  to_return += curr->_name + " \"" + curr->_descrip + "\" from "
168  + curr->_location;
169  to_return += SV_EOL;
170  }
171  return to_return;
172 }
173 
174 bool system_values::lookup(int value, astring &symbolic_name,
175  astring &description, astring &file_location)
176 {
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;
182  return true;
183 }
184 
185 bool system_values::lookup(const astring &symbolic_name, int &value,
186  astring &description, astring &file_location)
187 {
188  value_record *found = _list->text_find(symbolic_name, value);
189  if (!found) return false;
190  description = found->_descrip;
191  file_location = found->_location;
192  return true;
193 }
194 
195 int system_values::elements() const { return _list->ids().elements(); }
196 
197 bool system_values::get(int index, astring &symbolic_name, int &value,
198  astring &description, astring &file_location)
199 {
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);
203 }
204 
205 } //namespace.
206 
207 
a_sprintf is a specialization of astring that provides printf style support.
Definition: astring.h:440
contents * access()
A non-constant access of the underlying C-array. BE REALLY CAREFUL.
Definition: array.h:175
int length() const
Returns the current reported length of the allocated C array.
Definition: array.h:115
Provides a dynamically resizable ASCII character string.
Definition: astring.h:35
bool equal_to(const char *that) const
returns true if "that" is equal to this.
Definition: astring.cpp:159
Supports a configurator-based interface on text initialization files.
@ APPLICATION_DIRECTORY
config files live with application.
bool use_other_manifest(const basis::astring &manifest_file)
supports using a different manifest file than the default.
bool get(int index, basis::astring &symbolic_name, int &value, basis::astring &description, basis::astring &file_location)
accesses the "index"th item in the list.
static const char * EVENT_VALUES()
values that define event objects used in the program.
bool lookup(int value, basis::astring &symbolic_name, basis::astring &description, basis::astring &file_location)
locates a "value" and finds its name, description and location.
static const char * FILTER_VALUES()
values that define filters used in logging.
virtual basis::astring text_form() const
shows all items in the table.
int elements() const
returns how many items are listed for the types of values specified.
static const char * DEFAULT_MANIFEST
the default manifest file.
Definition: system_values.h:70
static const char * OUTCOME_VALUES()
values that define the outcomes of operations.
A hash table for storing integers.
Definition: int_hash.h:36
A simple object that wraps a templated set of ints.
Definition: set.h:156
int elements() const
Returns the number of elements in this set.
Definition: set.h:47
An array of strings with some additional helpful methods.
Definition: string_array.h:32
Provides a symbol_table that holds strings as the content.
Definition: string_table.h:32
const basis::astring & name(int index) const
returns the name held at the "index".
Definition: symbol_table.h:272
int symbols() const
returns the number of symbols listed in the table.
Definition: symbol_table.h:241
#define NULL_POINTER
The value representing a pointer to nothing.
Definition: definitions.h:32
#define FUNCDEF(func_in)
FUNCDEF sets the name of a function (and plugs it into the callstack).
Definition: enhance_cpp.h:57
#define bounds_return(value, low, high, to_return)
Verifies that "value" is between "low" and "high", inclusive.
Definition: guards.h:48
void shell_sort(type v[], int n, bool reverse=false)
shell sort algorithm.
Definition: sorts.h:55
The guards collection helps in testing preconditions and reporting errors.
Definition: array.h:30
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
Definition: functions.h:121
const int MAX_VALUE_BITS
A dynamic container class that holds any kind of object via pointers.
Definition: amorph.h:55
#define SV_EOL