source: rtems-tools/linkers/rld-config.h @ 2126ea7

4.104.115
Last change on this file since 2126ea7 was 6506aa1, checked in by Chris Johns <chrisj@…>, on 09/08/14 at 06:06:48

RTEMS trace linker builds trace applications.

The trace linker builds the both_hello example in examples-v2.

Move the various string support functions into a C++ file and stop being
inlined. Make them return const std::string.

Add ld support to rld-cc.

Add search path support to rld-config so installed common files can be used.

Fix the path bugs.

Add an absolute path function to rld-path.

  • Property mode set to 100644
File size: 7.0 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       * Find a record and throw an error if not found.
91       */
92      const record& get_record (const std::string& name) const;
93
94      /**
95       * Return the single item in a record. If the record is duplicated an
96       * error is thrown.
97       */
98      const std::string get_record_item (const std::string& name) const;
99
100      /**
101       * Return the list of items in a record in a strings container.
102       */
103      void get_record_items (const std::string& name, rld::strings& items_) const;
104    };
105
106    /**
107     * Configuration section container.
108     */
109    typedef std::list < section > sections;
110
111    /**
112     * Container of configuration file paths loaded.
113     */
114    typedef std::vector < std::string > paths;
115
116    /**
117     * The configuration.
118     */
119    class config
120    {
121    public:
122      /**
123       * Construct an empty configuration.
124       */
125      config(const std::string& search_path = "");
126
127      /**
128       * Desctruct the configuration object.
129       */
130      virtual ~config();
131
132      /**
133       * Set the search path.
134       */
135      void set_search_path (const std::string& search_path);
136
137      /**
138       * Clear the current configuration.
139       */
140      void clear ();
141
142      /**
143       * Load a configuration.
144       */
145      void load (const std::string& name);
146
147      /**
148       * Process any include records in the section named. If the section has
149       * any records named 'include' split the items and include the
150       * configuration files.
151       */
152      void includes (const section& sec, bool must_exist = false);
153
154      /**
155       * Get the section and throw an error if not found.
156       */
157      const section& get_section (const std::string& name) const;
158
159      /**
160       * Get the paths of loaded configuration files.
161       */
162      const paths& get_paths () const;
163
164    private:
165
166      paths    search; //< The paths to search for config files in.
167      paths    paths_; //< The path's of the loaded files.
168      sections secs;   //< The sections loaded from configuration files
169    };
170
171    /**
172     * Return the items from a record.
173     */
174    template < typename T >
175    void parse_items (const rld::config::record& record,
176                      T&                         items_,
177                      bool                       clear = true,
178                      bool                       split = true)
179    {
180      if (clear)
181        items_.clear ();
182      for (rld::config::items::const_iterator ii = record.items_.begin ();
183           ii != record.items_.end ();
184           ++ii)
185      {
186        if (split)
187        {
188          rld::strings ss;
189          rld::split (ss, (*ii).text, ',');
190          std::copy (ss.begin (), ss.end (), std::back_inserter (items_));
191        }
192        else
193        {
194          items_.push_back ((*ii).text);
195        }
196      }
197    }
198
199    /**
200     * Return the items from a record in a section. Optionally raise an error
201     * if the record is not found and it is to be present.
202     */
203    template < typename T >
204    void parse_items (const rld::config::section& section,
205                      const std::string&          name,
206                      T&                          items_,
207                      bool                        present = false,
208                      bool                        clear = true,
209                      bool                        split = true)
210    {
211      if (clear)
212        items_.clear ();
213      const rld::config::record* rec = 0;
214      try
215      {
216        const rld::config::record& rr = section.get_record (name);
217        rec = &rr;
218      }
219      catch (rld::error re)
220      {
221        /*
222         * Ignore the error if it does not need to exist.
223         */
224        if (present)
225          throw rld::error ("not found", "record: " + section.name + name);
226      }
227
228      if (rec)
229        parse_items (*rec, items_, clear, split);
230    }
231
232    /**
233     * Return the items from a record in a section in the
234     * configuration. Optionally raise an error if the section is not found and
235     * it is to be present.
236     */
237    template < typename T >
238    void parse_items (const rld::config::config& config,
239                      const std::string&         section,
240                      const std::string&         record,
241                      T&                         items_,
242                      bool                       present = false)
243    {
244      items_.clear ();
245      const rld::config::section* sec = 0;
246      try
247      {
248        const rld::config::section& sr = config.get_section (section);
249        sec = &sr;
250      }
251      catch (rld::error re)
252      {
253        /*
254         * Ignore the error if it does not need to exist.
255         */
256        if (present)
257          throw rld::error ("not found", "section: " + section);
258      }
259
260      if (sec)
261        parse_items (*sec, record, items_);
262    }
263  }
264}
265
266#endif
Note: See TracBrowser for help on using the repository browser.