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

4.104.115
Last change on this file since 6506aa1 was 6506aa1, checked in by Chris Johns <chrisj@…>, on Sep 8, 2014 at 6:06:48 AM

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: 5.4 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    const 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(const std::string& search_path)
82    {
83      set_search_path (search_path);
84    }
85
86    config::~config()
87    {
88    }
89
90    void
91    config::set_search_path (const std::string& search_path)
92    {
93      if (!search_path.empty ())
94        rld::path::path_split (search_path, search);
95    }
96
97    void
98    config::clear ()
99    {
100      secs.clear ();
101    }
102
103    void
104    config::load (const std::string& path)
105    {
106      CSimpleIniCaseA ini (false, true, true);
107
108      std::string checked_path;
109
110      if (rld::path::check_file (path))
111      {
112        checked_path = path;
113      }
114      else
115      {
116        bool found = false;
117        for (rld::path::paths::const_iterator spi = search.begin ();
118             spi != search.end ();
119             ++spi)
120        {
121          rld::path::path_join (*spi, path, checked_path);
122          if (rld::path::check_file (checked_path))
123          {
124            found = true;
125            break;
126          }
127        }
128        if (!found)
129          throw rld::error ("Not found.", "load config: " + path);
130      }
131
132      if (ini.LoadFile (checked_path.c_str ()) != SI_OK)
133        throw rld::error (::strerror (errno), "load config: " + path);
134
135      paths_.push_back (checked_path);
136
137      /*
138       * Merge the loaded configuration into our configuration.
139       */
140
141      CSimpleIniCaseA::TNamesDepend skeys;
142
143      ini.GetAllSections(skeys);
144
145      for (CSimpleIniCaseA::TNamesDepend::const_iterator si = skeys.begin ();
146           si != skeys.end ();
147           ++si)
148      {
149        section sec;
150
151        sec.name = (*si).pItem;
152
153        CSimpleIniCaseA::TNamesDepend rkeys;
154
155        ini.GetAllKeys((*si).pItem, rkeys);
156
157        for (CSimpleIniCaseA::TNamesDepend::const_iterator ri = rkeys.begin ();
158             ri != rkeys.end ();
159             ++ri)
160        {
161          record rec;
162
163          rec.name = (*ri).pItem;
164
165          CSimpleIniCaseA::TNamesDepend vals;
166
167          ini.GetAllValues((*si).pItem, (*ri).pItem, vals);
168
169          for (CSimpleIniCaseA::TNamesDepend::const_iterator vi = vals.begin ();
170               vi != vals.end ();
171               ++vi)
172          {
173            rec.items_.push_back (item ((*vi).pItem));
174          }
175
176          sec.recs.push_back (rec);
177        }
178
179        secs.push_back (sec);
180      }
181    }
182
183
184    void
185    config::includes (const section& sec, bool must_exist)
186    {
187      bool have_includes = false;
188
189      try
190      {
191        rld::strings is;
192        parse_items (sec, "include", is);
193
194        have_includes = true;
195
196        /*
197         * Include records are a paths which we can load.
198         */
199
200        for (rld::strings::const_iterator isi = is.begin ();
201             isi != is.end ();
202             ++isi)
203        {
204          load (*isi);
205        }
206      }
207      catch (rld::error re)
208      {
209        /*
210         * No include records, must be all inlined. If we have includes it must
211         * be another error so throw it.
212         */
213        if (have_includes || (!have_includes && must_exist))
214          throw;
215      }
216    }
217
218    const section&
219    config::get_section (const std::string& name) const
220    {
221      for (sections::const_iterator si = secs.begin ();
222           si != secs.end ();
223           ++si)
224      {
225        if ((*si).name == name)
226          return *si;
227      }
228
229      throw error ("not found", "config section: " + name);
230    }
231
232    const paths&
233    config::get_paths () const
234    {
235      return paths_;
236    }
237  }
238}
Note: See TracBrowser for help on using the repository browser.