#include "aaspi_path.h" #include "aaspi_file_info.h" #include #ifdef _WIN32 # include #else # include #endif void AASPI_Path::digest_string(const string &pathstr) { abspath=false; string drive=get_drivename(pathstr); plist.clear(); string::const_iterator it=pathstr.begin()+drive.size(); if (it == pathstr.end()) return; if (*it == sep_dir) { abspath=true; ++it; } if (it == pathstr.end()) return; string::const_iterator itb=it; for (; it != pathstr.end(); ++it) { if (*it == sep_dir) { plist.push_back(string(itb,it)); itb=it+1; } } plist.push_back(string(itb,it)); } string AASPI_Path::dirname() const { string res=drive; if (abspath) res += sep_dir; if (plist.empty()) return res; list::const_iterator it=plist.begin(); list::const_iterator lit=plist.end(); if (lit != it) --lit; res += *it; ++it; for (; it != lit; ++it) { res += sep_dir; res += *it; } return res; } string AASPI_Path::filename() const { if (plist.empty()) return string(); return plist.back(); } string AASPI_Path::basename() const { string wrk=filename(); string::iterator it=wrk.end(); if (it == wrk.begin()) return string(); --it; for (; it != wrk.begin(); --it) { if (*it == sep_ext) break; } if (it == wrk.begin()) { if (*it == sep_ext) { ++it; } else { return string(); } } if (*it != sep_ext) return string(); return string(wrk.begin(), it); } string AASPI_Path::extension() const { string wrk=filename(); string::iterator it=wrk.end(); if (it == wrk.begin()) return string(); --it; for (; it != wrk.begin(); --it) { if (*it == sep_ext) break; } if (it == wrk.begin()) { if (*it == sep_ext) { ++it; } else { return string(); } } if (*it != sep_ext) return string(); ++it; return string(it, wrk.end()); } string AASPI_Path::as_string() const { string res=drive; if (abspath) res += sep_dir; if (plist.empty()) return res; list::const_iterator it=plist.begin(); res += *it; ++it; for (; it != plist.end(); ++it) { res += sep_dir; res += *it; } return res; } string AASPI_Path::absolute_path() const { string res=as_string(); if (abspath) return res; if (res.empty()) return current_dir(); return current_dir()+sep_dir+res; } // simplify path removing redundant information string AASPI_Path::normalize_path() const { AASPI_Path tmp; tmp.abspath=abspath; tmp.drive=drive; if (!plist.empty()) { list::const_iterator lit=plist.end(); --lit; list::const_iterator it; for (it=plist.begin(); it != lit; ++it) { if ((*it).empty()) continue; if (*it == "." ) continue; if (*it == ".." ) { if (!tmp.plist.empty()) tmp.plist.pop_back(); continue; } tmp.plist.push_back(*it); } tmp.plist.push_back(*it); } return tmp.as_string(); } AASPI_Path &AASPI_Path::replace_extension(const string &newext) { if (plist.empty()) return *this; string tmp=basename(); if (newext.empty()) { plist.back()=tmp; } else if (newext[0] == sep_ext) { plist.back()=tmp+newext; } else { plist.back()=tmp+sep_ext+newext; } return *this; } AASPI_Path &AASPI_Path::operator+=(const AASPI_Path &path) { list::const_iterator it; for (it=path.plist.begin(); it != path.plist.end(); ++it) { plist.push_back(*it); } return *this; } list AASPI_Path::PathStringToList(const string &pathlist) { list plist; size_t pos=0; size_t len=pathlist.size(); while (pos < len) { size_t fpos=pathlist.find(sep_pathlist,pos); if (fpos == string::npos) { plist.push_back(pathlist.substr(pos,len-pos)); break; } if (fpos-pos > 0) { plist.push_back(pathlist.substr(pos,fpos-pos)); } pos=fpos+1; } return plist; } string AASPI_Path::FindInPath(const string &fname, const list &plist) { string full_path=""; AASPI_Path fn(fname); list::const_iterator it; for (it=plist.begin(); it != plist.end(); ++it) { #ifndef _MSC_VER AASPI_Path pth(*it); pth += fn.filename(); if (AASPI_FileInfo::isAFile(pth.as_string())) { #else string pth=*it; // fix the case that aaspi.bat is located at different hard drive than executable files. if (pth[pth.size()-1] != '\\') pth += '\\'; // check if the last element of pth is a backslash. If not, add a black slash to pth pth += fn.filename(); if (AASPI_FileInfo::isAFile(pth)) { #endif full_path=pth; break; } } return full_path; } string AASPI_Path::FindInPath(const string &fname, const string &pathlist) { list plist=PathStringToList(pathlist); return FindInPath(fname,plist); } #ifdef _WIN32 string AASPI_Path::get_drivename(const string &pathstr) { string str; if ((pathstr.size() >=2) && (pathstr[1] == sep_drive)) { return pathstr.substr(0,2); } return str; } string AASPI_Path::current_dir() const { char buff[1024]; char *ret; string drv=drivename(); if (drivename().empty()) { ret=_getcwd(buff,sizeof(buff)); } else { int drive= int(drv[0])&0x4f - 32; ret=_getdcwd(drive,buff,sizeof(buff)); } if (!ret) return string(); return string(buff); } #else string AASPI_Path::get_drivename(const string &pathstr) { return string(""); } string AASPI_Path::current_dir() const { char buff[1024]; char *ret=getcwd(buff,sizeof(buff)); if (!ret) return string(); return string(buff); } #endif // Test code #if 0 #include int main(int argc, char **argv) { AASPI_Path pth("/usr/local/bin/mystuff.sh"); AASPI_Path pth2("/"); AASPI_Path pth3("this/path/isrel.txt"); pth3.replace_extension(".exe"); AASPI_Path pth4("filenameonly.txt"); AASPI_Path pth5("a/path/noext"); pth5.remove_filename()+="addme.frd"; AASPI_Path pth6("a/./path////noext/..//../../../joe"); cout << pth.absolute_path() << endl; cout << pth.normalize_path() << endl; cout << pth.dirname() << " , " << pth.filename() << " , " << pth.basename() << " , " << pth.extension() << " , " << pth.is_absolute() << endl << endl; cout << pth2.absolute_path() << endl; cout << pth2.normalize_path() << endl; cout << pth2.dirname() << " , " << pth2.filename() << " , " << pth2.basename() << " , " << pth2.extension() << " , " << pth2.is_absolute() << endl << endl; cout << pth3.absolute_path() << endl; cout << pth3.normalize_path() << endl; cout << pth3.dirname() << " , " << pth3.filename() << " , " << pth3.basename() << " , " << pth3.extension() << " , " << pth3.is_absolute() << endl << endl; cout << pth4.absolute_path() << endl; cout << pth4.normalize_path() << endl; cout << pth4.dirname() << " , " << pth4.filename() << " , " << pth4.basename() << " , " << pth4.extension() << " , " << pth4.is_absolute() << endl << endl; cout << pth5.absolute_path() << endl; cout << pth5.normalize_path() << endl; cout << pth5.dirname() << " , " << pth5.filename() << " , " << pth5.basename() << " , " << pth5.extension() << " , " << pth5.is_absolute() << endl << endl; cout << pth6.absolute_path() << endl; cout << pth6.abs_norm_path() << endl; cout << pth6.normalize_path() << endl; cout << pth6.dirname() << " , " << pth6.filename() << " , " << pth6.basename() << " , " << pth6.extension() << " , " << pth6.is_absolute() << endl << endl; string x("Path="); x+=pth6; cout << x << endl; return 0; } #endif