source: rtems-tools/linkers/rld-config.cpp @ e5165d2

4.104.115
Last change on this file since e5165d2 was 097f1fd, checked in by Chris Johns <chrisj@…>, on 08/07/14 at 08:15:06

rtms-tld: Refactor the code to match a better configuration format.

  • Property mode set to 100644
File size: 4.9 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#include <errno.h>
26
27#include <rld-config.h>
28
29#include <SimpleIni.h>
30
31namespace rld
32{
33  namespace config
34  {
35    item::item (const std::string& text)
36      : text (text)
37    {
38    }
39
40    item::item (const char* text)
41      : text (text)
42    {
43    }
44
45    const record&
46    section::get_record (const std::string& name) const
47    {
48      for (records::const_iterator ri = recs.begin ();
49           ri != recs.end ();
50           ++ri)
51      {
52        if ((*ri).name == name)
53          return *ri;
54      }
55
56      throw error ("not found", "config record: " + this->name + '/' + name);
57    }
58
59    std::string
60    section::get_record_item (const std::string& rec_name) const
61    {
62      const record& rec = get_record (rec_name);
63      if (rec.items_.size () != 1)
64        throw rld::error ("duplicate", "record item: " + name + '/' + rec_name);
65      return rec.items_[0].text;
66    }
67
68    void
69    section::get_record_items (const std::string& rec_name, rld::strings& items) const
70    {
71      const record& rec = get_record (rec_name);
72      items.clear ();
73      for (rld::config::items::const_iterator ii = rec.items_.begin ();
74           ii != rec.items_.end ();
75           ++ii)
76      {
77        items.push_back ((*ii).text);
78      }
79    }
80
81    config::config()
82    {
83    }
84
85    config::~config()
86    {
87    }
88
89    void
90    config::clear ()
91    {
92      secs.clear ();
93    }
94
95    void
96    config::load (const std::string& path)
97    {
98      CSimpleIniCaseA ini (false, true, true);
99
100      if (ini.LoadFile (path.c_str ()) != SI_OK)
101        throw rld::error (::strerror (errno), "load config: " + path);
102
103      paths_.push_back (path);
104
105      /*
106       * Merge the loaded configuration into our configuration.
107       */
108
109      CSimpleIniCaseA::TNamesDepend skeys;
110
111      ini.GetAllSections(skeys);
112
113      for (CSimpleIniCaseA::TNamesDepend::const_iterator si = skeys.begin ();
114           si != skeys.end ();
115           ++si)
116      {
117        section sec;
118
119        sec.name = (*si).pItem;
120
121        CSimpleIniCaseA::TNamesDepend rkeys;
122
123        ini.GetAllKeys((*si).pItem, rkeys);
124
125        for (CSimpleIniCaseA::TNamesDepend::const_iterator ri = rkeys.begin ();
126             ri != rkeys.end ();
127             ++ri)
128        {
129          record rec;
130
131          rec.name = (*ri).pItem;
132
133          CSimpleIniCaseA::TNamesDepend vals;
134
135          ini.GetAllValues((*si).pItem, (*ri).pItem, vals);
136
137          for (CSimpleIniCaseA::TNamesDepend::const_iterator vi = vals.begin ();
138               vi != vals.end ();
139               ++vi)
140          {
141            rec.items_.push_back (item ((*vi).pItem));
142          }
143
144          sec.recs.push_back (rec);
145        }
146
147        secs.push_back (sec);
148      }
149    }
150
151
152    void
153    config::includes (const section& sec, bool must_exist)
154    {
155      bool have_includes = false;
156
157      try
158      {
159        rld::strings is;
160        parse_items (sec, "include", is);
161
162        have_includes = true;
163
164        /*
165         * Include records are a path which we can just load.
166         *
167         * @todo Add a search path. See 'rld::files' for details. We can default
168         *       the search path to the install $prefix of this tool and we can
169         *       then provide a default set of function signatures for RTEMS
170         *       APIs.
171         */
172
173        for (rld::strings::const_iterator isi = is.begin ();
174             isi != is.end ();
175             ++isi)
176        {
177          load (*isi);
178        }
179      }
180      catch (rld::error re)
181      {
182        /*
183         * No include records, must be all inlined. If we have includes it must
184         * be another error so throw it.
185         */
186        if (have_includes || (!have_includes && must_exist))
187          throw;
188      }
189    }
190
191    const section&
192    config::get_section (const std::string& name) const
193    {
194      for (sections::const_iterator si = secs.begin ();
195           si != secs.end ();
196           ++si)
197      {
198        if ((*si).name == name)
199          return *si;
200      }
201
202      throw error ("not found", "config section: " + name);
203    }
204
205    const paths&
206    config::get_paths () const
207    {
208      return paths_;
209    }
210  }
211}
Note: See TracBrowser for help on using the repository browser.