]> git.lyx.org Git - lyx.git/blobdiff - src/support/Package.cpp
Fix bug #4269
[lyx.git] / src / support / Package.cpp
index 2f3bad68f1891966c733ab0718c03cdce59b63b7..8b6fa0b03ae8becd97c3bc5c7b6caaa3245ecca7 100644 (file)
@@ -1,6 +1,6 @@
 // -*- C++ -*-
 /**
- * \file package.C
+ * \file package.cpp
  * This file is part of LyX, the document processor.
  * Licence details can be found in the file COPYING.
  *
 
 #include "support/Package.h"
 
-#include "debug.h"
-#include "gettext.h"
-
+#include "support/debug.h"
 #include "support/environment.h"
+#include "support/ExceptionMessage.h"
 #include "support/filetools.h"
+#include "support/gettext.h"
+#include "support/lassert.h"
 #include "support/lstrings.h"
-#include "support/ExceptionMessage.h"
 #include "support/os.h"
+#include "support/PathChanger.h"
+#include "support/Systemcall.h"
 
 #if defined (USE_WINDOWS_PACKAGING)
 # include "support/os_win32.h"
 #endif
 
-#include <boost/filesystem/operations.hpp>
-#include <boost/tuple/tuple.hpp>
 
+#include <iostream>
 #include <list>
-#include <utility>
 
 #if !defined (USE_WINDOWS_PACKAGING) && \
     !defined (USE_MACOSX_PACKAGING) && \
+    !defined (USE_HAIKU_PACKAGING) && \
     !defined (USE_POSIX_PACKAGING)
-#error USE_FOO_PACKAGING must be defined for FOO = WINDOWS, MACOSX or POSIX.
+#error USE_FOO_PACKAGING must be defined for FOO = WINDOWS, MACOSX, HAIKU or POSIX.
 #endif
 
 #if defined (USE_MACOSX_PACKAGING)
-# include <CoreServices/CoreServices.h> // FSFindFolder, FSRefMakePath
+# include "support/qstring_helpers.h"
+# include <QDir>
+# include <QDesktopServices>
 #endif
 
-using std::string;
-
-namespace fs = boost::filesystem;
+using namespace std;
 
 namespace lyx {
 namespace support {
@@ -54,32 +55,23 @@ namespace {
 Package package_;
 bool initialised_ = false;
 
-} // namespace anon
+} // namespace
 
 
 void init_package(string const & command_line_arg0,
                  string const & command_line_system_support_dir,
-                 string const & command_line_user_support_dir,
-                 exe_build_dir_to_top_build_dir top_build_dir_location)
+                 string const & command_line_user_support_dir)
 {
-       // Can do so only once.
-       if (initialised_)
-               return;
-
        package_ = Package(command_line_arg0,
                           command_line_system_support_dir,
-                          command_line_user_support_dir,
-                          top_build_dir_location);
+                          command_line_user_support_dir);
        initialised_ = true;
 }
 
 
 Package const & package()
 {
-       // Commented out because package().locale_dir() can be called
-       // from the message translation code in Messages.cpp before
-       // init_package() is called. Lars is on the case...
-       // BOOST_ASSERT(initialised_);
+       LAPPERR(initialised_);
        return package_;
 }
 
@@ -88,85 +80,144 @@ namespace {
 
 FileName const abs_path_from_binary_name(string const & exe);
 
-std::pair<FileName, FileName> const
-get_build_dirs(FileName const & abs_binary,
-              exe_build_dir_to_top_build_dir top_build_dir_location);
 
-FileName const get_document_dir(FileName const & home_dir);
+bool inBuildDir(FileName const & abs_binary, FileName &, FileName &);
 
-FileName const get_home_dir();
+FileName findLyxBinary(FileName const & abs_binary);
+
+FileName const get_document_dir(FileName const & home_dir);
 
 FileName const get_locale_dir(FileName const & system_support_dir);
 
 FileName const get_system_support_dir(FileName const & abs_binary,
                                    string const & command_line_system_support_dir);
 
-FileName const get_temp_dir();
-
 FileName const get_default_user_support_dir(FileName const & home_dir);
 
-std::pair<FileName, bool> const
-get_user_support_dir(FileName const & default_user_support_dir,
-                    string const & command_line_user_support_dir);
-
+bool userSupportDir(FileName const & default_user_support_dir,
+                    string const & command_line_user_support_dir, FileName & result);
 
 string const & with_version_suffix();
 
-} // namespace anon
+string const fix_dir_name(string const & name);
+
+} // namespace
 
 
 Package::Package(string const & command_line_arg0,
                 string const & command_line_system_support_dir,
-                string const & command_line_user_support_dir,
-                exe_build_dir_to_top_build_dir top_build_dir_location)
+                string const & command_line_user_support_dir)
        : explicit_user_support_dir_(false)
 {
-       home_dir_ = get_home_dir();
-       system_temp_dir_ = get_temp_dir();
+       // Specification of temp_dir_ may be reset by LyXRC,
+       // but the default is fixed for a given OS.
+       system_temp_dir_ = FileName::tempPath();
        temp_dir_ = system_temp_dir_;
-       document_dir_ = get_document_dir(home_dir_);
+       document_dir_ = get_document_dir(get_home_dir());
 
        FileName const abs_binary = abs_path_from_binary_name(command_line_arg0);
-       string const bdir = onlyPath(abs_binary.absFilename());
-       // We may be using libtools
-       if (suffixIs(bdir, ".libs/"))
-               binary_dir_ = FileName(addPath(bdir, "../"));
-       else
-               binary_dir_ = FileName(bdir);
+       binary_dir_ = FileName(onlyPath(abs_binary.absFileName()));
+
+       // the LyX package directory
+       lyx_dir_ = FileName(addPath(binary_dir_.absFileName(), "../"));
+       lyx_dir_ = FileName(lyx_dir_.realPath());
 
        // Is LyX being run in-place from the build tree?
-       boost::tie(build_support_dir_, system_support_dir_) =
-               get_build_dirs(abs_binary, top_build_dir_location);
+       in_build_dir_ = inBuildDir(abs_binary, build_support_dir_, system_support_dir_);
 
-       if (build_support_dir_.empty())
+       if (!in_build_dir_) {
                system_support_dir_ =
                        get_system_support_dir(abs_binary,
                                               command_line_system_support_dir);
+       }
+
+       // Find the LyX executable
+       lyx_binary_ = findLyxBinary(abs_binary);
 
        locale_dir_ = get_locale_dir(system_support_dir_);
 
        FileName const default_user_support_dir =
-               get_default_user_support_dir(home_dir_);
-       boost::tie(user_support_dir_, explicit_user_support_dir_) =
-               get_user_support_dir(default_user_support_dir,
-                                    command_line_user_support_dir);
+               get_default_user_support_dir(get_home_dir());
+
+       explicit_user_support_dir_ = userSupportDir(default_user_support_dir,
+                                    command_line_user_support_dir, user_support_dir_);
+
+
+       LYXERR(Debug::INIT, "<package>\n"
+               << "\tbinary_dir " << binary_dir().absFileName() << '\n'
+               << "\tsystem_support " << system_support().absFileName() << '\n'
+               << "\tbuild_support " << build_support().absFileName() << '\n'
+               << "\tuser_support " << user_support().absFileName() << '\n'
+               << "\tlocale_dir " << locale_dir().absFileName() << '\n'
+               << "\tdocument_dir " << document_dir().absFileName() << '\n'
+               << "\ttemp_dir " << temp_dir().absFileName() << '\n'
+               << "\thome_dir " << get_home_dir().absFileName() << '\n'
+               << "</package>\n");
+}
+
 
-       FileName const configure_script(addName(system_support().absFilename(), "configure.py"));
-       configure_command_ = os::python() + ' ' +
+int Package::reconfigureUserLyXDir(string const & option) const
+{
+       if (configure_command_.empty()) {
+               FileName const configure_script(addName(system_support().absFileName(), "configure.py"));
+               configure_command_ = os::python() + ' ' +
                        quoteName(configure_script.toFilesystemEncoding()) +
-                       with_version_suffix();
+                       with_version_suffix() + " --binary-dir=" +
+                       quoteName(FileName(binary_dir().absFileName()).toFilesystemEncoding());
+       }
+
+       lyxerr << to_utf8(_("LyX: reconfiguring user directory")) << endl;
+       PathChanger p(user_support());
+       Systemcall one;
+       int const ret = one.startscript(Systemcall::Wait, configure_command_ + option);
+       lyxerr << "LyX: " << to_utf8(_("Done!")) << endl;
+       return ret;
+}
 
-       lyxerr[Debug::INIT]
-               << "<package>\n"
-               << "\tbinary_dir " << binary_dir().absFilename() << '\n'
-               << "\tsystem_support " << system_support().absFilename() << '\n'
-               << "\tbuild_support " << build_support().absFilename() << '\n'
-               << "\tuser_support " << user_support().absFilename() << '\n'
-               << "\tlocale_dir " << locale_dir().absFilename() << '\n'
-               << "\tdocument_dir " << document_dir().absFilename() << '\n'
-               << "\ttemp_dir " << temp_dir().absFilename() << '\n'
-               << "\thome_dir " << home_dir().absFilename() << '\n'
-               << "</package>\n" << std::endl;
+
+string Package::getConfigureLockName() const
+{
+       return addName(user_support().absFileName(), ".lyx_configure_lock");
+}
+
+
+void Package::set_temp_dir(FileName const & temp_dir) const
+{
+       if (temp_dir.empty())
+               temp_dir_ = system_temp_dir_;
+       else
+               temp_dir_ = temp_dir;
+}
+
+
+FileName Package::messages_file(string const & c) const
+{
+       if (in_build_dir_) {
+               FileName res = FileName(lyx_dir().absFileName() + "/po/" + c + ".gmo");
+               if (!res.isReadableFile())
+                       res = FileName(lyx_dir().absFileName() + "../po/" + c + ".gmo");
+               if (!res.isReadableFile())
+                       res = FileName(top_srcdir().absFileName() + "/po/" + c + ".gmo");
+               return res;
+       } else
+               return FileName(locale_dir_.absFileName() + "/" + c
+                       + "/LC_MESSAGES/" PACKAGE ".mo");
+}
+
+
+// The specification of home_dir_ is fixed for a given OS.
+// A typical example on Windows: "C:/Documents and Settings/USERNAME"
+// and on a Posix-like machine: "/home/USERNAME".
+FileName const & Package::get_home_dir()
+{
+#if defined (USE_WINDOWS_PACKAGING)
+       static FileName const home_dir(getEnv("USERPROFILE"));
+#elif defined (USE_MACOSX_PACKAGING)
+       static FileName const home_dir(fromqstr(QDir::homePath()));
+#else // Posix-like.
+       static FileName const home_dir(getEnv("HOME"));
+#endif
+       return home_dir;
 }
 
 
@@ -198,7 +249,7 @@ string const & with_version_suffix()
        return program_suffix.empty() ? program_suffix : with_version_suffix;
 }
 
-} // namespace anon
+} // namespace
 
 
 FileName const & Package::top_srcdir()
@@ -241,26 +292,28 @@ string const fix_dir_name(string const & name)
 }
 
 
-FileName const
-get_build_support_dir(string const & binary_dir,
-                     exe_build_dir_to_top_build_dir top_build_dir_location)
-{
-       string indirection;
-       switch (top_build_dir_location) {
-       case top_build_dir_is_one_level_up:
-               indirection = "../lib";
-               break;
-       case top_build_dir_is_two_levels_up:
-               indirection = "../../lib";
-               break;
-       }
-       return FileName(normalizePath(addPath(binary_dir, indirection)));
-}
 
+bool isBuildDir(FileName const & abs_binary, string const & dir_location,
+       FileName & build_support_dir)
+{
+    string search_dir = onlyPath(abs_binary.absFileName()) + dir_location;
+
+    // Makefile by automake
+    build_support_dir = FileName(addPath(search_dir, "lib"));
+    if (!fileSearch(build_support_dir.absFileName(), "Makefile").empty()) {
+        return true;
+    }
+    //  cmake file, no Makefile in lib
+    FileName build_src_dir = FileName(addPath(search_dir, "src"));
+    if (!fileSearch(build_src_dir.absFileName(), "cmake_install.cmake").empty()) {
+        return true;
+    }
+
+    return false;
+}
 
-std::pair<FileName, FileName> const
-get_build_dirs(FileName const & abs_binary,
-              exe_build_dir_to_top_build_dir top_build_dir_location)
+bool inBuildDir(FileName const & abs_binary,
+       FileName & build_support_dir, FileName & system_support_dir)
 {
        string const check_text = "Checking whether LyX is run in place...";
 
@@ -272,30 +325,25 @@ get_build_dirs(FileName const & abs_binary,
 
        // Note that the name of the lyx binary may be a symbolic link.
        // If that is the case, then we follow the links too.
-       FileName binary = abs_binary;
+    FileName binary = abs_binary;
        while (true) {
                // Try and find "lyxrc.defaults".
-               string binary_dir = onlyPath(binary.absFilename());
-               // We may be using libtools with static linking.
-               if (suffixIs(binary_dir, ".libs/"))
-                       binary_dir = addPath(binary_dir, "../");
-               FileName const build_support_dir =
-                       get_build_support_dir(binary_dir, top_build_dir_location);
-               if (!fileSearch(build_support_dir.absFilename(), "Makefile").empty()) {
+               if( isBuildDir(binary, "../", build_support_dir) ||
+            isBuildDir(binary, "../../", build_support_dir))
+        {
                        // Try and find "chkconfig.ltx".
-                       string const system_support_dir =
-                               addPath(Package::top_srcdir().absFilename(), "lib");
+                       system_support_dir =
+                               FileName(addPath(Package::top_srcdir().absFileName(), "lib"));
 
-                       if (!fileSearch(system_support_dir, "chkconfig.ltx").empty()) {
-                               lyxerr[Debug::INIT] << check_text << " yes"
-                                                   << std::endl;
-                               return std::make_pair(build_support_dir, system_support_dir);
+                       if (!fileSearch(system_support_dir.absFileName(), "chkconfig.ltx").empty()) {
+                               LYXERR(Debug::INIT, check_text << " yes");
+                               return true;
                        }
                }
 
                // Check whether binary is a symbolic link.
                // If so, resolve it and repeat the exercise.
-               if (!fs::symbolic_link_exists(binary.toFilesystemEncoding()))
+               if (!binary.isSymLink())
                        break;
 
                FileName link;
@@ -307,8 +355,62 @@ get_build_dirs(FileName const & abs_binary,
                }
        }
 
-       lyxerr[Debug::INIT] << check_text << " no" << std::endl;
-       return std::make_pair(FileName(), FileName());
+       LYXERR(Debug::INIT, check_text << " no");
+       system_support_dir = FileName();
+       build_support_dir = FileName();
+
+    return false;
+}
+
+
+bool doesFileExist(FileName & result, string const & search_dir, string const & name)
+{
+    result = fileSearch(search_dir, name);
+    if (!result.empty()) {
+        return true;
+    }
+    return false;
+}
+
+
+bool lyxBinaryPath(FileName & lyx_binary, string const & search_dir, string const & ext)
+{
+    lyx_binary = FileName();
+    if(false) {
+    } else if (doesFileExist(lyx_binary, search_dir, "lyx" + ext)) {
+    } else if (doesFileExist(lyx_binary, search_dir, "LyX" + ext)) {
+    } else if (doesFileExist(lyx_binary, search_dir, "lyx" + string(PROGRAM_SUFFIX) + ext)) {
+    } else if (doesFileExist(lyx_binary, search_dir, "LyX" + string(PROGRAM_SUFFIX) + ext)){
+    }
+    return !lyx_binary.empty() ? true : false;
+}
+
+
+FileName findLyxBinary(FileName const & abs_binary)
+{
+    string ext;
+    string checkname = abs_binary.toFilesystemEncoding();
+    int check_len = checkname.length();
+    int prgsuffixlen = string(PROGRAM_SUFFIX).length();
+    if ((prgsuffixlen > 0) && (check_len > prgsuffixlen) &&
+       (checkname.substr(check_len-prgsuffixlen) == string(PROGRAM_SUFFIX))) {
+       ext = "";
+    }
+    else if (!abs_binary.extension().empty()) {
+        ext = "." + abs_binary.extension();
+    }
+
+    string binary_dir = onlyPath(abs_binary.absFileName());
+
+    FileName lyx_binary;
+    if (lyxBinaryPath(lyx_binary, binary_dir, ext))
+        return lyx_binary;
+
+    string search_dir = onlyPath(FileName(addPath(binary_dir, "/../")).absFileName());
+    if (lyxBinaryPath(lyx_binary, search_dir, ext))
+        return lyx_binary;
+
+    return FileName();
 }
 
 
@@ -320,26 +422,18 @@ FileName const get_document_dir(FileName const & home_dir)
        (void)home_dir; // Silence warning about unused variable.
        os::GetFolderPath win32_folder_path;
        return FileName(win32_folder_path(os::GetFolderPath::PERSONAL));
+#elif defined (USE_MACOSX_PACKAGING) && (QT_VERSION >= 0x050000)
+       (void)home_dir; // Silence warning about unused variable.
+       return FileName(fromqstr(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)));
+#elif defined (USE_MACOSX_PACKAGING)
+       (void)home_dir; // Silence warning about unused variable.
+       return FileName(fromqstr(QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation)));
 #else // Posix-like.
        return home_dir;
 #endif
 }
 
 
-// The specification of home_dir_ is fixed for a given OS.
-// A typical example on Windows: "C:/Documents and Settings/USERNAME"
-// and on a Posix-like machine: "/home/USERNAME".
-FileName const get_home_dir()
-{
-#if defined (USE_WINDOWS_PACKAGING)
-       string const home_dir = getEnv("USERPROFILE");
-#else // Posix-like.
-       string const home_dir = getEnv("HOME");
-#endif
-
-       return FileName(fix_dir_name(home_dir));
-}
-
 
 // Several sources are probed to ascertain the locale directory.
 // The only requirement is that the result is indeed a directory.
@@ -353,44 +447,29 @@ FileName const get_locale_dir(FileName const & system_support_dir)
        // 2. Search for system_support_dir / <relative locale dir>
        // The <relative locale dir> is OS-dependent. (On Unix, it will
        // be "../locale/".)
-       FileName path(normalizePath(addPath(system_support_dir.absFilename(),
-                                           relative_locale_dir())));
+       FileName path(addPath(system_support_dir.absFileName(),
+               relative_locale_dir()));
 
-       if (path.exists() && fs::is_directory(path.toFilesystemEncoding()))
+       if (path.exists() && path.isDirectory())
                return path;
 
        // 3. Fall back to the hard-coded LOCALEDIR.
        path = hardcoded_localedir();
-       if (path.exists() && fs::is_directory(path.toFilesystemEncoding()))
+       if (path.exists() && path.isDirectory())
                return path;
 
        return FileName();
 }
 
 
-// Specification of temp_dir_ may be reset by LyXRC,
-// but the default is fixed for a given OS.
-FileName const get_temp_dir()
-{
-#if defined (USE_WINDOWS_PACKAGING)
-       // Typical example: C:/TEMP/.
-       char path[MAX_PATH];
-       GetTempPath(MAX_PATH, path);
-       return FileName(os::internal_path(to_utf8(from_local8bit(path))));
-#else // Posix-like.
-       return FileName("/tmp");
-#endif
-}
-
-
 // Extracts the absolute path from the foo of "-sysdir foo" or "-userdir foo"
 FileName const abs_path_from_command_line(string const & command_line)
 {
        if (command_line.empty())
                return FileName();
 
-       string const path = fix_dir_name(command_line);
-       return os::is_absolute_path(path) ? FileName(path) : makeAbsPath(path);
+       string const str_path = fix_dir_name(command_line);
+       return makeAbsPath(str_path);
 }
 
 
@@ -407,7 +486,7 @@ FileName const get_binary_path(string const & exe)
 #else
        string const exe_path = os::internal_path(exe);
 #endif
-       if (os::is_absolute_path(exe_path))
+       if (FileName::isAbsolute(exe_path))
                return FileName(exe_path);
 
        // Two possibilities present themselves.
@@ -418,16 +497,16 @@ FileName const get_binary_path(string const & exe)
 
        // 2. exe must be the name of the binary only and it
        // can be found on the PATH.
-       string const exe_name = onlyFilename(exe_path);
+       string const exe_name = onlyFileName(exe_path);
        if (exe_name != exe_path)
                return FileName();
 
-       std::vector<string> const path = getEnvPath("PATH");
-       std::vector<string>::const_iterator it = path.begin();
-       std::vector<string>::const_iterator const end = path.end();
+       vector<string> const path = getEnvPath("PATH");
+       vector<string>::const_iterator it = path.begin();
+       vector<string>::const_iterator const end = path.end();
        for (; it != end; ++it) {
                // This will do nothing if *it is already absolute.
-               string const exe_dir = makeAbsPath(*it).absFilename();
+               string const exe_dir = makeAbsPath(*it).absFileName();
 
                FileName const exe_path(addName(exe_dir, exe_name));
                if (exe_path.exists())
@@ -465,21 +544,21 @@ get_system_support_dir(FileName const & abs_binary,
 
        // searched_dirs is used for diagnostic purposes only in the case
        // that "chkconfig.ltx" is not found.
-       std::list<FileName> searched_dirs;
+       list<FileName> searched_dirs;
 
        // 1. Use the -sysdir command line parameter.
        FileName path = abs_path_from_command_line(command_line_system_support_dir);
        if (!path.empty()) {
                searched_dirs.push_back(path);
-               if (check_command_line_dir(path.absFilename(), chkconfig_ltx, "-sysdir"))
+               if (check_command_line_dir(path.absFileName(), chkconfig_ltx, "-sysdir"))
                        return path;
        }
 
-       // 2. Use the "LYX_DIR_15x" environment variable.
-       path = extract_env_var_dir("LYX_DIR_15x");
+       // 2. Use the "LYX_DIR_${major}${minor}x" environment variable.
+       path = extract_env_var_dir(LYX_DIR_VER);
        if (!path.empty()) {
                searched_dirs.push_back(path);
-               if (check_env_var_dir(path, chkconfig_ltx, "LYX_DIR_15x"))
+               if (check_env_var_dir(path, chkconfig_ltx, LYX_DIR_VER))
                        return path;
        }
 
@@ -495,20 +574,19 @@ get_system_support_dir(FileName const & abs_binary,
        FileName binary = abs_binary;
        while (true) {
                // Try and find "chkconfig.ltx".
-               string const binary_dir = onlyPath(binary.absFilename());
+               string const binary_dir = onlyPath(binary.absFileName());
 
-               FileName const lyxdir(
-                       normalizePath(addPath(binary_dir, relative_lyxdir)));
+               FileName const lyxdir(addPath(binary_dir, relative_lyxdir));
                searched_dirs.push_back(lyxdir);
 
-               if (!fileSearch(lyxdir.absFilename(), chkconfig_ltx).empty()) {
+               if (!fileSearch(lyxdir.absFileName(), chkconfig_ltx).empty()) {
                        // Success! "chkconfig.ltx" has been found.
                        return lyxdir;
                }
 
                // Check whether binary is a symbolic link.
                // If so, resolve it and repeat the exercise.
-               if (!fs::symbolic_link_exists(binary.toFilesystemEncoding()))
+               if (!binary.isSymLink())
                        break;
 
                FileName link;
@@ -521,12 +599,12 @@ get_system_support_dir(FileName const & abs_binary,
        }
 
        // 4. Repeat the exercise on the directory itself.
-       FileName binary_dir(onlyPath(abs_binary.absFilename()));
+       FileName binary_dir(onlyPath(abs_binary.absFileName()));
        while (true) {
                // This time test whether the directory is a symbolic link
                // *before* looking for "chkconfig.ltx".
                // (We've looked relative to the original already.)
-               if (!fs::symbolic_link_exists(binary.toFilesystemEncoding()))
+               if (!binary.isSymLink())
                        break;
 
                FileName link;
@@ -538,11 +616,11 @@ get_system_support_dir(FileName const & abs_binary,
                }
 
                // Try and find "chkconfig.ltx".
-               FileName const lyxdir(
-                       normalizePath(addPath(binary_dir.absFilename(), relative_lyxdir)));
+               FileName const lyxdir(addPath(binary_dir.absFileName(),
+                       relative_lyxdir));
                searched_dirs.push_back(lyxdir);
 
-               if (!fileSearch(lyxdir.absFilename(), chkconfig_ltx).empty()) {
+               if (!fileSearch(lyxdir.absFileName(), chkconfig_ltx).empty()) {
                        // Success! "chkconfig.ltx" has been found.
                        return lyxdir;
                }
@@ -550,60 +628,53 @@ get_system_support_dir(FileName const & abs_binary,
 
        // 5. In desparation, try the hard-coded system support dir.
        path = hardcoded_system_support_dir();
-       if (!fileSearch(path.absFilename(), chkconfig_ltx).empty())
+       if (!fileSearch(path.absFileName(), chkconfig_ltx).empty())
                return path;
 
        // Everything has failed :-(
        // So inform the user and exit.
        string searched_dirs_str;
-       typedef std::list<FileName>::const_iterator iterator;
+       typedef list<FileName>::const_iterator iterator;
        iterator const begin = searched_dirs.begin();
        iterator const end = searched_dirs.end();
        for (iterator it = begin; it != end; ++it) {
                if (it != begin)
                        searched_dirs_str += "\n\t";
-               searched_dirs_str += it->absFilename();
+               searched_dirs_str += it->absFileName();
        }
 
        // FIXME UNICODE
        throw ExceptionMessage(ErrorException, _("No system directory"),
                bformat(_("Unable to determine the system directory "
-                                        "having searched\n"
-                                        "\t%1$s\n"
-                                        "Use the '-sysdir' command line parameter or "
-                                        "set the environment variable LYX_DIR_15x to "
-                                        "the LyX system directory containing the file "
-                                        "`chkconfig.ltx'."),
-                         from_utf8(searched_dirs_str)));
-
-       // Keep the compiler happy.
-       return FileName();
+                               "having searched\n"
+                               "\t%1$s\n"
+                               "Use the '-sysdir' command line parameter or "
+                               "set the environment variable\n%2$s "
+                               "to the LyX system directory containing the "
+                               "file `chkconfig.ltx'."),
+                         from_utf8(searched_dirs_str), from_ascii(LYX_DIR_VER)));
 }
 
 
 // Returns the absolute path to the user lyxdir, together with a flag
 // indicating whether this directory was specified explicitly (as -userdir
 // or through an environment variable) or whether it was deduced.
-std::pair<FileName, bool> const
-get_user_support_dir(FileName const & default_user_support_dir,
-                    string const & command_line_user_support_dir)
+bool userSupportDir(FileName const & default_user_support_dir,
+       string const & command_line_user_support_dir, FileName & result)
 {
-       bool explicit_userdir = true;
-
        // 1. Use the -userdir command line parameter.
-       FileName path =
-               abs_path_from_command_line(command_line_user_support_dir);
-       if (!path.empty())
-               return std::make_pair(path, explicit_userdir);
+       result = abs_path_from_command_line(command_line_user_support_dir);
+       if (!result.empty())
+               return true;
 
-       // 2. Use the LYX_USERDIR_15x environment variable.
-       path = extract_env_var_dir("LYX_USERDIR_15x");
-       if (!path.empty())
-               return std::make_pair(path, explicit_userdir);
+       // 2. Use the LYX_USERDIR_${major}${minor}x environment variable.
+       result = extract_env_var_dir(LYX_USERDIR_VER);
+       if (!result.empty())
+               return true;
 
        // 3. Use the OS-dependent default_user_support_dir
-       explicit_userdir = false;
-       return std::make_pair(default_user_support_dir, explicit_userdir);
+       result = default_user_support_dir;
+       return false;
 }
 
 
@@ -617,34 +688,25 @@ FileName const get_default_user_support_dir(FileName const & home_dir)
        os::GetFolderPath win32_folder_path;
        return FileName(addPath(win32_folder_path(os::GetFolderPath::APPDATA), PACKAGE));
 
-#elif defined (USE_MACOSX_PACKAGING)
+#elif defined (USE_MACOSX_PACKAGING) && (QT_VERSION >= 0x050000)
        (void)home_dir; // Silence warning about unused variable.
+       return FileName(addPath(fromqstr(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)), PACKAGE));
 
-       FSRef fsref;
-       OSErr const error_code =
-               FSFindFolder(kUserDomain, kApplicationSupportFolderType,
-                            kDontCreateFolder, &fsref);
-       if (error_code != 0)
-               return FileName();
-
-       // FSRefMakePath returns the result in utf8
-       char store[PATH_MAX + 1];
-       OSStatus const status_code =
-               FSRefMakePath(&fsref,
-                             reinterpret_cast<UInt8*>(store), PATH_MAX);
-       if (status_code != 0)
-               return FileName();
+#elif defined (USE_MACOSX_PACKAGING)
+       (void)home_dir; // Silence warning about unused variable.
+       return FileName(addPath(fromqstr(QDesktopServices::storageLocation(QDesktopServices::DataLocation)), PACKAGE));
 
-       return FileName(addPath(reinterpret_cast<char const *>(store), PACKAGE));
+#elif defined (USE_HAIKU_PACKAGING)
+       return FileName(addPath(home_dir.absFileName(), string("/config/settings/") + PACKAGE));
 
 #else // USE_POSIX_PACKAGING
-       return FileName(addPath(home_dir.absFilename(), string(".") + PACKAGE));
+       return FileName(addPath(home_dir.absFileName(), string(".") + PACKAGE));
 #endif
 }
 
 
 // Check that directory @c dir contains @c file.
-// Else emit a warning about an invalid @c command_line_switch.
+// Else emit an error message about an invalid @c command_line_switch.
 bool check_command_line_dir(string const & dir,
                            string const & file,
                            string const & command_line_switch)
@@ -652,7 +714,7 @@ bool check_command_line_dir(string const & dir,
        FileName const abs_path = fileSearch(dir, file);
        if (abs_path.empty()) {
                // FIXME UNICODE
-               throw ExceptionMessage(WarningException, _("File not found"), bformat(
+               throw ExceptionMessage(ErrorException, _("File not found"), bformat(
                        _("Invalid %1$s switch.\nDirectory %2$s does not contain %3$s."),
                        from_utf8(command_line_switch), from_utf8(dir),
                        from_utf8(file)));
@@ -676,13 +738,13 @@ bool check_env_var_dir(FileName const & dir,
                       string const & file,
                       string const & env_var)
 {
-       FileName const abs_path = fileSearch(dir.absFilename(), file);
+       FileName const abs_path = fileSearch(dir.absFileName(), file);
        if (abs_path.empty()) {
                // FIXME UNICODE
                throw ExceptionMessage(WarningException, _("File not found"), bformat(
                        _("Invalid %1$s environment variable.\n"
                                "Directory %2$s does not contain %3$s."),
-                       from_utf8(env_var), from_utf8(dir.absFilename()),
+                       from_utf8(env_var), from_utf8(dir.absFileName()),
                        from_utf8(file)));
        }
 
@@ -707,7 +769,7 @@ bool check_env_var_dir(FileName const & dir,
                        _("Invalid %1$s environment variable.\n%2$s is not a directory.");
 
                throw ExceptionMessage(WarningException, _("Directory not found"), bformat(
-                       fmt, from_utf8(env_var), from_utf8(dir.absFilename())));
+                       fmt, from_utf8(env_var), from_utf8(dir.absFileName())));
        }
 
        return success;
@@ -739,7 +801,7 @@ string const relative_system_support_dir()
        return result;
 }
 
-} // namespace anon
+} // namespace
 
 } // namespace support
 } // namespace lyx