source: rtems-tools/rtemstoolkit/rld-path.cpp @ 3618a62

5
Last change on this file since 3618a62 was b249516, checked in by Chris Johns <chrisj@…>, on 03/29/15 at 07:06:00

rtemstoolkit: Add support to return the system path split as paths.

Seacch the path for the program name if not found and set it as
an absolute path. This allow the prefix to be found.

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 * Copyright (c) 2011-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#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <errno.h>
22#include <string.h>
23#include <sys/stat.h>
24#include <unistd.h>
25
26#include <rld.h>
27
28namespace rld
29{
30  namespace path
31  {
32    const std::string
33    basename (const std::string& name)
34    {
35      size_t b = name.find_last_of (RLD_PATH_SEPARATOR);
36      if (b != std::string::npos)
37        return name.substr (b + 1);
38      return name;
39    }
40
41    const std::string
42    dirname (const std::string& name)
43    {
44      size_t b = name.find_last_of (RLD_PATH_SEPARATOR);
45      if (b != std::string::npos)
46        return name.substr (0, b);
47      return name;
48    }
49
50    const std::string
51    extension (const std::string& name)
52    {
53      size_t b = name.find_last_of ('.');
54      if (b != std::string::npos)
55        return name.substr (b);
56      return name;
57    }
58
59    void
60    path_split (const std::string& path, paths& paths)
61    {
62      strings ps;
63      rld::split (ps, path, RLD_PATHSTR_SEPARATOR);
64      if (ps.size ())
65      {
66        for (strings::iterator psi = ps.begin ();
67             psi != ps.end ();
68             ++psi)
69        {
70          if (check_directory (*psi))
71            paths.push_back (*psi);
72        }
73      }
74    }
75
76    void
77    path_join (const std::string& base, const std::string& part, std::string& joined)
78    {
79      if ((base[base.size () - 1] != RLD_PATH_SEPARATOR) &&
80          (part[0] != RLD_PATH_SEPARATOR))
81        joined = base + RLD_PATH_SEPARATOR + part;
82      else if ((base[base.size () - 1] == RLD_PATH_SEPARATOR) &&
83               (part[0] == RLD_PATH_SEPARATOR))
84        joined = base + &part[1];
85      else
86        joined = base + part;
87    }
88
89    void
90    path_join (const std::string& base, const paths& parts, std::string& joined)
91    {
92      joined = base;
93      for (paths::const_iterator pi = parts.begin ();
94           pi != parts.end ();
95           ++pi)
96      {
97        path_join (joined, *pi, joined);
98      }
99    }
100
101    const std::string
102    path_abs (const std::string& path)
103    {
104      std::string apath;
105
106      if (path[0] == RLD_PATH_SEPARATOR)
107      {
108        apath = path;
109      }
110      else
111      {
112        char* buf = 0;
113        try
114        {
115          buf = new char[32 * 1024];
116          if (!::getcwd (buf, 32 * 1024))
117          {
118            delete [] buf;
119            throw rld::error (::strerror (errno), "get current working directory");
120          }
121          path_join (buf, path, apath);
122          delete [] buf;
123        }
124        catch (...)
125        {
126          delete [] buf;
127          throw;
128        }
129      }
130
131      strings ps;
132      strings aps;
133
134      rld::split (ps, apath, RLD_PATH_SEPARATOR);
135
136      for (strings::iterator psi = ps.begin ();
137           psi != ps.end ();
138           ++psi)
139      {
140        const std::string& dir = *psi;
141
142        if (dir.empty () || dir == ".")
143        {
144          /* do nothing */
145        }
146        else if (dir == "..")
147        {
148          aps.pop_back ();
149        }
150        else
151        {
152          aps.push_back (dir);
153        }
154      }
155
156      return RLD_PATH_SEPARATOR + rld::join (aps, RLD_PATH_SEPARATOR_STR);
157    }
158
159    bool
160    check_file (const std::string& path)
161    {
162      struct stat sb;
163      if (::stat (path.c_str (), &sb) == 0)
164        if (S_ISREG (sb.st_mode))
165          return true;
166      return false;
167    }
168
169    bool
170    check_directory (const std::string& path)
171    {
172      struct stat sb;
173      if (::stat (path.c_str (), &sb) == 0)
174        if (S_ISDIR (sb.st_mode))
175          return true;
176      return false;
177    }
178
179    void
180    find_file (std::string& path, const std::string& name, paths& search_paths)
181    {
182      for (paths::iterator pi = search_paths.begin ();
183           pi != search_paths.end ();
184           ++pi)
185      {
186        path_join (*pi, name, path);
187        if (check_file (path))
188          return;
189      }
190      path.clear ();
191    }
192
193    void
194    unlink (const std::string& path, bool not_present_error)
195    {
196      struct stat sb;
197      if (::stat (path.c_str (), &sb) >= 0)
198      {
199        if (!S_ISREG (sb.st_mode))
200            throw rld::error ("Not a regular file", "unlinking: " + path);
201
202        int r;
203#if _WIN32
204        r = ::remove(path.c_str ());
205#else
206        r = ::unlink (path.c_str ());
207#endif
208        if (r < 0)
209          throw rld::error (::strerror (errno), "unlinking: " + path);
210      }
211      else
212      {
213        if (not_present_error)
214          throw rld::error ("Not found", "unlinking: " + path);
215      }
216    }
217
218    void
219    get_system_path (paths& paths)
220    {
221      const char* path = ::getenv ("PATH");
222      strings     ps;
223      rld::split (ps, path, RLD_PATHSTR_SEPARATOR);
224      if (ps.size ())
225      {
226        for (strings::iterator psi = ps.begin ();
227             psi != ps.end ();
228             ++psi)
229        {
230          if (check_directory (*psi))
231            paths.push_back (*psi);
232        }
233      }
234    }
235  }
236}
Note: See TracBrowser for help on using the repository browser.