11 #ifndef __ccuty_path__
12 #define __ccuty_path__
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);
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);
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 ".";
45 return pos== 0 ?
"/" : path.substr(0, pos);
50 return (!path.empty() && path.back() !=
'/') ? path+
'/' : path;
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 "";
59 return with_dot ? path.substr(pos) : path.substr(pos+1);
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;
67 return path.substr(0, pos) + ext;
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;