/Lib/

le,const char *outDir, } error: - QDir::setCurrent(oldDir); + Dir::setCurrent(oldDir); } diff --git a/src/dir.cpp b/src/dir.cpp new file mode 100644 index 0000000..caef5c7 --- /dev/null +++ b/src/dir.cpp @@ -0,0 +1,292 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2021 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#include "filesystem.hpp" +#include "dir.h" + +namespace fs = ghc::filesystem; + +//----------------------------------------------------------------------------------------------- + +struct DirEntry::Private +{ + fs::directory_entry entry; +}; + +DirEntry::DirEntry() : p(std::make_unique()) +{ +} + +DirEntry::~DirEntry() +{ +} + +bool DirEntry::is_directory() const +{ + return p->entry.is_directory(); +} + +bool DirEntry::is_regular_file() const +{ + return p->entry.is_regular_file(); +} + +bool DirEntry::is_symlink() const +{ + return p->entry.is_symlink(); +} + +std::string DirEntry::path() const +{ + return p->entry.path().string(); +} + +//----------------------------------------------------------------------------------------------- + +struct DirIterator::Private +{ + Private() : it() {} + Private(const std::string &path) : it(path) {} + fs::directory_iterator it; + mutable DirEntry current; +}; + +DirIterator::DirIterator() : p(std::make_unique()) +{ +} + +DirIterator::DirIterator(const std::string &path) : p(std::make_unique(path)) +{ +} + +DirIterator::DirIterator(const DirIterator &it) : p(std::make_unique()) +{ + p->it = it.p->it; +} + +DirIterator::~DirIterator() +{ +} + +DirIterator &DirIterator::operator=(const DirIterator &it) +{ + if (&it!=this) + { + p->it = it.p->it; + } + return *this; +} + +DirIterator DirIterator::operator++() +{ + DirIterator result; + result.p->it = ++p->it; + return result; +} + +const DirIterator::value_type &DirIterator::operator*() const +{ + p->current.p->entry = *p->it; + return p->current; +} + +const DirIterator::value_type *DirIterator::operator->() const +{ + p->current.p->entry = *p->it; + return &p->current; +} + +bool operator==(const DirIterator &it1,const DirIterator &it2) +{ + return it1.p->it!=it2.p->it; +} + +bool operator!=(const DirIterator &it1,const DirIterator &it2) +{ + return it1.p->it!=it2.p->it; +} + +DirIterator begin(DirIterator it) noexcept +{ + return it; +} + +DirIterator end(const DirIterator &) noexcept +{ + return DirIterator(); +} + + +//----------------------------------------------------------------------------------------------- + + +struct Dir::Private +{ + fs::path path; +}; + +Dir::Dir() : p(std::make_unique()) +{ + std::error_code ec; + p->path = fs::current_path(ec); +} + +Dir::Dir(const Dir &d) : p(std::make_unique()) +{ + p->path = d.p->path; +} + +Dir &Dir::operator=(const Dir &d) +{ + if (&d!=this) + { + p->path = d.p->path; + } + return *this; +} + +Dir::Dir(const std::string &path) : p(std::make_unique()) +{ + setPath(path); +} + +Dir::~Dir() +{ +} + +void Dir::setPath(const std::string &path) +{ + p->path = path; +} + +std::string Dir::path() const +{ + return p->path.string(); +} + +DirIterator Dir::iterator() const +{ + return DirIterator(p->path.string()); +} + +static void correctPath(std::string &s) +{ + std::replace( s.begin(), s.end(), '\\', '/' ); +} + +bool Dir::exists(const std::string &path,bool acceptsAbsPath) const +{ + std::string result = filePath(path,acceptsAbsPath); + std::error_code ec; + bool exist = fs::exists(fs::path(result),ec); + return !ec && exist; +} + +bool Dir::exists() const +{ + return exists(p->path.string()); +} + +bool Dir::isRelative() const +{ + return isRelativePath(p->path.string()); +} + +bool Dir::isRelativePath(const std::string &path) +{ + return fs::path(path).is_relative(); +} + +std::string Dir::filePath(const std::string &path,bool acceptsAbsPath) const +{ + std::string result; + if (acceptsAbsPath && !isRelativePath(path)) + { + result = path; + } + else + { + result = (p->path / path).string(); + } + correctPath(result); + return result; +} + +bool Dir::mkdir(const std::string &path,bool acceptsAbsPath) const +{ + std::error_code ec; + std::string result = filePath(path,acceptsAbsPath); + if (exists(path,acceptsAbsPath)) + { + return true; + } + else + { + return fs::create_directory(result,ec); + } +} + +bool Dir::rmdir(const std::string &path,bool acceptsAbsPath) const +{ + return remove(path,acceptsAbsPath); +} + +bool Dir::remove(const std::string &path,bool acceptsAbsPath) const +{ + std::error_code ec; + std::string result = filePath(path,acceptsAbsPath); + return fs::remove(result,ec); +} + +bool Dir::rename(const std::string &orgName,const std::string &newName,bool acceptsAbsPath) const +{ + std::error_code ec; + std::string fn1 = filePath(orgName,acceptsAbsPath); + std::string fn2 = filePath(newName,acceptsAbsPath); + fs::rename(fn1,fn2,ec); + return !ec; +} + +std::string Dir::currentDirPath() +{ + std::error_code ec; + std::string result = fs::current_path(ec).string(); + correctPath(result); + return result; +} + +bool Dir::setCurrent(const std::string &path) +{ + std::error_code ec; + fs::current_path(path,ec); + return !ec; +} + +std::string Dir::cleanDirPath(const std::string &path) +{ + std::error_code ec; + std::string result = fs::path(path).lexically_normal().string(); + correctPath(result); + return result; +} + +std::string Dir::absPath() const +{ + std::error_code ec; + std::string result = fs::absolute(p->path,ec).string(); + correctPath(result); + return result; +} + diff --git a/src/dir.h b/src/dir.h new file mode 100644 index 0000000..c02c60d --- /dev/null +++ b/src/dir.h @@ -0,0 +1,103 @@ +/****************************************************************************** + * + * Copyright (C) 1997-2021 by Dimitri van Heesch. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation under the terms of the GNU General Public License is hereby + * granted. No representations are made about the suitability of this software + * for any purpose. It is provided "as is" without express or implied warranty. + * See the GNU General Public License for more details. + * + * Documents produced by Doxygen are derivative works derived from the + * input used in their production; they are not affected by this license. + * + */ + +#ifndef DIR_H +#define DIR_H + +#include +#include + +#include "fileinfo.h" + +class DirEntry +{ + public: + ~DirEntry(); + bool is_directory() const; + bool is_regular_file() const; + bool is_symlink() const; + std::string path() const; + private: + friend class DirIterator; + DirEntry(); + struct Private; + std::unique_ptr p; +}; + +class DirIterator +{ + public: + using value_type = DirEntry; + using difference_type = std::ptrdiff_t; + using pointer = value_type*; + using reference = value_type&; + using iterator_category = std::input_iterator_tag; + DirIterator(const DirIterator &it); + DirIterator &operator=(const DirIterator &it); + DirIterator operator++(); + const value_type &operator*() const; + const value_type *operator->() const; + + friend bool operator==(const DirIterator &it1,const DirIterator &it2); + friend bool operator!=(const DirIterator &it1,const DirIterator &it2); + friend DirIterator begin(DirIterator it) noexcept; + friend DirIterator end(const DirIterator &) noexcept; + ~DirIterator(); + + private: + friend class Dir; + DirIterator(); + DirIterator(const std::string &path); + struct Private; + std::unique_ptr p; +}; + +/** Class representing a directory in the file system */ +class Dir final +{ + public: + Dir(); + Dir(const std::string &path); + Dir(const Dir &d); + Dir &operator=(const Dir &d); + ~Dir(); + void setPath(const std::string &path); + std::string path() const; + + DirIterator iterator() const; + + bool exists() const; + std::string filePath(const std::string &path,bool acceptsAbsPath=true) const; + bool exists(const std::string &path,bool acceptsAbsPath=true) const; + bool mkdir(const std::string &path,bool acceptsAbsPath=true) const; + bool rmdir(const std::string &path,bool acceptsAbsPath=true) const; + bool remove(const std::string &path,bool acceptsAbsPath=true) const; + bool rename(const std::string &orgName,const std::string &newName, + bool acceptsAbsPath=true) const; + std::string absPath() const; + + bool isRelative() const; + + static bool isRelativePath(const std::string &path); + static std::string currentDirPath(); + static bool setCurrent(const std::string &path); + static std::string cleanDirPath(const std::string &path); + + private: + struct Private; + std::unique_ptr p; +}; + +#endif diff --git a/src/dirdef.h b/src/dirdef.h index 0e3db91..5bc49e7 100644 --- a/src/dirdef.h +++ b/src/dirdef.h @@ -24,7 +24,6 @@ #include class FileList; -class QStrList; class FileDef; class OutputList; class UsedDir; diff --git a/src/docbookgen.cpp b/src/docbookgen.cpp index 4319dda..1f10029 100644 --- a/src/docbookgen.cpp +++ b/src/docbookgen.cpp @@ -17,7 +17,6 @@ #include -#include #include #include "docbookgen.h" #include "doxygen.h" @@ -51,6 +50,7 @@ #include "membergroup.h" #include "dirdef.h" #include "section.h" +#include "dir.h" // no debug info #define Docbook_DB(x) do {} while(0) @@ -296,8 +296,8 @@ DB_GEN_C void DocbookGenerator::init() { QCString dir=Config_getString(DOCBOOK_OUTPUT); - QDir d(dir); - if (!d.exists() && !d.mkdir(dir)) + Dir d(dir.str()); + if (!d.exists() && !d.mkdir(dir.str())) { term("Could not create output directory %s\n",dir.data()); } diff --git a/src/dot.cpp b/src/dot.cpp index ddabbc7..cc0f070 100644 --- a/src/dot.cpp +++ b/src/dot.cpp @@ -16,8 +16,6 @@ #include #include -#include - #include "config.h" #include "dot.h" #include "dotrunner.h" @@ -29,6 +27,7 @@ #include "doxygen.h" #include "language.h" #include "index.h" +#include "dir.h" #define MAP_CMD "cmapx" @@ -273,7 +272,7 @@ bool DotManager::run() const void writeDotGraphFromFile(const char *inFile,const char *outDir, const char *outFile,GraphOutputFormat format) { - QDir d(outDir); + Dir d(outDir); if (!d.exists()) { term("Output dir %s does not exist!\n",outDir); @@ -281,8 +280,8 @@ void writeDotGraphFromFile(const char *inFile,const char *outDir, QCString imgExt = getDotImageExtension(); QCString imgName = (QCString)outFile+"."+imgExt; - QCString absImgName = d.absPath().utf8()+"/"+imgName; - QCString absOutFile = d.absPath().utf8()+"/"+outFile; + QCString absImgName = QCString(d.absPath())+"/"+imgName; + QCString absOutFile = QCString(d.absPath())+"/"+outFile; DotRunner dotRun(inFile); if (format==GOF_BITMAP) @@ -326,7 +325,7 @@ void writeDotImageMapFromFile(FTextStream &t, const QCString &context,int graphId) { - QDir d(outDir); + Dir d(outDir.str()); if (!d.exists()) { term("Output dir %s does not exist!\n",outDir.data()); @@ -335,7 +334,7 @@ void writeDotImageMapFromFile(FTextStream &t, QCString mapName = baseName+".map"; QCString imgExt = getDotImageExtension(); QCString imgName = baseName+"."+imgExt; - QCString absOutFile = d.absPath().utf8()+"/"+mapName; + QCString absOutFile = QCString(d.absPath())+"/"+mapName; DotRunner dotRun(inFile.data()); dotRun.addJob(MAP_CMD,absOutFile); @@ -368,5 +367,5 @@ void writeDotImageMapFromFile(FTextStream &t, t << "" << endl; } } - d.remove(absOutFile); + d.remove(absOutFile.str()); } diff --git a/src/dotfilepatcher.cpp b/src/dotfilepatcher.cpp index aafca34..4960cf4 100644 --- a/src/dotfilepatcher.cpp +++ b/src/dotfilepatcher.cpp @@ -18,13 +18,13 @@ #include "qstring.h" #include "config.h" -#include "qdir.h" #include "message.h" #include "ftextstream.h" #include "docparser.h" #include "doxygen.h" #include "util.h" #include "dot.h" +#include "dir.h" static const char svgZoomHeader[] = "\n" @@ -312,25 +312,26 @@ bool DotFilePatcher::run() const //printf("DotFilePatcher::addSVGConversion: file=%s zoomable=%d\n", // m_patchFile.data(),map->zoomable); } - QCString tmpName = m_patchFile+".tmp"; - QCString patchFile = m_patchFile; - if (!QDir::current().rename(patchFile,tmpName)) + std::string tmpName = m_patchFile.str()+".tmp"; + std::string patchFile = m_patchFile.str(); + Dir thisDir; + if (!thisDir.rename(patchFile,tmpName)) { - err("Failed to rename file %s to %s!\n",m_patchFile.data(),tmpName.data()); + err("Failed to rename file %s to %s!\n",m_patchFile.data(),tmpName.c_str()); return FALSE; } - QFile fi(tmpName); - QFile fo(patchFile); + QFile fi(tmpName.c_str()); + QFile fo(patchFile.c_str()); if (!fi.open(IO_ReadOnly)) { - err("problem opening file %s for patching!\n",tmpName.data()); - QDir::current().rename(tmpName,patchFile); + err("problem opening file %s for patching!\n",tmpName.c_str()); + thisDir.rename(tmpName,patchFile); return FALSE; } if (!fo.open(IO_WriteOnly)) { err("problem opening file %s for patching!\n",m_patchFile.data()); - QDir::current().rename(tmpName,patchFile); + thisDir.rename(tmpName,patchFile); return FALSE; } FTextStream t(&fo); @@ -481,11 +482,11 @@ bool DotFilePatcher::run() const fo.close(); // keep original SVG file so we can refer to it, we do need to replace // dummy link by real ones - fi.setName(tmpName); + fi.setName(tmpName.c_str()); fo.setName(orgName); if (!fi.open(IO_ReadOnly)) { - err("problem opening file %s for reading!\n",tmpName.data()); + err("problem opening file %s for reading!\n",tmpName.c_str()); return FALSE; } if (!fo.open(IO_Write