source: rtems-tools/rtemstoolkit/rld-config.h @ 36e6631

4.104.115
Last change on this file since 36e6631 was 5025439, checked in by Chris Johns <chrisj@…>, on 09/21/14 at 04:24:37

rtems-tld: Add config options, fix void args, and SCore traces.

  • Property mode set to 100644
File size: 7.1 KB
Line 
1/*
2 * Copyright (c) 2014, Chris Johns <chrisj@rtems.org>
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16/**
17 * @file
18 *
19 * @ingroup rtems_rld
20 *
21 * @brief INI Configuration reader.
22 *
23 */
24
25#if !defined (_RLD_CONFIG_H_)
26#define _RLD_CONFIG_H_
27
28#include <string>
29#include <list>
30#include <vector>
31
32#include <rld.h>
33
34namespace rld
35{
36  namespace config
37  {
38    /**
39     * The configuration item. This is a data component of a record contained
40     * in a section.
41     */
42    struct item
43    {
44      std::string text; /**< The text as read from the configuration. */
45
46      /**
47       * Construct an item.
48       */
49      item (const std::string& text);
50      item (const char*        text);
51    };
52
53    /**
54     * Configuration item container.
55     */
56    typedef std::vector < item > items;
57
58    /**
59     * Configuration record is a line in a section. There can be multiple
60     * records with the same key in a section. Keys are specific to a section.
61     */
62    struct record
63    {
64      std::string name;   //< Name of the record.
65      items       items_; //< The record's items.
66
67      /**
68       * Return true if there is only one item.
69       */
70      bool single () const {
71        return items_.size () == 1;
72      }
73    };
74
75    /**
76     * Configuration record container.
77     */
78    typedef std::list < record > records;
79
80    /**
81     * Configuration section. A section contains a number of records and the
82     * records contain [1..n] items.
83     */
84    struct section
85    {
86      std::string name;  //< Name of the section.
87      records     recs;  //< The section's records.
88
89      /**
90       * Has the section got a record ?
91       */
92      bool has_record (const std::string& name) const;
93
94      /**
95       * Find a record and throw an error if not found.
96       */
97      const record& get_record (const std::string& name) const;
98
99      /**
100       * Return the single item in a record. If the record is duplicated an
101       * error is thrown.
102       */
103      const std::string get_record_item (const std::string& name) const;
104
105      /**
106       * Return the list of items in a record in a strings container.
107       */
108      void get_record_items (const std::string& name, rld::strings& items_) const;
109    };
110
111    /**
112     * Configuration section container.
113     */
114    typedef std::list < section > sections;
115
116    /**
117     * Container of configuration file paths loaded.
118     */
119    typedef std::vector < std::string > paths;
120
121    /**
122     * The configuration.
123     */
124    class config
125    {
126    public:
127      /**
128       * Construct an empty configuration.
129       */
130      config(const std::string& search_path = "");
131
132      /**
133       * Desctruct the configuration object.
134       */
135      virtual ~config();
136
137      /**
138       * Set the search path.
139       */
140      void set_search_path (const std::string& search_path);
141
142      /**
143       * Clear the current configuration.
144       */
145      void clear ();
146
147      /**
148       * Load a configuration.
149       */
150      void load (const std::string& name);
151
152      /**
153       * Process any include records in the section named. If the section has
154       * any records named 'include' split the items and include the
155       * configuration files.
156       */
157      void includes (const section& sec, bool must_exist = true);
158
159      /**
160       * Get the section and throw an error if not found.
161       */
162      const section& get_section (const std::string& name) const;
163
164      /**
165       * Get the paths of loaded configuration files.
166       */
167      const paths& get_paths () const;
168
169    private:
170
171      paths    search; //< The paths to search for config files in.
172      paths    paths_; //< The path's of the loaded files.
173      sections secs;   //< The sections loaded from configuration files
174    };
175
176    /**
177     * Return the items from a record.
178     */
179    template < typename T >
180    void parse_items (const rld::config::record& record,
181                      T&                         items_,
182                      bool                       clear = true,
183                      bool                       split = true)
184    {
185      if (clear)
186        items_.clear ();
187      for (rld::config::items::const_iterator ii = record.items_.begin ();
188           ii != record.items_.end ();
189           ++ii)
190      {
191        if (split)
192        {
193          rld::strings ss;
194          rld::split (ss, (*ii).text, ',');
195          std::copy (ss.begin (), ss.end (), std::back_inserter (items_));
196        }
197        else
198        {
199          items_.push_back ((*ii).text);
200        }
201      }
202    }
203
204    /**
205     * Return the items from a record in a section. Optionally raise an error
206     * if the record is not found and it is to be present.
207     */
208    template < typename T >
209    void parse_items (const rld::config::section& section,
210                      const std::string&          name,
211                      T&                          items_,
212                      bool                        present = false,
213                      bool                        clear = true,
214                      bool                        split = true)
215    {
216      if (clear)
217        items_.clear ();
218      const rld::config::record* rec = 0;
219      try
220      {
221        const rld::config::record& rr = section.get_record (name);
222        rec = &rr;
223      }
224      catch (rld::error re)
225      {
226        /*
227         * Ignore the error if it does not need to exist.
228         */
229        if (present)
230          throw rld::error ("not found", "record: " + section.name + name);
231      }
232
233      if (rec)
234        parse_items (*rec, items_, clear, split);
235    }
236
237    /**
238     * Return the items from a record in a section in the
239     * configuration. Optionally raise an error if the section is not found and
240     * it is to be present.
241     */
242    template < typename T >
243    void parse_items (const rld::config::config& config,
244                      const std::string&         section,
245                      const std::string&         record,
246                      T&                         items_,
247                      bool                       present = false)
248    {
249      items_.clear ();
250      const rld::config::section* sec = 0;
251      try
252      {
253        const rld::config::section& sr = config.get_section (section);
254        sec = &sr;
255      }
256      catch (rld::error re)
257      {
258        /*
259         * Ignore the error if it does not need to exist.
260         */
261        if (present)
262          throw rld::error ("not found", "section: " + section);
263      }
264
265      if (sec)
266        parse_items (*sec, record, items_);
267    }
268  }
269}
270
271#endif
Note: See TracBrowser for help on using the repository browser.