source: rtems-tools/linkers/rld-config.h @ 6fb1409

4.104.115
Last change on this file since 6fb1409 was 6fb1409, checked in by Chris Johns <chrisj@…>, on 09/08/14 at 22:20:41

rtems-tld: Add entry and exit trace support.

  • Property mode set to 100644
File size: 7.1 KB
RevLine 
[ea29902]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
[b6d7f5f]32#include <rld.h>
33
[ea29902]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.
[097f1fd]65      items       items_; //< The record's items.
[b6d7f5f]66
67      /**
68       * Return true if there is only one item.
69       */
70      bool single () const {
[097f1fd]71        return items_.size () == 1;
[b6d7f5f]72      }
[ea29902]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
[6fb1409]89      /**
90       * Has the section got a record ?
91       */
92      bool has_record (const std::string& name) const;
93
[ea29902]94      /**
95       * Find a record and throw an error if not found.
96       */
97      const record& get_record (const std::string& name) const;
[058d502]98
99      /**
100       * Return the single item in a record. If the record is duplicated an
101       * error is thrown.
102       */
[6506aa1]103      const std::string get_record_item (const std::string& name) const;
[058d502]104
105      /**
106       * Return the list of items in a record in a strings container.
107       */
[097f1fd]108      void get_record_items (const std::string& name, rld::strings& items_) const;
[ea29902]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       */
[6506aa1]130      config(const std::string& search_path = "");
131
132      /**
133       * Desctruct the configuration object.
134       */
[ea29902]135      virtual ~config();
136
[6506aa1]137      /**
138       * Set the search path.
139       */
140      void set_search_path (const std::string& search_path);
141
[ea29902]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
[b6d7f5f]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 = false);
158
[ea29902]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
[6506aa1]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
[ea29902]174    };
[b6d7f5f]175
176    /**
177     * Return the items from a record.
178     */
179    template < typename T >
[097f1fd]180    void parse_items (const rld::config::record& record,
181                      T&                         items_,
182                      bool                       clear = true,
183                      bool                       split = true)
[b6d7f5f]184    {
[097f1fd]185      if (clear)
186        items_.clear ();
187      for (rld::config::items::const_iterator ii = record.items_.begin ();
188           ii != record.items_.end ();
[b6d7f5f]189           ++ii)
190      {
[097f1fd]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        }
[b6d7f5f]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,
[097f1fd]211                      T&                          items_,
212                      bool                        present = false,
213                      bool                        clear = true,
214                      bool                        split = true)
[b6d7f5f]215    {
[097f1fd]216      if (clear)
217        items_.clear ();
[b6d7f5f]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)
[097f1fd]234        parse_items (*rec, items_, clear, split);
[b6d7f5f]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,
[097f1fd]246                      T&                         items_,
[b6d7f5f]247                      bool                       present = false)
248    {
[097f1fd]249      items_.clear ();
[b6d7f5f]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)
[097f1fd]266        parse_items (*sec, record, items_);
[b6d7f5f]267    }
[ea29902]268  }
269}
270
271#endif
Note: See TracBrowser for help on using the repository browser.