source: rtems-tools/rtemstoolkit/rld.cpp @ 0c0b2d4

4.10
Last change on this file since 0c0b2d4 was 0c0b2d4, checked in by Chris Johns <chrisj@…>, on Apr 3, 2016 at 5:37:01 AM

rtemstoolkit: Add version number parsing to get major, minor, revision.

Add support to return the major, minor or revision numbers as numbers.

  • Property mode set to 100644
File size: 8.7 KB
Line 
1/*
2 * Copyright (c) 2011, 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_ld
20 *
21 * @brief RTEMS Linker.
22 *
23 */
24
25#if HAVE_CONFIG_H
26#include "config.h"
27#endif
28
29#include <iostream>
30
31#include <sys/stat.h>
32
33#include <rld.h>
34
35namespace rld
36{
37  static int verbose_level = 0;
38
39  /**
40   * The program's command line.
41   */
42  static std::string cmdline;
43
44  /**
45   * The program name as set by the caller.
46   */
47  static std::string progname;
48
49  /**
50   * The option container.
51   */
52  typedef std::vector < std::string > library_container;
53
54  /**
55   * The libraries the user provided on the command line.
56   */
57  static library_container libpaths;
58
59  /**
60   * The libraries pass on the command line.
61   */
62  static library_container libs;
63
64  /**
65   * The libraries.
66   */
67  static library_container libraries;
68
69  /**
70   * The version major number.
71   */
72  static uint64_t _version_major;
73
74  /**
75   * The version minor number.
76   */
77  static uint64_t _version_minor;
78
79  /**
80   * The version revision number.
81   */
82  static uint64_t _version_revision;
83
84  bool
85  starts_with(const std::string& s1, const std::string& s2)
86  {
87    return s2.size () <= s1.size () && s1.compare (0, s2.size (), s2) == 0;
88  }
89
90  const std::string
91  ltrim (const std::string& s)
92  {
93    std::string t = s;
94    t.erase (t.begin (),
95             std::find_if (t.begin (), t.end (),
96                         std::not1 (std::ptr_fun < int, int > (std::isspace))));
97    return t;
98  }
99
100  const std::string
101  rtrim (const std::string& s)
102  {
103    std::string t = s;
104    t.erase (std::find_if (t.rbegin (), t.rend (),
105                           std::not1 (std::ptr_fun < int, int > (std::isspace))).base(),
106             t.end());
107    return t;
108  }
109
110  const std::string
111  trim (const std::string& s)
112  {
113    return ltrim (rtrim (s));
114  }
115
116  const std::string
117  dequote (const std::string& s)
118  {
119    if (!s.empty ())
120    {
121      char front = s[0];
122      char back = s[s.length () - 1];
123      if ((front == '"') || (front == '\''))
124      {
125        if (front != back)
126          throw rld::error ("invalid quoting", "string: " + s);
127        return s.substr (1, s.length () - (1 + 1));
128      }
129    }
130    return s;
131  }
132
133  const std::string
134  find_replace(const std::string& sin,
135               const std::string& out,
136               const std::string& in)
137  {
138    std::string s = sin;
139    size_t      pos = 0;
140    while ((pos = s.find (out, pos)) != std::string::npos)
141    {
142      s.replace (pos, out.length (), in);
143      pos += in.length ();
144    }
145    return s;
146  }
147
148  const strings
149  split (strings&           se,
150         const std::string& s,
151         char               delimiter,
152         bool               strip_quotes,
153         bool               strip_whitespace,
154         bool               empty)
155  {
156    std::stringstream ss(s);
157    std::string       e;
158    se.clear ();
159    while (std::getline (ss, e, delimiter))
160    {
161      if (strip_whitespace)
162        e = trim (e);
163      if (strip_quotes)
164        e = dequote (e);
165      if (empty || !e.empty ())
166      {
167        se.push_back (e);
168      }
169    }
170    return se;
171  }
172
173  const std::string
174  join (const strings& ss, const std::string& separator)
175  {
176    std::string s;
177    for (strings::const_iterator ssi = ss.begin ();
178         ssi != ss.end ();
179         ++ssi)
180    {
181      s += *ssi;
182      if ((ssi + 1) != ss.end ())
183        s += separator;
184    }
185    return s;
186  }
187
188  const std::string
189  tolower (const std::string& sin)
190  {
191    std::string s = sin;
192    std::transform (s.begin (), s.end (), s.begin (), ::tolower);
193    return s;
194  }
195
196  void
197  version_parse (const std::string& str,
198                 uint64_t&          major,
199                 uint64_t&          minor,
200                 uint64_t&          revision)
201  {
202    strings parts;
203
204    rld::split (parts, str, '.');
205
206    if (parts.size () >= 1)
207    {
208      std::istringstream iss (parts[0]);
209      iss >> major;
210    }
211
212    if (parts.size () >= 2)
213    {
214      std::istringstream iss (parts[1]);
215      iss >> minor;
216    }
217
218    if (parts.size () >= 3)
219    {
220      size_t p = parts[2].find ('_');
221
222      if (p != std::string::npos)
223        parts[2].erase (p);
224
225      std::istringstream iss (parts[2]);
226
227      if (p != std::string::npos)
228        iss >> std::hex;
229
230      iss >> revision;
231    }
232  }
233
234  void
235  verbose_inc ()
236  {
237    ++verbose_level;
238  }
239
240  int
241  verbose (int level)
242  {
243    return verbose_level && (verbose_level >= level) ? verbose_level : 0;
244  }
245
246  const std::string
247  version ()
248  {
249    return RTEMS_RELEASE;
250  }
251
252  uint64_t
253  version_major ()
254  {
255    if (_version_major == 0)
256      version_parse (version (),
257                     _version_major,
258                     _version_minor,
259                     _version_revision);
260    return _version_major;
261  }
262
263  uint64_t
264  version_minor ()
265  {
266    if (_version_major == 0)
267      version_parse (version (),
268                     _version_major,
269                     _version_minor,
270                     _version_revision);
271    return _version_minor;
272  }
273
274  uint64_t
275  version_revision ()
276  {
277    if (_version_major == 0)
278      version_parse (version (),
279                     _version_major,
280                     _version_minor,
281                     _version_revision);
282    return _version_revision;
283  }
284
285  void
286  set_cmdline (int argc, char* argv[])
287  {
288    cmdline.clear ();
289    for (int arg = 0; arg < argc; ++arg)
290    {
291      std::string a = argv[arg];
292      cmdline += ' ' + a;
293    }
294    cmdline = rld::trim (cmdline);
295  }
296
297  const std::string
298  get_cmdline ()
299  {
300    return cmdline;
301  }
302
303  void
304  set_progname (const std::string& progname_)
305  {
306    if (rld::path::check_file (progname_))
307      progname = rld::path::path_abs (progname_);
308    else
309    {
310      rld::path::paths paths;
311      rld::path::get_system_path (paths);
312      for (rld::path::paths::const_iterator path = paths.begin ();
313           path != paths.end ();
314           ++path)
315      {
316        std::string pp;
317        rld::path::path_join (*path, progname_, pp);
318        if (rld::path::check_file (pp))
319        {
320          progname = rld::path::path_abs (pp);
321          break;
322        }
323      }
324    }
325  }
326
327  const std::string
328  get_progname ()
329  {
330    return progname;
331  }
332
333  const std::string
334  get_program_name ()
335  {
336    return rld::path::basename (progname);
337  }
338
339  const std::string
340  get_program_path ()
341  {
342    return rld::path::dirname (progname);
343  }
344
345  const std::string
346  get_prefix ()
347  {
348    std::string pp = get_program_path ();
349    if (rld::path::basename (pp) == "bin")
350      return rld::path::dirname (pp);
351    return pp;
352  }
353
354  void
355  map (rld::files::cache& cache, rld::symbols::table& symbols)
356  {
357    std::cout << "Archive files    : " << cache.archive_count () << std::endl;
358    std::cout << "Object files     : " << cache.object_count () << std::endl;
359    std::cout << "Exported symbols : " << symbols.size () << std::endl;
360
361    std::cout << "Archives:" << std::endl;
362    cache.output_archive_files (std::cout);
363    std::cout << "Objects:" << std::endl;
364    cache.output_object_files (std::cout);
365
366    std::cout << "Exported symbols:" << std::endl;
367    rld::symbols::output (std::cout, symbols);
368    std::cout << "Unresolved symbols:" << std::endl;
369    cache.output_unresolved_symbols (std::cout);
370  }
371
372  void
373  warn_unused_externals (rld::files::object_list& objects)
374  {
375    bool first = true;
376    for (rld::files::object_list::iterator oli = objects.begin ();
377         oli != objects.end ();
378         ++oli)
379    {
380      rld::files::object&     object = *(*oli);
381      rld::symbols::pointers& externals = object.external_symbols ();
382
383      if (rld::symbols::referenced (externals) != externals.size ())
384      {
385        if (first)
386        {
387          std::cout << "Unreferenced externals in object files:" << std::endl;
388          first = false;
389        }
390
391        std::cout << ' ' << object.name ().basename () << std::endl;
392
393        for (rld::symbols::pointers::iterator sli = externals.begin ();
394             sli != externals.end ();
395             ++sli)
396        {
397          rld::symbols::symbol& sym = *(*sli);
398          if (sym.references () == 0)
399            std::cout << "  " << sym.name () << std::endl;
400        }
401      }
402    }
403  }
404
405}
Note: See TracBrowser for help on using the repository browser.