ccuty  1.0
 All Classes Namespaces Files Functions Enumerations Macros Pages
ccpath.hpp
Go to the documentation of this file.
1 //
2 // ccpath: C++ functions for managing Unix pathnames.
3 // (C) Eric Lecolinet 2017 - www.telecom-paristech.fr/~elc
4 //
5 
11 #ifndef __ccuty_path__
12 #define __ccuty_path__
13 
14 #include <string>
15 #include <cstddef>
16 #include <cstdlib>
17 #include <cstdio>
18 
20 namespace ccuty {
21 
24  inline std::string basename(const std::string& path, bool with_extension = true) {
25  if (path.empty()) return ".";
26  if (path.size()==1) return path;
27  if (path[path.size()-1]=='/') return ccuty::basename(path.substr(0, path.size()-1));
28  size_t pos = path.find_last_of('/');
29  if (with_extension) return (pos==std::string::npos) ? path : path.substr(pos+1);
30  else {
31  ssize_t pos2 = path.size()-1, pos_min = (pos==std::string::npos) ? 0 : pos+1;
32  while (pos2 >= pos_min && path[pos2]!='.') --pos2;
33  if (pos2 < pos_min) return (pos==std::string::npos) ? path : path.substr(pos+1);
34  else return (pos==std::string::npos) ? path.substr(0, pos2) : path.substr(pos+1, pos2-pos-1);
35  }
36  }
37 
39  inline std::string dirname(const std::string& path) {
40  if (path.empty()) return ".";
41  if (path.size()==1) return path[0]=='/' ? "/" : ".";
42  if (path[path.size()-1]=='/') return ccuty::dirname(path.substr(0, path.size()-1));
43  size_t pos = path.find_last_of('/');
44  if (pos == std::string::npos) return "."; // no slash
45  return pos== 0 ? "/" : path.substr(0, pos);
46  }
47 
49  inline std::string dirslashed(const std::string& path) {
50  return (!path.empty() && path.back() != '/') ? path+'/' : path;
51  }
52 
55  inline std::string extname(const std::string& path, bool with_dot = true) {
56  ssize_t pos = path.size()-1;
57  while (pos >= 0 && path[pos]!='.' && path[pos]!='/') --pos;
58  if (pos < 0 || path[pos]=='/') return ""; // no extension
59  return with_dot ? path.substr(pos) : path.substr(pos+1);
60  }
61 
63  inline std::string change_extname(const std::string& path, const std::string& ext) {
64  ssize_t pos = path.size()-1;
65  while (pos >= 0 && path[pos]!='.' && path[pos]!='/') --pos;
66  if (pos < 0 || path[pos]=='/') return path + ext; // no extension
67  return path.substr(0, pos) + ext;
68  }
69 
71  inline std::string join_paths(const std::string& left, const std::string& right) {
72  if (left.empty()) return right;
73  else if (right.empty()) return left;
74  else if (right[0] == '/') return left + right;
75  else if (left.back() == '/') return left + right;
76  else return left + '/' + right;
77  }
78 }
79 
80 #endif