]> git.lyx.org Git - lyx.git/blobdiff - development/Win32/package.C
Fix some WorkArea fallouts
[lyx.git] / development / Win32 / package.C
index 3b18a3c2d9380596a48cef0148cfe9d8ecf148c2..fd92e5cea260f8c230fc94e706649ac41bb166ca 100644 (file)
 #include "debug.h"
 #include "gettext.h"
 
-#include "support/FileInfo.h"
+#include "support/environment.h"
 #include "support/filetools.h"
 #include "support/lstrings.h"
 #include "support/os.h"
 
 #include <boost/assert.hpp>
+#include <boost/filesystem/operations.hpp>
 #include <boost/tuple/tuple.hpp>
 
 #include <list>
 #endif
 
 #if defined (USE_WINDOWS_PACKAGING)
+
+/*
+ * MinGW's version of winver.h contains this comment:
+ *
+ * If you need Win32 API features newer the Win95 and WinNT then you must
+ * define WINVER before including windows.h or any other method of including
+ * the windef.h header.
+ *
+ * GetLongPathNameA requires WINVER == 0x0500.
+ *
+ * It doesn't matter if the Windows version is older than this because the
+ * function will compile but will fail at run time. See
+ * http://msdn.microsoft.com/library/en-us/mslu/winprog/microsoft_layer_for_unicode_apis_with_limited_support.asp
+ */
+# if defined(__MINGW32__)
+#  define WINVER 0x0500
+# endif
+
 # include <windows.h>
 # include <shlobj.h>  // SHGetFolderPath
 
@@ -51,6 +70,7 @@
 
 using std::string;
 
+namespace fs = boost::filesystem;
 
 namespace lyx {
 namespace support {
@@ -65,7 +85,8 @@ bool initialised_ = false;
 
 void init_package(string const & command_line_arg0,
                  string const & command_line_system_support_dir,
-                 string const & command_line_user_support_dir)
+                 string const & command_line_user_support_dir,
+                 exe_build_dir_to_top_build_dir top_build_dir_location)
 {
        // Can do so only once.
        if (initialised_)
@@ -73,7 +94,8 @@ void init_package(string const & command_line_arg0,
 
        package_ = Package(command_line_arg0,
                           command_line_system_support_dir,
-                          command_line_user_support_dir);
+                          command_line_user_support_dir,
+                          top_build_dir_location);
        initialised_ = true;
 }
 
@@ -92,7 +114,9 @@ namespace {
 
 string const abs_path_from_binary_name(string const & exe);
 
-std::pair<string, string> const get_build_dirs(string const & abs_binary);
+std::pair<string, string> const
+get_build_dirs(string const & abs_binary,
+              exe_build_dir_to_top_build_dir top_build_dir_location);
 
 string const get_document_dir(string const & home_dir);
 
@@ -116,7 +140,8 @@ get_user_support_dir(string const & default_user_support_dir,
 
 Package::Package(string const & command_line_arg0,
                 string const & command_line_system_support_dir,
-                string const & command_line_user_support_dir)
+                string const & command_line_user_support_dir,
+                exe_build_dir_to_top_build_dir top_build_dir_location)
        : explicit_user_support_dir_(false)
 {
        home_dir_ = get_home_dir();
@@ -128,7 +153,7 @@ Package::Package(string const & command_line_arg0,
 
        // Is LyX being run in-place from the build tree?
        boost::tie(build_support_dir_, system_support_dir_) =
-               get_build_dirs(abs_binary);
+               get_build_dirs(abs_binary, top_build_dir_location);
 
        if (build_support_dir_.empty())
                system_support_dir_ =
@@ -163,20 +188,20 @@ namespace {
 // configuration-time.
 string const top_srcdir()
 {
-       static string const dir("c:\\lyx\\lyx-devel");
+       static string const dir("%TOP_SRCDIR%");
        return dir;
 }
 
 
 string const hardcoded_localedir()
 {
-       return string("c:\\lyx\\lyx-devel\\lib\\locale");
+       return string("%LOCALEDIR%");
 }
 
 
 string const hardcoded_system_support_dir()
 {
-       return string("c:\\lyx\\lyx-devel\\lib");
+       return string("../../lib/");
 }
 
 } // namespace anon
@@ -184,7 +209,7 @@ string const hardcoded_system_support_dir()
 
 string const & Package::top_srcdir() const
 {
-       static string const dir("c:\\lyx\\lyx-devel");
+       static string const dir("%TOP_SRCDIR%");
        return dir;
 }
 
@@ -223,7 +248,27 @@ string const win32_folder_path(int folder_id)
 #endif
 
 
-std::pair<string, string> const get_build_dirs(string const & abs_binary)
+std::string const
+get_build_support_dir(std::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 NormalizePath(AddPath(binary_dir, indirection));
+}
+
+
+std::pair<string, string> const
+get_build_dirs(string const & abs_binary,
+              exe_build_dir_to_top_build_dir top_build_dir_location)
 {
        string const check_text = "Checking whether LyX is run in place...";
 
@@ -240,7 +285,7 @@ std::pair<string, string> const get_build_dirs(string const & abs_binary)
                // Try and find "lyxrc.defaults".
                string const binary_dir = OnlyPath(binary);
                string const build_support_dir =
-                       NormalizePath(AddPath(binary_dir, "../lib"));
+                       get_build_support_dir(binary_dir, top_build_dir_location);
 
                if (!FileSearch(build_support_dir, "lyxrc.defaults").empty()) {
                        // Try and find "chkconfig.ltx".
@@ -257,8 +302,7 @@ std::pair<string, string> const get_build_dirs(string const & abs_binary)
 
                // Check whether binary is a symbolic link.
                // If so, resolve it and repeat the exercise.
-               FileInfo const file(binary, true);
-               if (!file.isOK() || !file.isLink())
+               if (!fs::symbolic_link_exists(binary))
                        break;
 
                string link;
@@ -294,9 +338,9 @@ string const get_document_dir(string const & home_dir)
 string const get_home_dir()
 {
 #if defined (USE_WINDOWS_PACKAGING)
-       string const home_dir = GetEnv("USERPROFILE");
+       string const home_dir = getEnv("USERPROFILE");
 #else // Posix-like.
-       string const home_dir = GetEnv("HOME");
+       string const home_dir = getEnv("HOME");
 #endif
 
        return os::internal_path(home_dir);
@@ -317,14 +361,12 @@ string const get_locale_dir(string const & system_support_dir)
        // be "../locale/".)
        path = NormalizePath(AddPath(system_support_dir, relative_locale_dir()));
 
-       FileInfo fi(path);
-       if (fi.isOK() && fi.isDir())
+       if (fs::exists(path) && fs::is_directory(path))
                return path;
 
        // 3. Fall back to the hard-coded LOCALEDIR.
        path = hardcoded_localedir();
-       FileInfo fi2(path);
-       if (fi2.isOK() && fi2.isDir())
+       if (fs::exists(path) && fs::is_directory(path))
                return path;
 
        return string();
@@ -339,6 +381,7 @@ string const get_temp_dir()
        // Typical example: C:/TEMP/.
        char path[MAX_PATH + 1];
        GetTempPath(MAX_PATH, path);
+       GetLongPathName(path, path, MAX_PATH + 1);
        return os::internal_path(path);
 #else // Posix-like.
        return "/tmp";
@@ -371,14 +414,19 @@ string const abs_path_from_command_line(string const & command_line)
 // Does the grunt work for abs_path_from_binary_name()
 string const get_binary_path(string const & exe)
 {
-       string const exe_path = os::internal_path(exe);
+       // The executable may have been invoked either with or
+       // without the .exe extension.
+       // Ensure that it is present.
+       string const as_internal_path = os::internal_path(exe);
+       string const exe_path = suffixIs(as_internal_path, ".exe") ?
+               as_internal_path : as_internal_path + ".exe";
        if (os::is_absolute_path(exe_path))
                return exe_path;
 
        // Two possibilities present themselves.
        // 1. The binary is relative to the CWD.
        string const abs_exe_path = MakeAbsPath(exe_path);
-       if (FileInfo(abs_exe_path, true).isOK())
+       if (fs::exists(abs_exe_path))
                return abs_exe_path;
 
        // 2. exe must be the name of the binary only and it
@@ -395,7 +443,7 @@ string const get_binary_path(string const & exe)
                string const exe_dir = MakeAbsPath(*it);
 
                string const exe_path = AddName(exe_dir, exe_name);
-               if (FileInfo(exe_path, true).isOK())
+               if (fs::exists(exe_path))
                        return exe_path;
        }
 
@@ -473,8 +521,7 @@ get_system_support_dir(string const & abs_binary,
 
                // Check whether binary is a symbolic link.
                // If so, resolve it and repeat the exercise.
-               FileInfo const file(binary, true);
-               if (!file.isOK() || !file.isLink())
+               if (!fs::symbolic_link_exists(binary))
                        break;
 
                string link;
@@ -492,8 +539,7 @@ get_system_support_dir(string const & abs_binary,
                // This time test whether the directory is a symbolic link
                // *before* looking for "chkconfig.ltx".
                // (We've looked relative to the original already.)
-               FileInfo const file(binary_dir, true);
-               if (!file.isOK() || !file.isLink())
+               if (!fs::symbolic_link_exists(binary))
                        break;
 
                string link;
@@ -629,7 +675,7 @@ bool check_command_line_dir(string const & dir,
 // The environment variable @c env_var expands to a (single) file path.
 string const extract_env_var_dir(string const & env_var)
 {
-       string const dir = os::internal_path(GetEnv(env_var));
+       string const dir = os::internal_path(getEnv(env_var));
        return dir.empty() ? dir : MakeAbsPath(dir);
 }
 
@@ -657,8 +703,7 @@ bool check_env_var_dir(string const & dir,
 bool check_env_var_dir(string const & dir,
                       string const & env_var)
 {
-       FileInfo fi(dir);
-       bool const success = (fi.isOK() && fi.isDir());
+       bool const success = (fs::exists(dir) && fs::is_directory(dir));
 
        if (!success) {
                // Put this string on a single line so that the gettext
@@ -667,7 +712,7 @@ bool check_env_var_dir(string const & dir,
                // translation.
                string const fmt =
                _("Invalid %1$s environment variable.\n%2$s is not a directory.");
-               
+
                lyxerr << bformat(fmt, env_var, dir)
                       << std::endl;
        }