]> git.lyx.org Git - lyx.git/blobdiff - src/support/filetools.C
several small patches
[lyx.git] / src / support / filetools.C
index c1052a180a7b40891cb2ecce89d15de0b465475e..f4480d3b6cf884554de56200626227f84a3f7e89 100644 (file)
@@ -32,6 +32,7 @@
 #include "lyx_gui_misc.h"
 #include "FileInfo.h"
 #include "support/path.h"        // I know it's OS/2 specific (SMiyata)
+#include "support/syscall.h"
 #include "gettext.h"
 #include "lyxlib.h"
 
@@ -57,6 +58,7 @@ using std::make_pair;
 using std::pair;
 using std::endl;
 using std::ifstream;
+using std::vector;
 
 #if 0
 using std::getenv;
@@ -77,6 +79,12 @@ bool IsLyXFilename(string const & filename)
 }
 
 
+bool IsSGMLFilename(string const & filename)
+{
+       return contains(filename, ".sgml");
+}
+
+
 // Substitutes spaces with underscores in filename (and path)
 string const MakeLatexName(string const & file)
 {
@@ -112,37 +120,6 @@ string const QuoteName(string const & name)
 }
 
 
-// Returns an unique name to be used as a temporary file. 
-string const TmpFileName(string const & dir, string const & mask)
-{// With all these temporary variables, it should be safe enough :-) (JMarc)
-       string tmpdir;  
-       if (dir.empty())
-               tmpdir = system_tempdir;
-       else
-               tmpdir = dir;
-       string tmpfl(AddName(tmpdir, mask));
-
-       // find a uniq postfix for the filename...
-       // using the pid, and...
-       tmpfl += tostr(getpid());
-       // a short string...
-       string ret;
-       FileInfo fnfo;
-       for (int a = 'a'; a <= 'z'; ++a)
-               for (int b = 'a'; b <= 'z'; ++b)
-                       for (int c = 'a'; c <= 'z'; ++c) {
-                               // if this is not enough I have no idea what
-                               // to do.
-                               ret = tmpfl + char(a) + char(b) + char(c);
-                               // check if the file exist
-                               if (!fnfo.newFile(ret).exist())
-                                       return ret;
-                       }
-       lyxerr << "Not able to find a uniq tmpfile name." << endl;
-       return string();
-}
-
-
 // Is a file readable ?
 bool IsFileReadable (string const & path)
 {
@@ -174,7 +151,7 @@ int IsFileWriteable (string const & path)
 //      -1: error- couldn't find out
 int IsDirWriteable (string const & path)
 {
-        string const tmpfl(TmpFileName(path));
+        string const tmpfl(lyx::tempName(path)); //TmpFileName(path));
 
        if (tmpfl.empty()) {
                WriteFSAlert(_("LyX Internal Error!"), 
@@ -227,6 +204,48 @@ string const FileOpenSearch (string const & path, string const & name,
 }
 
 
+/// Returns a vector of all files in directory dir having extension ext.
+vector<string> const DirList(string const & dir, string const & ext)
+{
+       // This is a non-error checking C/system implementation
+       string extension(ext);
+       if (!extension.empty() && extension[0] != '.')
+               extension.insert(0, ".");
+       vector<string> dirlist;
+       DIR * dirp = ::opendir(dir.c_str());
+       dirent * dire;
+       while ((dire = ::readdir(dirp))) {
+               string const fil = dire->d_name;
+               if (suffixIs(fil, extension)) {
+                       dirlist.push_back(fil);
+               }
+       }
+       ::closedir(dirp);
+       return dirlist;
+       /* I would have prefered to take a vector<string>& as parameter so
+          that we could avoid the copy of the vector when returning.
+          Then we would use:
+          dirlist.swap(argvec);
+          to avoid the copy. (Lgb)
+       */
+       /* A C++ implementaion will look like this:
+          string extension(ext);
+          if (extension[0] != '.') extension.insert(0, ".");
+          vector<string> dirlist;
+          directory_iterator dit("dir");
+          while (dit != directory_iterator()) {
+                  string fil = (*dit).filename;
+                  if (prefixIs(fil, extension)) {
+                          dirlist.push_back(fil);
+                  }
+                  ++dit;
+          }
+          dirlist.swap(argvec);
+          return;
+       */
+}
+
+
 // Returns the real name of file name in directory path, with optional
 // extension ext.  
 string const FileSearch(string const & path, string const & name, 
@@ -417,9 +436,18 @@ int DeleteAllFilesInDir (string const & path)
 static
 string const CreateTmpDir(string const & tempdir, string const & mask)
 {
-       string const tmpfl(TmpFileName(tempdir, mask));
+       lyxerr[Debug::FILES]
+               << "CreateTmpDir: tempdir=`" << tempdir << "'\n"
+               << "CreateTmpDir:    mask=`" << mask << "'" << endl;
        
-       if ((tmpfl.empty()) || lyx::mkdir(tmpfl, 0777)) {
+       string const tmpfl(lyx::tempName(tempdir, mask));
+       // lyx::tempName actually creates a file to make sure that it
+       // stays unique. So we have to delete it before we can create
+       // a dir with the same name. Note also that we are not thread
+       // safe because of the gap between unlink and mkdir. (Lgb)
+       lyx::unlink(tmpfl.c_str());
+       
+       if (tmpfl.empty() || lyx::mkdir(tmpfl, 0777)) {
                WriteFSAlert(_("Error! Couldn't create temporary directory:"),
                             tempdir);
                return string();
@@ -446,7 +474,7 @@ int DestroyTmpDir(string const & tmpdir, bool Allfiles)
 
 string const CreateBufferTmpDir(string const & pathfor)
 {
-       return CreateTmpDir(pathfor, "lyx_bufrtmp");
+       return CreateTmpDir(pathfor, "lyx_tmpbuf");
 }
 
 
@@ -463,7 +491,7 @@ string const CreateLyXTmpDir(string const & deflt)
 #ifdef __EMX__
                         Path p(user_lyxdir);
 #endif
-                       string const t(CreateTmpDir(deflt, "lyx_tmp"));
+                       string const t(CreateTmpDir(deflt, "lyx_tmpdir"));
                         return t;
                } else
                         return deflt;
@@ -471,13 +499,13 @@ string const CreateLyXTmpDir(string const & deflt)
 #ifdef __EMX__
                Path p(user_lyxdir);
 #endif
-               string const t(CreateTmpDir("/tmp", "lyx_tmp"));
+               string const t(CreateTmpDir("/tmp", "lyx_tmpdir"));
                return t;
        }
 }
 
 
-int DestroyLyXTmpDir (string const & tmpdir)
+int DestroyLyXTmpDir(string const & tmpdir)
 {
        return DestroyTmpDir (tmpdir, false); // Why false?
 }
@@ -502,28 +530,6 @@ bool createDirectory(string const & path, int permission)
 }
 
 
-// Returns current working directory
-string const GetCWD ()
-{
-       int n = 256;    // Assume path is less than 256 chars
-       char * err;
-       char * tbuf = new char[n];
-       
-       // Safe. Hopefully all getcwds behave this way!
-       while (((err = lyx::getcwd(tbuf, n)) == 0) && (errno == ERANGE)) {
-               // Buffer too small, double the buffersize and try again
-               delete[] tbuf;
-               n = 2 * n;
-               tbuf = new char[n];
-       }
-
-       string result;
-       if (err) result = tbuf;
-       delete[] tbuf;
-       return result;
-}
-
-
 // Strip filename from path name
 string const OnlyPath(string const & Filename)
 {
@@ -565,7 +571,7 @@ string const MakeAbsPath(string const & RelPath, string const & BasePath)
                delete[] with_drive;
 #endif
        } else
-               TempBase = GetCWD();
+               TempBase = lyx::getcwd(); //GetCWD();
 #ifdef __EMX__
        if (AbsolutePath(TempRel))
                return TempBase.substr(0, 2) + TempRel;
@@ -647,6 +653,21 @@ string const OnlyFilename(string const & fname)
 }
 
 
+// Strips filename from path
+string const BasePath(string const & fname)
+{
+       if (fname.empty())
+               return fname;
+
+       string::size_type j = fname.rfind('/');
+       if (j == string::npos) // no '/' in fname
+               return string();
+
+       // Strip to basename
+       return fname.substr(0,j + 1);
+}
+
+
 // Is a filename/path absolute?
 bool AbsolutePath(string const & path)
 {
@@ -674,7 +695,7 @@ string const ExpandPath(string const & path)
        RTemp = split(RTemp, Temp, '/');
 
        if (Temp == ".") {
-               return GetCWD() + '/' + RTemp;
+               return lyx::getcwd() /*GetCWD()*/ + '/' + RTemp;
        } else if (Temp == "~") {
                return GetEnvPath("HOME") + '/' + RTemp;
        } else if (Temp == "..") {
@@ -746,7 +767,7 @@ string const GetFileContents(string const & fname)
                if (ifs && ofs) {
                        ofs << ifs.rdbuf();
                        ifs.close();
-                       return ofs.str();
+                       return ofs.str().c_str();
                }
        }
        lyxerr << "LyX was not able to read file '" << fname << "'" << endl;
@@ -855,8 +876,8 @@ string const MakeRelPath(string const & abspath0, string const & basepath0)
 // different, then the absolute path will be used as relative path.
 {
        // This is a hack. It should probaly be done in another way. Lgb.
-       string abspath = CleanupPath(abspath0);
-       string basepath = CleanupPath(basepath0);
+       string const abspath = CleanupPath(abspath0);
+       string const basepath = CleanupPath(basepath0);
        if (abspath.empty())
                return "<unknown_path>";
 
@@ -869,8 +890,8 @@ string const MakeRelPath(string const & abspath0, string const & basepath0)
 
        // Go back to last /
        if (i < abslen && i < baselen
-           || (i<abslen && abspath[i] != '/' && i == baselen)
-           || (i<baselen && basepath[i] != '/' && i == abslen))
+           || (i < abslen && abspath[i] != '/' && i == baselen)
+           || (i < baselen && basepath[i] != '/' && i == abslen))
        {
                if (i) --i;     // here was the last match
                while (i && abspath[i] != '/') --i;
@@ -919,12 +940,10 @@ string const AddPath(string const & path, string const & path_2)
                        buf += '/';
        }
 
-       if (!path2.empty()){
-               string::size_type p2start = path2.find_first_not_of('/');
-
-               string::size_type p2end = path2.find_last_not_of('/');
-
-               string tmp = path2.substr(p2start, p2end - p2start + 1);
+       if (!path2.empty()) {
+               string::size_type const p2start = path2.find_first_not_of('/');
+               string::size_type const p2end = path2.find_last_not_of('/');
+               string const tmp = path2.substr(p2start, p2end - p2start + 1);
                buf += tmp + '/';
        }
        return buf;
@@ -1008,10 +1027,10 @@ MakeDisplayPath (string const & path, unsigned int threshold)
                        // Yes, filename in itself is too long.
                        // Pick the start and the end of the filename.
                        relhome = OnlyFilename(path);
-                       string head = relhome.substr(0, threshold/2 - 3);
+                       string const head = relhome.substr(0, threshold/2 - 3);
 
                        l2 = relhome.length();
-                       string tail =
+                       string const tail =
                                relhome.substr(l2 - threshold/2 - 2, l2 - 1);
                        relhome = head + "..." + tail;
                }
@@ -1028,7 +1047,7 @@ bool LyXReadLink(string const & File, string & Link)
                                     LinkBuffer, sizeof(LinkBuffer) - 1);
        if (nRead <= 0)
                return false;
-       LinkBuffer[nRead] = 0;
+       LinkBuffer[nRead] = '\0'; // terminator
        Link = LinkBuffer;
        return true;
 }
@@ -1050,7 +1069,7 @@ cmdret const do_popen(string const & cmd)
                ret += static_cast<char>(c);
                c = fgetc(inf);
        }
-       int pret = pclose(inf);
+       int const pret = pclose(inf);
        return make_pair(pret, ret);
 }
 
@@ -1109,7 +1128,7 @@ void removeAutosaveFile(string const & filename)
        a += '#';
        a += OnlyFilename(filename);
        a += '#';
-       FileInfo fileinfo(a);
+       FileInfo const fileinfo(a);
        if (fileinfo.exist()) {
                if (lyx::unlink(a) != 0) {
                        WriteFSAlert(_("Could not delete auto-save file!"), a);