nis-util
1.0.D108
|
00001 // 00002 // nis-util - NIS Administration Utilities 00003 // Copyright (C) 2012 Peter Miller 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License as published by 00007 // the Free Software Foundation; either version 2 of the License, or (at 00008 // your option) any later version. 00009 // 00010 // This program is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU General Public License along 00016 // with this program. If not, see <http://www.gnu.org/licenses/>. 00017 // 00018 00019 #include <lib/ac/string.h> 00020 #include <list> 00021 00022 #include <lib/path_join.h> 00023 00024 typedef std::list<rcstring> string_list_t; 00025 00026 00027 static void 00028 split(const rcstring &text, string_list_t &parts) 00029 { 00030 if (text.empty()) 00031 { 00032 parts.push_back("."); 00033 return; 00034 } 00035 const char *cp = text.c_str(); 00036 for (;;) 00037 { 00038 const char *slash = strchr(cp, '/'); 00039 if (!slash) 00040 { 00041 parts.push_back(cp); 00042 return; 00043 } 00044 parts.push_back(rcstring(cp, slash - cp)); 00045 cp = slash + 1; 00046 } 00047 } 00048 00049 00050 static rcstring 00051 unsplit(string_list_t &parts) 00052 { 00053 // toss empty parts, except at the start 00054 { 00055 string_list_t fixed; 00056 for 00057 ( 00058 string_list_t::const_iterator it = parts.begin(); 00059 it != parts.end(); 00060 ++it 00061 ) 00062 { 00063 rcstring part = *it; 00064 if (!part.empty() || it == parts.begin()) 00065 fixed.push_back(part); 00066 } 00067 parts = fixed; 00068 } 00069 00070 // toss redundant dots 00071 { 00072 string_list_t fixed; 00073 for 00074 ( 00075 string_list_t::const_iterator it = parts.begin(); 00076 it != parts.end(); 00077 ++it 00078 ) 00079 { 00080 rcstring part = *it; 00081 if (part != ".") 00082 fixed.push_back(part); 00083 } 00084 parts = fixed; 00085 } 00086 00087 if (parts.size() == 1 && parts.front().empty()) 00088 return "/"; 00089 if (parts.empty()) 00090 return "."; 00091 00092 // glue the parts together again 00093 rcstring result; 00094 for 00095 ( 00096 string_list_t::const_iterator it = parts.begin(); 00097 it != parts.end(); 00098 ++it 00099 ) 00100 { 00101 rcstring part = *it; 00102 if (it != parts.begin()) 00103 result += "/"; 00104 result += part; 00105 } 00106 return result; 00107 } 00108 00109 00110 rcstring 00111 path_join(const rcstring &lhs, const rcstring &rhs) 00112 { 00113 string_list_t parts; 00114 split(lhs, parts); 00115 split(rhs, parts); 00116 return unsplit(parts); 00117 } 00118 00119 00120 rcstring 00121 path_join(const rcstring &p1, const rcstring &p2, const rcstring &p3) 00122 { 00123 string_list_t parts; 00124 split(p1, parts); 00125 split(p2, parts); 00126 split(p3, parts); 00127 return unsplit(parts); 00128 } 00129 00130 00131 rcstring 00132 path_join(const rcstring &p1, const rcstring &p2, const rcstring &p3, 00133 const rcstring &p4) 00134 { 00135 string_list_t parts; 00136 split(p1, parts); 00137 split(p2, parts); 00138 split(p3, parts); 00139 split(p4, parts); 00140 return unsplit(parts); 00141 } 00142 00143 00144 // vim: set ts=8 sw=4 et :