]> git.lyx.org Git - lyx.git/blobdiff - src/support/filetools.C
in addition to the changes mentioned in ChangeLog, there is the usual batch of whites...
[lyx.git] / src / support / filetools.C
index f54f05d4b16a82174452243d7e8e53561cd4e870..e29bbcdd02eba81e37ace3281cdf6753aa687057 100644 (file)
@@ -17,6 +17,9 @@
 #include <config.h>
 
 #include <cctype>
+#include <utility>
+using std::make_pair;
+using std::pair;
 
 #ifdef __GNUG__
 #pragma implementation "filetools.h"
@@ -74,15 +77,18 @@ string SpaceLess(string const & file)
        
        for (string::size_type i = 0; i < name.length(); ++i) {
                name[i] &= 0x7f; // set 8th bit to 0
-               if (!isalnum(name[i]) && name[i] != '.')
-                       name[i] = '_';
-       }
-       string temp = AddName(path, name);
-       // Replace spaces with underscores, also in directory
-       // No!!! I checked it that it is not necessary.
-       // temp = subst(temp, ' ', '_');
+       };
 
-       return temp;
+       // ok so we scan through the string twice, but who cares.
+       string keep("abcdefghijklmnopqrstuvwxyz"
+               "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+               "@!\"'()*+,-./0123456789:;<=>?[]`|");
+       
+       string::size_type pos = 0;
+       while ((pos = name.find_first_not_of(keep, pos)) != string::npos) {
+               name[pos++] = '_';
+       }
+       return AddName(path, name);
 }
 
 
@@ -102,9 +108,9 @@ string TmpFileName(string const & dir, string const & mask)
        // 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) {
+       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);
@@ -195,7 +201,7 @@ string FileOpenSearch (string const & path, string const & name,
        while (notfound && !path_element.empty()) {
                path_element = CleanupPath(path_element);
                if (!suffixIs(path_element, '/'))
-                       path_element+='/';
+                       path_element+= '/';
                path_element = subst(path_element, "$$LyX", system_lyxdir);
                path_element = subst(path_element, "$$User", user_lyxdir);
                
@@ -252,7 +258,7 @@ string FileSearch(string const & path, string const & name,
 string LibFileSearch(string const & dir, string const & name, 
                      string const & ext)
 {
-        string fullname = FileSearch(AddPath(user_lyxdir,dir), name,
+        string fullname = FileSearch(AddPath(user_lyxdir, dir), name,
                                      ext); 
        if (!fullname.empty())
                return fullname;
@@ -263,7 +269,7 @@ string LibFileSearch(string const & dir, string const & name,
        if (!fullname.empty())
                return fullname;
 
-       return FileSearch(AddPath(system_lyxdir,dir), name, ext);
+       return FileSearch(AddPath(system_lyxdir, dir), name, ext);
 }
 
 
@@ -345,7 +351,7 @@ int DeleteAllFilesInDir (string const & path)
        }
        while ((de = readdir(dir))) {
                string temp = de->d_name;
-               if (temp=="." || temp=="..") 
+               if (temp == "." || temp == "..") 
                        continue;
                string unlinkpath = AddName (path, temp);
 
@@ -494,7 +500,7 @@ string MakeAbsPath(string const & RelPath, string const & BasePath)
        // checks for already absolute path
        if (AbsolutePath(RelPath))
 #ifdef __EMX__
-               if(RelPath[0]!='/' && RelPath[0]!='\\')
+               if(RelPath[0]!= '/' && RelPath[0]!= '\\')
 #endif
                return RelPath;
 
@@ -531,8 +537,8 @@ string MakeAbsPath(string const & RelPath, string const & BasePath)
                // Split by next /
                RTemp = split(RTemp, Temp, '/');
                
-               if (Temp==".") continue;
-               if (Temp=="..") {
+               if (Temp == ".") continue;
+               if (Temp == "..") {
                        // Remove one level of TempBase
                        int i = TempBase.length()-2;
 #ifndef __EMX__
@@ -601,7 +607,7 @@ bool AbsolutePath(string const & path)
 #ifndef __EMX__
        return (!path.empty() && path[0] == '/');
 #else
-       return (!path.empty() && (path[0]=='/' || (isalpha((unsigned char) path[0]) && path.length()>1 && path[1]==':')));
+       return (!path.empty() && (path[0] == '/' || (isalpha(static_cast<unsigned char>(path[0])) && path.length()>1 && path[1] == ':')));
 #endif
 }
 
@@ -610,7 +616,6 @@ bool AbsolutePath(string const & path)
 // Supports ./ and ~/. Later we can add support for ~logname/. (Asger)
 string ExpandPath(string const & path)
 {
-       Assert(!path.empty()); // We don't allow empty path. (Lgb)
        // checks for already absolute path
        string RTemp = ReplaceEnvironmentPath(path);
        if (AbsolutePath(RTemp))
@@ -620,13 +625,13 @@ string ExpandPath(string const & path)
        string copy(RTemp);
 
        // Split by next /
-       RTemp=split(RTemp, Temp, '/');
+       RTemp= split(RTemp, Temp, '/');
 
-       if (Temp==".") {
+       if (Temp == ".") {
                return GetCWD() + '/' + RTemp;
-       } else if (Temp=="~") {
+       } else if (Temp == "~") {
                return GetEnvPath("HOME") + '/' + RTemp;
-       } else if (Temp=="..") {
+       } else if (Temp == "..") {
                return MakeAbsPath(copy);
        } else
                // Don't know how to handle this
@@ -653,14 +658,14 @@ string NormalizePath(string const & path)
                // Split by next /
                RTemp = split(RTemp, Temp, '/');
                
-               if (Temp==".") {
+               if (Temp == ".") {
                        TempBase = "./";
-               } else if (Temp=="..") {
+               } else if (Temp == "..") {
                        // Remove one level of TempBase
                        int i = TempBase.length()-2;
                        while (i>0 && TempBase[i] != '/')
                                --i;
-                       if (i>=0 && TempBase[i] == '/')
+                       if (i>= 0 && TempBase[i] == '/')
                                TempBase.erase(i+1, string::npos);
                        else
                                TempBase = "../";
@@ -694,7 +699,6 @@ string CleanupPath(string const & path)
 
 string ReplaceEnvironmentPath(string const & path)
 {
-       Assert(!path.empty()); // We don't allow empty path. (Lgb)
 // 
 // CompareChar: Environmentvariables starts with this character
 // PathChar:    Next path component start with this character
@@ -703,14 +707,14 @@ string ReplaceEnvironmentPath(string const & path)
 //      Search Environmentvariable
 //      if found: Replace Strings
 //
-       const char CompareChar = '$';
-       const char FirstChar = '{'; 
-       const char EndChar = '}'; 
-       const char UnderscoreChar = '_'; 
+       char const CompareChar = '$';
+       char const FirstChar = '{'; 
+       char const EndChar = '}'; 
+       char const UnderscoreChar = '_'; 
        string EndString; EndString += EndChar;
        string FirstString; FirstString += FirstChar;
        string CompareString; CompareString += CompareChar;
-       const string RegExp("*}*"); // Exist EndChar inside a String?
+       string const RegExp("*}*"); // Exist EndChar inside a String?
 
 // first: Search for a '$' - Sign.
        //string copy(path);
@@ -738,7 +742,7 @@ string ReplaceEnvironmentPath(string const & path)
                        continue;
                }
                // check contents of res1
-               const char * res1_contents = res1.c_str();
+               char const * res1_contents = res1.c_str();
                if (*res1_contents != FirstChar) {
                        // Again No Environmentvariable
                        result1 += CompareString;
@@ -747,11 +751,11 @@ string ReplaceEnvironmentPath(string const & path)
 
                // Check for variable names
                // Situation ${} is detected as "No Environmentvariable"
-               const char * cp1 = res1_contents+1;
-               bool result = isalpha((unsigned char) *cp1) || (*cp1 == UnderscoreChar);
+               char const * cp1 = res1_contents+1;
+               bool result = isalpha(*cp1) || (*cp1 == UnderscoreChar);
                ++cp1;
                while (*cp1 && result) {
-                       result = isalnum((unsigned char) *cp1) || 
+                       result = isalnum(*cp1) || 
                                (*cp1 == UnderscoreChar); 
                        ++cp1;
                }
@@ -801,8 +805,8 @@ string 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;
@@ -882,7 +886,7 @@ string ChangeExtension(string const & oldname, string const & extension,
        string ext;
        // Make sure the extension starts with a dot
        if (!extension.empty() && extension[0] != '.')
-               ext='.' + extension;
+               ext= '.' + extension;
        else
                ext = extension;
        string ret_str;
@@ -952,10 +956,58 @@ bool LyXReadLink(string const & File, string & Link)
        char LinkBuffer[512];
                 // Should be PATH_MAX but that needs autconf support
        int nRead;
-       nRead = readlink(File.c_str(), LinkBuffer,sizeof(LinkBuffer)-1);
+       nRead = readlink(File.c_str(), LinkBuffer, sizeof(LinkBuffer)-1);
        if (nRead <= 0)
                return false;
        LinkBuffer[nRead] = 0;
        Link = LinkBuffer;
        return true;
 }
+
+
+typedef pair<int, string> cmdret;
+static cmdret do_popen(string const & cmd)
+{
+       // One question is if we should use popen or
+       // create our own popen based on fork, exec, pipe
+       // of course the best would be to have a
+       // pstream (process stream), with the
+       // variants ipstream, opstream and
+       FILE * inf = popen(cmd.c_str(), "r");
+       string ret;
+       int c = fgetc(inf);
+       while (c != EOF) {
+               ret += static_cast<char>(c);
+               c = fgetc(inf);
+       }
+       int pret = pclose(inf);
+       return make_pair(pret, ret);
+}
+
+
+string findtexfile(string const & fil, string const & format)
+{
+       /* There is no problem to extend this function too use other
+          methods to look for files. It could be setup to look
+          in environment paths and also if wanted as a last resort
+          to a recursive find. One of the easier extensions would
+          perhaps be to use the LyX file lookup methods. But! I am
+          going to implement this until I see some demand for it.
+          Lgb
+       */
+       
+        // If fil is a file with absolute path we just return it
+        if (AbsolutePath(fil)) return fil;
+       
+        // Check in the current dir.
+        if (FileInfo(OnlyFilename(fil)).exist())
+               return OnlyFilename(fil);
+       
+        // No we try to find it using kpsewhich.
+        string kpsecmd = "kpsewhich --format= " + format + " " + OnlyFilename(fil);
+        cmdret c = do_popen(kpsecmd);
+       
+        lyxerr << "kpse status = " << c.first << "\n"
+               << "kpse result = `" << strip(c.second, '\n') << "'" << endl;
+        return c.first != -1 ? strip(c.second, '\n') : string();
+}