]> git.lyx.org Git - lyx.git/blobdiff - src/support/filetools.cpp
Let paragraph::requestSpellcheck() consider contained insets
[lyx.git] / src / support / filetools.cpp
index 8d48c8e9bd8361aa80be5c55e44415433b32d606..cfb245cd549e301d2de7a3edf6b220a6dad71c97 100644 (file)
 
 #include <config.h>
 
+#include "support/filetools.h"
+
 #include "LyX.h"
 #include "LyXRC.h"
 
-#include "support/filetools.h"
-
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/environment.h"
@@ -42,7 +42,6 @@
 #include <QDir>
 
 #include "support/lassert.h"
-#include "support/regex.h"
 
 #include <fcntl.h>
 #ifdef HAVE_MAGIC_H
 
 #include <utility>
 #include <fstream>
+#include <regex>
 #include <sstream>
 #include <vector>
 
+#include <QCryptographicHash>
+
 #if defined (_WIN32)
 #include <io.h>
 #include <windows.h>
@@ -335,12 +337,16 @@ FileName const fileSearch(string const & path, string const & name,
 //   2) build_lyxdir (if not empty)
 //   3) system_lyxdir
 FileName const libFileSearch(string const & dir, string const & name,
-                          string const & ext, search_mode mode)
+                          string const & ext, search_mode mode,
+                          bool const only_global)
 {
-       FileName fullname = fileSearch(addPath(package().user_support().absFileName(), dir),
-                                    name, ext, mode);
-       if (!fullname.empty())
-               return fullname;
+       FileName fullname;
+       if (!only_global) {
+               fullname = fileSearch(addPath(package().user_support().absFileName(), dir),
+                                            name, ext, mode);
+               if (!fullname.empty())
+                       return fullname;
+       }
 
        if (!package().build_support().empty())
                fullname = fileSearch(addPath(package().build_support().absFileName(), dir),
@@ -442,7 +448,7 @@ string const commandPrep(string const & command_in)
 }
 
 
-FileName const tempFileName(FileName tempdir, string const & mask, bool const dir)
+FileName const tempFileName(FileName const & tempdir, string const & mask, bool const dir)
 {
        return tempFileName(TempFile(tempdir, mask).name(), dir);
 }
@@ -654,6 +660,19 @@ string const addName(string const & path, string const & fname)
 }
 
 
+string const addPathName(std::string const & path, std::string const & fname)
+{
+       string const pathpart = onlyPath(fname);
+       string const namepart = onlyFileName(fname);
+       string newpath = path;
+       if (!pathpart.empty())
+               newpath = addPath(newpath, pathpart);
+       if (!namepart.empty())
+               newpath = addName(newpath, namepart);
+       return newpath;
+}
+
+
 // Strips path from filename
 string const onlyFileName(string const & fname)
 {
@@ -670,8 +689,12 @@ string const onlyFileName(string const & fname)
 
 
 // Search the string for ${VAR} and $VAR and replace VAR using getenv.
+// If VAR does not exist, ${VAR} and $VAR are left as is in the string.
 string const replaceEnvironmentPath(string const & path)
 {
+       if (!contains(path, '$'))
+               return path;
+
        // ${VAR} is defined as
        // $\{[A-Za-z_][A-Za-z_0-9]*\}
        static string const envvar_br = "[$]\\{([A-Za-z_][A-Za-z_0-9]*)\\}";
@@ -689,14 +712,23 @@ string const replaceEnvironmentPath(string const & path)
                string result = path;
                while (1) {
                        smatch what;
+                       bool brackets = true;
                        if (!regex_match(result, what, envvar_br_re)) {
+                               brackets = false;
                                if (!regex_match(result, what, envvar_re))
                                        break;
                        }
                        string env_var = getEnv(what.str(2));
+                       if (env_var.empty()) {
+                               // temporarily use alert/bell (0x07) in place of $
+                               if (brackets)
+                                       env_var = "\a{" + what.str(2) + '}';
+                               else
+                                       env_var = "\a" + what.str(2);
+                       }
                        result = what.str(1) + env_var + what.str(3);
                }
-               return result;
+               return subst(result, '\a', '$');
        } catch (exception const & e) {
                LYXERR0("Something is very wrong: " << e.what());
                return path;
@@ -1093,7 +1125,7 @@ cmd_ret const runCommand(string const & cmd)
 
        // (Claus Hentschel) Check if popen was successful ;-)
        if (!inf) {
-               lyxerr << "RunCommand:: could not start child process" << endl;
+               lyxerr << "RunCommand: could not start child process" << endl;
                return { false, string() };
        }
 
@@ -1125,7 +1157,7 @@ cmd_ret const runCommand(string const & cmd)
 #endif
 
        if (!valid)
-               perror("RunCommand:: could not terminate child process");
+               perror("RunCommand: could not terminate child process");
 
        return { valid, result };
 }
@@ -1134,7 +1166,7 @@ cmd_ret const runCommand(string const & cmd)
 FileName const findtexfile(string const & fil, string const & /*format*/,
                                                   bool const onlykpse)
 {
-       /* There is no problem to extend this function too use other
+       /* There is no problem to extend this function to 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
@@ -1279,5 +1311,40 @@ void fileUnlock(int fd, const char * /* lock_file*/)
 #endif
 }
 
-} //namespace support
+
+std::string toHexHash(const std::string & str)
+{
+       // Use the best available hashing algorithm. Qt 5 proposes SHA-2, but Qt 4 is limited to SHA-1.
+#if QT_VERSION >= 0x050000
+       auto hashAlgo = QCryptographicHash::Sha256;
+#else
+       auto hashAlgo = QCryptographicHash::Sha1;
+#endif
+
+       QByteArray hash = QCryptographicHash::hash(toqstr(str).toLocal8Bit(), hashAlgo);
+       return fromqstr(QString(hash.toHex()));
+}
+
+
+std::string sanitizeFileName(const std::string & str)
+{
+       // The list of characters to keep is probably over-restrictive,
+       // but it is not really a problem.
+       // Apart from non-ASCII characters, at least the following characters
+       // are forbidden: '/', '.', ' ', and ':'.
+       // On windows it is not possible to create files with '<', '>' or '?'
+       // in the name.
+       static std::string const keep = "abcdefghijklmnopqrstuvwxyz"
+                                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                  "+-0123456789;=";
+
+       std::string name = str;
+       string::size_type pos = 0;
+       while ((pos = name.find_first_not_of(keep, pos)) != string::npos)
+               name[pos++] = '_';
+
+       return name;
+}
+
+} // namespace support
 } // namespace lyx