source: rtems-tools/rtemstoolkit/rld-path.cpp @ 87e0e76

4.104.115
Last change on this file since 87e0e76 was 87e0e76, checked in by Chris Johns <chrisj@…>, on 09/13/14 at 02:09:16

Refactor code into the RTEMS Toolkit.

  • Property mode set to 100644
File size: 5.1 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, 132 * 1024))
117            throw rld::error (::strerror (errno), "get current working directory");
118          path_join (buf, path, apath);
119        }
120        catch (...)
121        {
122          delete [] buf;
123          throw;
124        }
125      }
126
127      strings ps;
128      strings aps;
129
130      rld::split (ps, apath, RLD_PATH_SEPARATOR);
131
132      for (strings::iterator psi = ps.begin ();
133           psi != ps.end ();
134           ++psi)
135      {
136        const std::string& dir = *psi;
137
138        if (dir.empty () || dir == ".")
139        {
140          /* do nothing */
141        }
142        else if (dir == "..")
143        {
144          aps.pop_back ();
145        }
146        else
147        {
148          aps.push_back (dir);
149        }
150      }
151
152      return RLD_PATH_SEPARATOR + rld::join (aps, RLD_PATH_SEPARATOR_STR);
153    }
154
155    bool
156    check_file (const std::string& path)
157    {
158      struct stat sb;
159      if (::stat (path.c_str (), &sb) == 0)
160        if (S_ISREG (sb.st_mode))
161          return true;
162      return false;
163    }
164
165    bool
166    check_directory (const std::string& path)
167    {
168      struct stat sb;
169      if (::stat (path.c_str (), &sb) == 0)
170        if (S_ISDIR (sb.st_mode))
171          return true;
172      return false;
173    }
174
175    void
176    find_file (std::string& path, const std::string& name, paths& search_paths)
177    {
178      for (paths::iterator pi = search_paths.begin ();
179           pi != search_paths.end ();
180           ++pi)
181      {
182        path_join (*pi, name, path);
183        if (check_file (path))
184          return;
185      }
186      path.clear ();
187    }
188
189    void
190    unlink (const std::string& path, bool not_present_error)
191    {
192      struct stat sb;
193      if (::stat (path.c_str (), &sb) >= 0)
194      {
195        if (!S_ISREG (sb.st_mode))
196            throw rld::error ("Not a regular file", "unlinking: " + path);
197
198        int r;
199#if _WIN32
200        r = ::remove(path.c_str ());
201#else
202        r = ::unlink (path.c_str ());
203#endif
204        if (r < 0)
205          throw rld::error (::strerror (errno), "unlinking: " + path);
206      }
207      else
208      {
209        if (not_present_error)
210          throw rld::error ("Not found", "unlinking: " + path);
211      }
212    }
213  }
214}
Note: See TracBrowser for help on using the repository browser.