]> git.lyx.org Git - features.git/commitdiff
remove special handling of Package.cpp[.in]
authorAndré Pönitz <poenitz@gmx.net>
Mon, 27 Aug 2007 21:29:56 +0000 (21:29 +0000)
committerAndré Pönitz <poenitz@gmx.net>
Mon, 27 Aug 2007 21:29:56 +0000 (21:29 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19840 a592a061-630c-0410-9148-cb99ea01b6c8

configure.ac
development/cmake/config.h.cmake
development/cmake/src/support/CMakeLists.txt
development/qmake/app/app.pro
development/qmake/support/support.pro
development/scons/SConstruct
development/scons/scons_manifest.py
po/POTFILES.in
src/support/Makefile.am
src/support/Package.cpp [new file with mode: 0644]
src/support/Package.cpp.in [deleted file]

index 5d2650036ab034a0dc0e5d32616444315a5f7ea9..39d2292e7d628cf7fdc55715c35b677ca62260a2 100644 (file)
@@ -312,19 +312,12 @@ ${FRONTEND_INFO}\
   LyX binary dir:               ${real_bindir}\n\
   LyX files dir:                ${real_pkgdatadir}\n"
 
-MSYS_AC_CANONICAL_PATH(LYX_ABS_TOP_SRCDIR, ${srcdir})
-MSYS_AC_CANONICAL_PATH(LYX_ABS_INSTALLED_LOCALEDIR, ${real_localedir})
-MSYS_AC_CANONICAL_PATH(LYX_ABS_INSTALLED_DATADIR, ${real_pkgdatadir})
-
 AC_SUBST(VERSION_INFO)
 AC_SUBST(RPM_FRONTEND)
 AC_SUBST(AM_CPPFLAGS)
 AC_SUBST(AM_CXXFLAGS)
 AC_SUBST(AM_CFLAGS)
 AC_SUBST(AM_LDFLAGS)
-AC_SUBST(LYX_ABS_TOP_SRCDIR)
-AC_SUBST(LYX_ABS_INSTALLED_LOCALEDIR)
-AC_SUBST(LYX_ABS_INSTALLED_DATADIR)
 
 ## Some config.h stuff
 
@@ -454,6 +447,19 @@ AC_ARG_ENABLE(monolithic-frontend-qt4,
   [enable_monolithic_frontend_qt4=no])
 AM_CONDITIONAL(MONOLITHIC_FRONTEND_QT4, test "$enable_monolithic_frontend_qt4" = "yes")
 
+MSYS_AC_CANONICAL_PATH(lyx_abs_top_srcdir, ${srcdir})
+MSYS_AC_CANONICAL_PATH(lyx_abs_installed_localedir, ${real_localedir})
+MSYS_AC_CANONICAL_PATH(lyx_abs_installed_datadir, ${real_pkgdatadir})
+
+AC_DEFINE_UNQUOTED([LYX_ABS_TOP_SRCDIR],
+       "${lyx_abs_top_srcdir}", [Top source directory])
+AC_DEFINE_UNQUOTED([LYX_ABS_INSTALLED_LOCALEDIR],
+       "${lyx_abs_installed_localedir}",[Hard coded locale directory])
+AC_DEFINE_UNQUOTED([LYX_ABS_INSTALLED_DATADIR],
+       "${lyx_abs_installed_datadir}",[Hard system support directory])
+AC_DEFINE_UNQUOTED([PROGRAM_SUFFIX],
+       "${version_suffix}",[Program version suffix])
+
 AC_DEFINE_UNQUOTED([LYX_DATE],"$LYX_DATE",[Date of release])
 AC_DEFINE_UNQUOTED([VERSION_INFO],"$VERSION_INFO",[Full version info])
 AC_DEFINE_UNQUOTED([LYX_MAJOR_VERSION],$lyx_major,[Major version number])
@@ -461,7 +467,6 @@ AC_DEFINE_UNQUOTED([LYX_MINOR_VERSION],$lyx_minor,[Minor version number])
 AC_DEFINE_UNQUOTED([LYX_RELEASE_LEVEL],$lyx_release,[Release version number])
 AC_DEFINE_UNQUOTED([LYX_RELEASE_PATCH],$lyx_patch,[Patch version number])
 
-
 AC_CONFIG_FILES([Makefile
       boost/Makefile \
       config/Makefile \
@@ -472,7 +477,7 @@ AC_CONFIG_FILES([Makefile
       development/MacOSX/spotlight/Makefile \
       development/lyx.spec \
       intl/Makefile \
-      lib/Makefile \
+     lib/Makefile \
       lib/doc/Makefile \
       lib/lyx2lyx/lyx2lyx_version.py \
       lib/lyx2lyx/Makefile \
index 55da8fa75013cf8ba2833272a13dc883c4c0b0a0..8f15e9ff552adb69484b8b195cd619afa01b0f6d 100644 (file)
 #cmakedefine LYX_DATE "${LYX_DATE}"
 #cmakedefine VERSION_INFO "${VERSION_INFO}"
 
+#cmakedefine PROGRAM_SUFFIX "${PPROGRAM_SUFFIX}"
+#cmakedefine LYX_ABS_INSTALLED_DATADIR "${LYX_DIR}"
+#cmakedefine LYX_ABS_INSTALLED_LOCALEDIR "${LOCALEDIR}"
+#cmakedefine LYX_ABS_TOP_SRCDIR "${TOP_SRCDIR}"
 
 #cmakedefine USE_POSIX_PACKAGING 1
 #cmakedefine USE_WINDOWS_PACKAGING 1
index 0221d64d6736e38cd8c3aeed987f30f754999a62..594af5dcc03f5fcc49f2ae02c7d52073d3b89c31 100644 (file)
@@ -6,8 +6,8 @@
 
 project(support)
 
-configure_file(${TOP_SRC_DIR}/src/support/Package.cpp.in 
-               ${CMAKE_CURRENT_BINARY_DIR}/package.C)
+#configure_file(${TOP_SRC_DIR}/src/support/Package.cpp.in 
+#               ${CMAKE_CURRENT_BINARY_DIR}/package.C)
 
 file(GLOB support_sources ${TOP_SRC_DIR}/src/support/${LYX_CPP_FILES})
 file(GLOB support_headers ${TOP_SRC_DIR}/src/support/${LYX_HPP_FILES})
@@ -25,7 +25,7 @@ list(REMOVE_ITEM support_sources
        ${TOP_SRC_DIR}/src/support/minizip/iowin32.h
        ${TOP_SRC_DIR}/src/support/minizip/iowin32.c)
 
-set(support_sources ${support_sources} ${CMAKE_CURRENT_BINARY_DIR}/package.C)
+#set(support_sources ${support_sources} ${CMAKE_CURRENT_BINARY_DIR}/package.C)
 
 lyx_add_msvc_pch(support)
        
index 626f5662045fb4415aca6a7294e08209f09595ab..791a07a41c26fd1535a84013f5fcf909c062b089 100644 (file)
@@ -21,7 +21,6 @@ LIBS += -lAiksaurus
 
 LIBS += -L../lib
 
-LIBS += ../support/$(OBJECTS_DIR)/Package.o
 LIBS += -Wl,--start-group
 LIBS += -llyxmathed$${DEBUGSUFFIX}
 LIBS += -llyxinsets$${DEBUGSUFFIX}
index d4dcf9a4ae0d51f09f13bca0bbf41939d3e74cc2..ca5318ad5773af4137e496236bf7864ca8dd5d8d 100644 (file)
@@ -55,6 +55,7 @@ CPP += FileName.cpp
 CPP += ForkedCallQueue.cpp
 CPP += Forkedcall.cpp
 CPP += ForkedcallsController.cpp
+CPP += Package.cpp
 CPP += Path.cpp
 CPP += Systemcall.cpp
 CPP += Timeout.cpp
@@ -84,63 +85,6 @@ CPP += unicode.cpp
 CPP += unlink.cpp
 CPP += userinfo.cpp
 
-
-QMAKE_RUN_CXX1  = $(CXX) -c $(CXXFLAGS) $(INCPATH)
-
-#packagetarget.target = Package.cpp
-#packagetarget.commands = \
-#      @rm -f tmp_package ;\
-#      sed \'s,@LYX_DIR@,$(LYX_ABS_INSTALLED_DATADIR),;\
-#s,@LOCALEDIR@,$(LYX_ABS_INSTALLED_LOCALEDIR),;\
-#s,@TOP_SRCDIR@,$(LYX_ABS_TOP_SRCDIR),;\
-#s,@PROGRAM_SUFFIX@,$(program_suffix),\' \
-#              $${BUILD_BASE_SOURCE_DIR}/src/support/Package.cpp.in > tmp_package ;\
-#      if cmp -s tmp_package Package.cpp ; then \
-#              rm -f tmp_package ;\
-#      else \
-#              rm -f Package.cpp ;\
-#              cp tmp_package Package.cpp ;\
-#      fi
-#packagetarget.depends = config.h
-#packagetarget.variable_out = SOURCES
-#packagetarget.CONFIG = no_link
-##SOURCES += $${BUILD_BASE_TARGET_DIR}/src/Package.cpp
-#QMAKE_EXTRA_TARGETS += packagetarget
-#
-##OBJECTS += $(OBJECTS_DIR)/Package.o 
-#POST_TARGETDEPS += $(OBJECTS_DIR)/Package.o 
-
-packagetarget.target = Package.cpp
-packagetarget.commands = \
-       @rm -f tmp_package ;\
-       sed \'s,@LYX_DIR@,$(LYX_ABS_INSTALLED_DATADIR),;\
-s,@LOCALEDIR@,$(LYX_ABS_INSTALLED_LOCALEDIR),;\
-s,@TOP_SRCDIR@,$(LYX_ABS_TOP_SRCDIR),;\
-s,@PROGRAM_SUFFIX@,$(program_suffix),\' \
-               $${BUILD_BASE_SOURCE_DIR}/src/support/Package.cpp.in > tmp_package ;\
-       if cmp -s tmp_package Package.cpp ; then \
-               rm -f tmp_package ;\
-       else \
-               rm -f Package.cpp ;\
-               cp tmp_package Package.cpp ;\
-       fi
-#packagetarget.depends = config.h
-packagetarget.CONFIG = no_link
-#SOURCES += $${BUILD_BASE_TARGET_DIR}/src/Package.cpp
-packagetarget2.target = $(OBJECTS_DIR)/Package.o
-packagetarget2.commands = $${QMAKE_RUN_CXX1} -c Package.cpp \
-       -o $(OBJECTS_DIR)/Package.o
-packagetarget2.depends = Package.cpp
-QMAKE_EXTRA_TARGETS += packagetarget packagetarget2
-QMAKE_CLEAN += $(OBJECTS_DIR)/Package.o Package.cpp
-
-PRE_TARGETDEPS += $(OBJECTS_DIR)/Package.o 
-
-LIBS += $(OBJECTS_DIR)/Package.o
-
 for(FILE,CPP) { SOURCES += $${BUILD_BASE_SOURCE_DIR}/src/support/$${FILE} }
 for(FILE,HPP) { HEADERS += $${BUILD_BASE_SOURCE_DIR}/src/support/$${FILE} }
 for(PATH,INC) { INCLUDEPATH += $${BUILD_BASE_SOURCE_DIR}/$${PATH} }
index b07cd0e5aa0f1dccd075ebe29b176638207b2f93..e66633e5c309c7ec7a6e7e5a4723f1880064c841 100644 (file)
@@ -350,10 +350,11 @@ env.AppendUnique(LIBPATH = ['$LOCALLIBPATH'])
 # 3. compiler commands and flags like CCFLAGS.
 #     MSGFMT used to process po files
 # 4. Variables that will be used to replace variables in some_file.in
-#     src/support/Package.cpp.in:
-#       TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX
 #     lib/lyx2lyx/lyx2lyx_version.py.in
 #       PACKAGE_VERSION
+# FIXME Bo: Please look here, that's not needed anymore (Andre')
+#     src/support/Package.cpp.in:
+#       TOP_SRCDIR, LOCALEDIR, LYX_DIR, PROGRAM_SUFFIX
 
 # full path name is used to build msvs project files
 # and to replace TOP_SRCDIR in package.C
@@ -383,6 +384,8 @@ if env.has_key('version_suffix'):
         program_suffix = env['version_suffix']
 else:
     program_suffix = ''
+
+# FIXME Bo: Please look here, can this be simplified? (Andre')
 # used by Package.cpp.in
 env['PROGRAM_SUFFIX'] = program_suffix
 
@@ -1042,6 +1045,14 @@ result = utils.createConfigFile(conf,
             'Full version info'),
         ('#define LYX_DATE "%s"' % lyx_date,
             'Date of release'),
+        ('#define PROGRAM_SUFFIX "%s"' % '$PROGRAM_SUFFIX',
+            'Program version suffix'),
+        ('#define LYX_ABS_INSTALLED_DATADIR "%s"' % '$LYX_DIR',
+            'Hard coded system support directory'),
+        ('#define LYX_ABS_INSTALLED_LOCALEDIR "%s"' % '$LOCALEDIR',
+            'Hard coded locale directory'),
+        ('#define LYX_ABS_TOP_SRCDIR "%s"' % '$TOP_SRCDIR',
+            'Top source directory'),
         ('#define BOOST_ALL_NO_LIB 1',
             'disable automatic linking of boost libraries.'),
         ('#define USE_%s_PACKAGING 1' % packaging_method.upper(),
index 46b1ce039f45b5632346822e36f1ac62a8c53114..d57cec9741f9428032f28c36c26d51c04f90aee1 100644 (file)
@@ -340,6 +340,7 @@ src_support_files = Split('''
     ForkedCallQueue.cpp
     Forkedcall.cpp
     ForkedcallsController.cpp
+    Package.cpp
     Path.cpp
     Systemcall.cpp
     Timeout.cpp
@@ -377,7 +378,6 @@ src_support_extra_header_files = Split('''
 
 
 src_support_extra_src_files = Split('''
-    Package.cpp.in
     atexit.c
     os_cygwin.cpp
     os_unix.cpp
index db9f98e49eaed0118888fe4e42a521072a87a412..e0c0538533d2390a45ee44dc2c44a777ebd3b1c4 100644 (file)
@@ -32,7 +32,6 @@ src/callback.cpp
 src/client/debug.cpp
 src/debug.cpp
 src/frontends/LyXView.cpp
-src/frontends/WorkArea.cpp
 src/frontends/controllers/ControlAboutlyx.cpp
 src/frontends/controllers/ControlBibtex.cpp
 src/frontends/controllers/ControlBox.cpp
@@ -144,7 +143,6 @@ src/output.cpp
 src/output_plaintext.cpp
 src/rowpainter.cpp
 src/support/FileFilterList.cpp
-src/support/Package.cpp.in
 src/support/filetools.cpp
 src/support/os_win32.cpp
 src/support/userinfo.cpp
index e26d035a6b7bef069d684bec9911d695de5e0188..1692e9fa60bc9b23eb9de6573c938377249bf862 100644 (file)
@@ -2,7 +2,7 @@ include $(top_srcdir)/config/common.am
 
 CLEANFILES += $(BUILT_SOURCES)
 
-EXTRA_DIST = Package.cpp.in pch.h \
+EXTRA_DIST = pch.h \
        os_cygwin.cpp os_unix.cpp os_win32.cpp os_win32.h
 
 pkglib_LTLIBRARIES = liblyxsupport.la
@@ -10,7 +10,7 @@ pkglib_LTLIBRARIES = liblyxsupport.la
 liblyxsupport_la_LIBADD = $(LIBSHLWAPI) $(QT4_CORE_LIB) $(BOOST_SIGNALS)
 liblyxsupport_la_LDFLAGS = $(QT4_CORE_LDFLAGS)
 
-BUILT_SOURCES = $(PCH_FILE) Package.cpp
+BUILT_SOURCES = $(PCH_FILE)
 
 AM_CPPFLAGS += $(PCH_FLAGS) -I$(srcdir)/.. $(BOOST_INCLUDES)
 AM_CPPFLAGS += $(QT4_CPPFLAGS) $(QT4_CORE_INCLUDES) -I$(srcdir)/minizip
@@ -103,24 +103,6 @@ liblyxsupport_la_SOURCES = \
        minizip/zip.c \
        minizip/zip.h
 
-Package.cpp: build_package
-
-# Solaris sed does not like spaces bewteen the ;-delimited commands
-build_package: Package.cpp.in
-       @rm -f tmp_package ;\
-       sed "s,@LYX_DIR@,$(LYX_ABS_INSTALLED_DATADIR),;\
-s,@LOCALEDIR@,$(LYX_ABS_INSTALLED_LOCALEDIR),;\
-s,@TOP_SRCDIR@,$(LYX_ABS_TOP_SRCDIR),;\
-s,@PROGRAM_SUFFIX@,$(program_suffix)," \
-               $(srcdir)/Package.cpp.in > tmp_package ;\
-       if cmp -s tmp_package Package.cpp ; then \
-               rm -f tmp_package ;\
-       else \
-               rm -f Package.cpp ;\
-               mv tmp_package Package.cpp ;\
-       fi
-
-
 ############################## Tests ##################################
 
 EXTRA_DIST += tests/test_convert tests/test_filetools \
diff --git a/src/support/Package.cpp b/src/support/Package.cpp
new file mode 100644 (file)
index 0000000..3535f7a
--- /dev/null
@@ -0,0 +1,748 @@
+// -*- C++ -*-
+/**
+ * \file package.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author Angus Leeming
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "support/Package.h"
+
+#include "debug.h"
+#include "gettext.h"
+
+#include "support/environment.h"
+#include "support/filetools.h"
+#include "support/lstrings.h"
+#include "support/ExceptionMessage.h"
+#include "support/os.h"
+
+#if defined (USE_WINDOWS_PACKAGING)
+# include "support/os_win32.h"
+#endif
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/tuple/tuple.hpp>
+
+#include <list>
+#include <utility>
+
+#if !defined (USE_WINDOWS_PACKAGING) && \
+    !defined (USE_MACOSX_PACKAGING) && \
+    !defined (USE_POSIX_PACKAGING)
+#error USE_FOO_PACKAGING must be defined for FOO = WINDOWS, MACOSX or POSIX.
+#endif
+
+#if defined (USE_MACOSX_PACKAGING)
+# include <CoreServices/CoreServices.h> // FSFindFolder, FSRefMakePath
+#endif
+
+using std::string;
+
+namespace fs = boost::filesystem;
+
+namespace lyx {
+namespace support {
+
+namespace {
+
+Package package_;
+bool initialised_ = false;
+
+} // namespace anon
+
+
+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)
+{
+       // 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);
+       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_);
+       return package_;
+}
+
+
+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);
+
+FileName const get_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);
+
+
+string const & with_version_suffix();
+
+} // namespace anon
+
+
+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)
+       : explicit_user_support_dir_(false)
+{
+       home_dir_ = get_home_dir();
+       system_temp_dir_ = get_temp_dir();
+       temp_dir_ = system_temp_dir_;
+       document_dir_ = get_document_dir(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);
+
+       // 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);
+
+       if (build_support_dir_.empty())
+               system_support_dir_ =
+                       get_system_support_dir(abs_binary,
+                                              command_line_system_support_dir);
+
+       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);
+
+       FileName const configure_script(addName(system_support().absFilename(), "configure.py"));
+       configure_command_ = os::python() + ' ' +
+                       quoteName(configure_script.toFilesystemEncoding()) +
+                       with_version_suffix();
+
+       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;
+}
+
+
+namespace {
+
+// These next functions contain the stuff that is substituted at
+// configuration-time.
+FileName const hardcoded_localedir()
+{
+       // FIXME UNICODE
+       // The build system needs to make sure that this is in utf8 encoding.
+       return FileName(LYX_ABS_INSTALLED_LOCALEDIR);
+}
+
+
+FileName const hardcoded_system_support_dir()
+{
+       // FIXME UNICODE
+       // The build system needs to make sure that this is in utf8 encoding.
+       return FileName(LYX_ABS_INSTALLED_DATADIR);
+}
+
+
+string const & with_version_suffix()
+{
+       static string const program_suffix = PROGRAM_SUFFIX;
+       static string const with_version_suffix =
+               " --with-version-suffix=" PROGRAM_SUFFIX;
+       return program_suffix.empty() ? program_suffix : with_version_suffix;
+}
+
+} // namespace anon
+
+
+FileName const & Package::top_srcdir()
+{
+       // FIXME UNICODE
+       // The build system needs to make sure that this is in utf8 encoding.
+       static FileName const dir(LYX_ABS_TOP_SRCDIR);
+       return dir;
+}
+
+
+namespace {
+
+bool check_command_line_dir(string const & dir,
+                           string const & file,
+                           string const & command_line_switch);
+
+FileName const extract_env_var_dir(string const & env_var);
+
+bool check_env_var_dir(FileName const & dir,
+                      string const & env_var);
+
+bool check_env_var_dir(FileName const & dir,
+                      string const & file,
+                      string const & env_var);
+
+string const relative_locale_dir();
+
+string const relative_system_support_dir();
+
+
+/**
+ * Convert \p name to internal path and strip a trailing slash, since it
+ * comes from user input (commandline or environment).
+ * \p name is encoded in utf8.
+ */
+string const fix_dir_name(string const & name)
+{
+       return rtrim(os::internal_path(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)));
+}
+
+
+std::pair<FileName, FileName> const
+get_build_dirs(FileName 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...";
+
+       // We're looking for "Makefile" in a directory
+       //   binary_dir/../lib
+       // We're also looking for "chkconfig.ltx" in a directory
+       //   top_srcdir()/lib
+       // If both are found, then we're running LyX in-place.
+
+       // 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;
+       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()) {
+                       // Try and find "chkconfig.ltx".
+                       string const system_support_dir =
+                               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);
+                       }
+               }
+
+               // Check whether binary is a symbolic link.
+               // If so, resolve it and repeat the exercise.
+               if (!fs::symbolic_link_exists(binary.toFilesystemEncoding()))
+                       break;
+
+               FileName link;
+               if (readLink(binary, link)) {
+                       binary = link;
+               } else {
+                       // Unable to resolve the link.
+                       break;
+               }
+       }
+
+       lyxerr[Debug::INIT] << check_text << " no" << std::endl;
+       return std::make_pair(FileName(), FileName());
+}
+
+
+// Specification of document_dir_ may be reset by LyXRC,
+// but the default is fixed for a given OS.
+FileName const get_document_dir(FileName const & home_dir)
+{
+#if defined (USE_WINDOWS_PACKAGING)
+       (void)home_dir; // Silence warning about unused variable.
+       os::GetFolderPath win32_folder_path;
+       return FileName(win32_folder_path(os::GetFolderPath::PERSONAL));
+#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.
+FileName const get_locale_dir(FileName const & system_support_dir)
+{
+       // 1. Use the "LYX_LOCALEDIR" environment variable.
+       FileName const path_env = extract_env_var_dir("LYX_LOCALEDIR");
+       if (!path_env.empty() && check_env_var_dir(path_env, "LYX_LOCALEDIR"))
+               return path_env;
+
+       // 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())));
+
+       if (fs::exists(path.toFilesystemEncoding()) &&
+           fs::is_directory(path.toFilesystemEncoding()))
+               return path;
+
+       // 3. Fall back to the hard-coded LOCALEDIR.
+       path = hardcoded_localedir();
+       if (fs::exists(path.toFilesystemEncoding()) &&
+           fs::is_directory(path.toFilesystemEncoding()))
+               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);
+}
+
+
+// Does the grunt work for abs_path_from_binary_name()
+FileName const get_binary_path(string const & exe)
+{
+#if defined (USE_WINDOWS_PACKAGING)
+       // 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";
+#else
+       string const exe_path = os::internal_path(exe);
+#endif
+       if (os::is_absolute_path(exe_path))
+               return FileName(exe_path);
+
+       // Two possibilities present themselves.
+       // 1. The binary is relative to the CWD.
+       FileName const abs_exe_path = makeAbsPath(exe_path);
+       if (fs::exists(abs_exe_path.toFilesystemEncoding()))
+               return abs_exe_path;
+
+       // 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);
+       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();
+       for (; it != end; ++it) {
+               // This will do nothing if *it is already absolute.
+               string const exe_dir = makeAbsPath(*it).absFilename();
+
+               FileName const exe_path(addName(exe_dir, exe_name));
+               if (fs::exists(exe_path.toFilesystemEncoding()))
+                       return exe_path;
+       }
+
+       // Didn't find anything.
+       return FileName();
+}
+
+
+// Extracts the absolute path to the binary name received as argv[0].
+FileName const abs_path_from_binary_name(string const & exe)
+{
+       FileName const abs_binary = get_binary_path(exe);
+       if (abs_binary.empty()) {
+               // FIXME UNICODE
+               throw ExceptionMessage(ErrorException,
+                       _("LyX binary not found"),
+                       bformat(_("Unable to determine the path to the LyX binary from the command line %1$s"),
+                               from_utf8(exe)));
+       }
+       return abs_binary;
+}
+
+
+// A plethora of directories is searched to ascertain the system
+// lyxdir which is defined as the first directory to contain
+// "chkconfig.ltx".
+FileName const
+get_system_support_dir(FileName const & abs_binary,
+                 string const & command_line_system_support_dir)
+{
+       string const chkconfig_ltx = "chkconfig.ltx";
+
+       // searched_dirs is used for diagnostic purposes only in the case
+       // that "chkconfig.ltx" is not found.
+       std::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"))
+                       return path;
+       }
+
+       // 2. Use the "LYX_DIR_15x" environment variable.
+       path = extract_env_var_dir("LYX_DIR_15x");
+       if (!path.empty()) {
+               searched_dirs.push_back(path);
+               if (check_env_var_dir(path, chkconfig_ltx, "LYX_DIR_15x"))
+                       return path;
+       }
+
+       // 3. Search relative to the lyx binary.
+       // We're looking for "chkconfig.ltx" in a directory
+       //   OnlyPath(abs_binary) / <relative dir> / PACKAGE /
+       // PACKAGE is hardcoded in config.h. Eg "lyx" or "lyx-1.3.6cvs".
+       // <relative dir> is OS-dependent; on Unix, it will be "../share/".
+       string const relative_lyxdir = relative_system_support_dir();
+
+       // One subtlety to be aware of. 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;
+       while (true) {
+               // Try and find "chkconfig.ltx".
+               string const binary_dir = onlyPath(binary.absFilename());
+
+               FileName const lyxdir(
+                       normalizePath(addPath(binary_dir, relative_lyxdir)));
+               searched_dirs.push_back(lyxdir);
+
+               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()))
+                       break;
+
+               FileName link;
+               if (readLink(binary, link)) {
+                       binary = link;
+               } else {
+                       // Unable to resolve the link.
+                       break;
+               }
+       }
+
+       // 4. Repeat the exercise on the directory itself.
+       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()))
+                       break;
+
+               FileName link;
+               if (readLink(binary_dir, link)) {
+                       binary_dir = link;
+               } else {
+                       // Unable to resolve the link.
+                       break;
+               }
+
+               // Try and find "chkconfig.ltx".
+               FileName const lyxdir(
+                       normalizePath(addPath(binary_dir.absFilename(), relative_lyxdir)));
+               searched_dirs.push_back(lyxdir);
+
+               if (!fileSearch(lyxdir.absFilename(), chkconfig_ltx).empty()) {
+                       // Success! "chkconfig.ltx" has been found.
+                       return lyxdir;
+               }
+       }
+
+       // 5. In desparation, try the hard-coded system support dir.
+       path = hardcoded_system_support_dir();
+       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;
+       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();
+       }
+
+       // 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();
+}
+
+
+// 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 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);
+
+       // 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);
+
+       // 3. Use the OS-dependent default_user_support_dir
+       explicit_userdir = false;
+       return std::make_pair(default_user_support_dir, explicit_userdir);
+}
+
+
+// $HOME/.lyx on POSIX but on Win32 it will be something like
+// "C:/Documents and Settings/USERNAME/Application Data/LyX"
+FileName const get_default_user_support_dir(FileName const & home_dir)
+{
+#if defined (USE_WINDOWS_PACKAGING)
+       (void)home_dir; // Silence warning about unused variable.
+
+       os::GetFolderPath win32_folder_path;
+       return FileName(addPath(win32_folder_path(os::GetFolderPath::APPDATA), PACKAGE));
+
+#elif defined (USE_MACOSX_PACKAGING)
+       (void)home_dir; // Silence warning about unused variable.
+
+       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();
+
+       return FileName(addPath(reinterpret_cast<char const *>(store), PACKAGE));
+
+#else // USE_POSIX_PACKAGING
+       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.
+bool check_command_line_dir(string const & dir,
+                           string const & file,
+                           string const & command_line_switch)
+{
+       FileName const abs_path = fileSearch(dir, file);
+       if (abs_path.empty()) {
+               // FIXME UNICODE
+               throw ExceptionMessage(WarningException, _("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)));
+       }
+
+       return !abs_path.empty();
+}
+
+
+// The environment variable @c env_var expands to a (single) file path.
+FileName const extract_env_var_dir(string const & env_var)
+{
+       string const dir = fix_dir_name(getEnv(env_var));
+       return dir.empty() ? FileName() : makeAbsPath(dir);
+}
+
+
+// Check that directory @c dir contains @c file.
+// Else emit a warning about an invalid @c env_var.
+bool check_env_var_dir(FileName const & dir,
+                      string const & file,
+                      string const & env_var)
+{
+       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(file)));
+       }
+
+       return !abs_path.empty();
+}
+
+
+// Check that directory @c dir is indeed a directory.
+// Else emit a warning about an invalid @c env_var.
+bool check_env_var_dir(FileName const & dir,
+                      string const & env_var)
+{
+       string const encoded(dir.toFilesystemEncoding());
+       bool const success = (fs::exists(encoded) && fs::is_directory(encoded));
+
+       if (!success) {
+               // Put this string on a single line so that the gettext
+               // search mechanism in po/Makefile.in.in will register
+               // Package.cpp.in as a file containing strings that need
+               // translation.
+               // FIXME UNICODE
+               docstring const fmt =
+                       _("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())));
+       }
+
+       return success;
+}
+
+
+// The locale directory relative to the LyX system directory.
+string const relative_locale_dir()
+{
+#if defined (USE_WINDOWS_PACKAGING) || defined (USE_MACOSX_PACKAGING)
+       return "locale/";
+#else
+       return "../locale/";
+#endif
+}
+
+
+// The system lyxdir is relative to the directory containing the LyX binary.
+string const relative_system_support_dir()
+{
+       string result;
+
+#if defined (USE_WINDOWS_PACKAGING) || defined (USE_MACOSX_PACKAGING)
+       result = "../Resources/";
+#else // Posix-like.
+       result = addPath("../share/", PACKAGE);
+#endif
+
+       return result;
+}
+
+} // namespace anon
+
+} // namespace support
+} // namespace lyx
diff --git a/src/support/Package.cpp.in b/src/support/Package.cpp.in
deleted file mode 100644 (file)
index 0a6d812..0000000
+++ /dev/null
@@ -1,751 +0,0 @@
-// -*- C++ -*-
-/**
- * \file package.C
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author Angus Leeming
- *
- * Full author contact details are available in file CREDITS.
- *
- * Warning! This file is autogenerated from Package.cpp.in.
- * All changes to this file will be lost.
- */
-
-#include <config.h>
-
-#include "support/Package.h"
-
-#include "debug.h"
-#include "gettext.h"
-
-#include "support/environment.h"
-#include "support/filetools.h"
-#include "support/lstrings.h"
-#include "support/ExceptionMessage.h"
-#include "support/os.h"
-
-#if defined (USE_WINDOWS_PACKAGING)
-# include "support/os_win32.h"
-#endif
-
-#include <boost/filesystem/operations.hpp>
-#include <boost/tuple/tuple.hpp>
-
-#include <list>
-#include <utility>
-
-#if !defined (USE_WINDOWS_PACKAGING) && \
-    !defined (USE_MACOSX_PACKAGING) && \
-    !defined (USE_POSIX_PACKAGING)
-#error USE_FOO_PACKAGING must be defined for FOO = WINDOWS, MACOSX or POSIX.
-#endif
-
-#if defined (USE_MACOSX_PACKAGING)
-# include <CoreServices/CoreServices.h> // FSFindFolder, FSRefMakePath
-#endif
-
-using std::string;
-
-namespace fs = boost::filesystem;
-
-namespace lyx {
-namespace support {
-
-namespace {
-
-Package package_;
-bool initialised_ = false;
-
-} // namespace anon
-
-
-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)
-{
-       // 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);
-       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_);
-       return package_;
-}
-
-
-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);
-
-FileName const get_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);
-
-
-string const & with_version_suffix();
-
-} // namespace anon
-
-
-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)
-       : explicit_user_support_dir_(false)
-{
-       home_dir_ = get_home_dir();
-       system_temp_dir_ = get_temp_dir();
-       temp_dir_ = system_temp_dir_;
-       document_dir_ = get_document_dir(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);
-
-       // 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);
-
-       if (build_support_dir_.empty())
-               system_support_dir_ =
-                       get_system_support_dir(abs_binary,
-                                              command_line_system_support_dir);
-
-       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);
-
-       FileName const configure_script(addName(system_support().absFilename(), "configure.py"));
-       configure_command_ = os::python() + ' ' +
-                       quoteName(configure_script.toFilesystemEncoding()) +
-                       with_version_suffix();
-
-       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;
-}
-
-
-namespace {
-
-// These next functions contain the stuff that is substituted at
-// configuration-time.
-FileName const hardcoded_localedir()
-{
-       // FIXME UNICODE
-       // The build system needs to make sure that this is in utf8 encoding.
-       return FileName("@LOCALEDIR@");
-}
-
-
-FileName const hardcoded_system_support_dir()
-{
-       // FIXME UNICODE
-       // The build system needs to make sure that this is in utf8 encoding.
-       return FileName("@LYX_DIR@");
-}
-
-
-string const & with_version_suffix()
-{
-       static string const program_suffix("@PROGRAM_SUFFIX@");
-       static string const
-               with_version_suffix(" --with-version-suffix=@PROGRAM_SUFFIX@");
-       return program_suffix.empty() ? program_suffix : with_version_suffix;
-}
-
-} // namespace anon
-
-
-FileName const & Package::top_srcdir()
-{
-       // FIXME UNICODE
-       // The build system needs to make sure that this is in utf8 encoding.
-       static FileName const dir("@TOP_SRCDIR@");
-       return dir;
-}
-
-
-namespace {
-
-bool check_command_line_dir(string const & dir,
-                           string const & file,
-                           string const & command_line_switch);
-
-FileName const extract_env_var_dir(string const & env_var);
-
-bool check_env_var_dir(FileName const & dir,
-                      string const & env_var);
-
-bool check_env_var_dir(FileName const & dir,
-                      string const & file,
-                      string const & env_var);
-
-string const relative_locale_dir();
-
-string const relative_system_support_dir();
-
-
-/**
- * Convert \p name to internal path and strip a trailing slash, since it
- * comes from user input (commandline or environment).
- * \p name is encoded in utf8.
- */
-string const fix_dir_name(string const & name)
-{
-       return rtrim(os::internal_path(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)));
-}
-
-
-std::pair<FileName, FileName> const
-get_build_dirs(FileName 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...";
-
-       // We're looking for "Makefile" in a directory
-       //   binary_dir/../lib
-       // We're also looking for "chkconfig.ltx" in a directory
-       //   top_srcdir()/lib
-       // If both are found, then we're running LyX in-place.
-
-       // 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;
-       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()) {
-                       // Try and find "chkconfig.ltx".
-                       string const system_support_dir =
-                               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);
-                       }
-               }
-
-               // Check whether binary is a symbolic link.
-               // If so, resolve it and repeat the exercise.
-               if (!fs::symbolic_link_exists(binary.toFilesystemEncoding()))
-                       break;
-
-               FileName link;
-               if (readLink(binary, link)) {
-                       binary = link;
-               } else {
-                       // Unable to resolve the link.
-                       break;
-               }
-       }
-
-       lyxerr[Debug::INIT] << check_text << " no" << std::endl;
-       return std::make_pair(FileName(), FileName());
-}
-
-
-// Specification of document_dir_ may be reset by LyXRC,
-// but the default is fixed for a given OS.
-FileName const get_document_dir(FileName const & home_dir)
-{
-#if defined (USE_WINDOWS_PACKAGING)
-       (void)home_dir; // Silence warning about unused variable.
-       os::GetFolderPath win32_folder_path;
-       return FileName(win32_folder_path(os::GetFolderPath::PERSONAL));
-#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.
-FileName const get_locale_dir(FileName const & system_support_dir)
-{
-       // 1. Use the "LYX_LOCALEDIR" environment variable.
-       FileName const path_env = extract_env_var_dir("LYX_LOCALEDIR");
-       if (!path_env.empty() && check_env_var_dir(path_env, "LYX_LOCALEDIR"))
-               return path_env;
-
-       // 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())));
-
-       if (fs::exists(path.toFilesystemEncoding()) &&
-           fs::is_directory(path.toFilesystemEncoding()))
-               return path;
-
-       // 3. Fall back to the hard-coded LOCALEDIR.
-       path = hardcoded_localedir();
-       if (fs::exists(path.toFilesystemEncoding()) &&
-           fs::is_directory(path.toFilesystemEncoding()))
-               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);
-}
-
-
-// Does the grunt work for abs_path_from_binary_name()
-FileName const get_binary_path(string const & exe)
-{
-#if defined (USE_WINDOWS_PACKAGING)
-       // 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";
-#else
-       string const exe_path = os::internal_path(exe);
-#endif
-       if (os::is_absolute_path(exe_path))
-               return FileName(exe_path);
-
-       // Two possibilities present themselves.
-       // 1. The binary is relative to the CWD.
-       FileName const abs_exe_path = makeAbsPath(exe_path);
-       if (fs::exists(abs_exe_path.toFilesystemEncoding()))
-               return abs_exe_path;
-
-       // 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);
-       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();
-       for (; it != end; ++it) {
-               // This will do nothing if *it is already absolute.
-               string const exe_dir = makeAbsPath(*it).absFilename();
-
-               FileName const exe_path(addName(exe_dir, exe_name));
-               if (fs::exists(exe_path.toFilesystemEncoding()))
-                       return exe_path;
-       }
-
-       // Didn't find anything.
-       return FileName();
-}
-
-
-// Extracts the absolute path to the binary name received as argv[0].
-FileName const abs_path_from_binary_name(string const & exe)
-{
-       FileName const abs_binary = get_binary_path(exe);
-       if (abs_binary.empty()) {
-               // FIXME UNICODE
-               throw ExceptionMessage(ErrorException,
-                       _("LyX binary not found"),
-                       bformat(_("Unable to determine the path to the LyX binary from the command line %1$s"),
-                               from_utf8(exe)));
-       }
-       return abs_binary;
-}
-
-
-// A plethora of directories is searched to ascertain the system
-// lyxdir which is defined as the first directory to contain
-// "chkconfig.ltx".
-FileName const
-get_system_support_dir(FileName const & abs_binary,
-                 string const & command_line_system_support_dir)
-{
-       string const chkconfig_ltx = "chkconfig.ltx";
-
-       // searched_dirs is used for diagnostic purposes only in the case
-       // that "chkconfig.ltx" is not found.
-       std::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"))
-                       return path;
-       }
-
-       // 2. Use the "LYX_DIR_15x" environment variable.
-       path = extract_env_var_dir("LYX_DIR_15x");
-       if (!path.empty()) {
-               searched_dirs.push_back(path);
-               if (check_env_var_dir(path, chkconfig_ltx, "LYX_DIR_15x"))
-                       return path;
-       }
-
-       // 3. Search relative to the lyx binary.
-       // We're looking for "chkconfig.ltx" in a directory
-       //   OnlyPath(abs_binary) / <relative dir> / PACKAGE /
-       // PACKAGE is hardcoded in config.h. Eg "lyx" or "lyx-1.3.6cvs".
-       // <relative dir> is OS-dependent; on Unix, it will be "../share/".
-       string const relative_lyxdir = relative_system_support_dir();
-
-       // One subtlety to be aware of. 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;
-       while (true) {
-               // Try and find "chkconfig.ltx".
-               string const binary_dir = onlyPath(binary.absFilename());
-
-               FileName const lyxdir(
-                       normalizePath(addPath(binary_dir, relative_lyxdir)));
-               searched_dirs.push_back(lyxdir);
-
-               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()))
-                       break;
-
-               FileName link;
-               if (readLink(binary, link)) {
-                       binary = link;
-               } else {
-                       // Unable to resolve the link.
-                       break;
-               }
-       }
-
-       // 4. Repeat the exercise on the directory itself.
-       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()))
-                       break;
-
-               FileName link;
-               if (readLink(binary_dir, link)) {
-                       binary_dir = link;
-               } else {
-                       // Unable to resolve the link.
-                       break;
-               }
-
-               // Try and find "chkconfig.ltx".
-               FileName const lyxdir(
-                       normalizePath(addPath(binary_dir.absFilename(), relative_lyxdir)));
-               searched_dirs.push_back(lyxdir);
-
-               if (!fileSearch(lyxdir.absFilename(), chkconfig_ltx).empty()) {
-                       // Success! "chkconfig.ltx" has been found.
-                       return lyxdir;
-               }
-       }
-
-       // 5. In desparation, try the hard-coded system support dir.
-       path = hardcoded_system_support_dir();
-       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;
-       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();
-       }
-
-       // 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();
-}
-
-
-// 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 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);
-
-       // 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);
-
-       // 3. Use the OS-dependent default_user_support_dir
-       explicit_userdir = false;
-       return std::make_pair(default_user_support_dir, explicit_userdir);
-}
-
-
-// $HOME/.lyx on POSIX but on Win32 it will be something like
-// "C:/Documents and Settings/USERNAME/Application Data/LyX"
-FileName const get_default_user_support_dir(FileName const & home_dir)
-{
-#if defined (USE_WINDOWS_PACKAGING)
-       (void)home_dir; // Silence warning about unused variable.
-
-       os::GetFolderPath win32_folder_path;
-       return FileName(addPath(win32_folder_path(os::GetFolderPath::APPDATA), PACKAGE));
-
-#elif defined (USE_MACOSX_PACKAGING)
-       (void)home_dir; // Silence warning about unused variable.
-
-       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();
-
-       return FileName(addPath(reinterpret_cast<char const *>(store), PACKAGE));
-
-#else // USE_POSIX_PACKAGING
-       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.
-bool check_command_line_dir(string const & dir,
-                           string const & file,
-                           string const & command_line_switch)
-{
-       FileName const abs_path = fileSearch(dir, file);
-       if (abs_path.empty()) {
-               // FIXME UNICODE
-               throw ExceptionMessage(WarningException, _("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)));
-       }
-
-       return !abs_path.empty();
-}
-
-
-// The environment variable @c env_var expands to a (single) file path.
-FileName const extract_env_var_dir(string const & env_var)
-{
-       string const dir = fix_dir_name(getEnv(env_var));
-       return dir.empty() ? FileName() : makeAbsPath(dir);
-}
-
-
-// Check that directory @c dir contains @c file.
-// Else emit a warning about an invalid @c env_var.
-bool check_env_var_dir(FileName const & dir,
-                      string const & file,
-                      string const & env_var)
-{
-       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(file)));
-       }
-
-       return !abs_path.empty();
-}
-
-
-// Check that directory @c dir is indeed a directory.
-// Else emit a warning about an invalid @c env_var.
-bool check_env_var_dir(FileName const & dir,
-                      string const & env_var)
-{
-       string const encoded(dir.toFilesystemEncoding());
-       bool const success = (fs::exists(encoded) && fs::is_directory(encoded));
-
-       if (!success) {
-               // Put this string on a single line so that the gettext
-               // search mechanism in po/Makefile.in.in will register
-               // Package.cpp.in as a file containing strings that need
-               // translation.
-               // FIXME UNICODE
-               docstring const fmt =
-                       _("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())));
-       }
-
-       return success;
-}
-
-
-// The locale directory relative to the LyX system directory.
-string const relative_locale_dir()
-{
-#if defined (USE_WINDOWS_PACKAGING) || defined (USE_MACOSX_PACKAGING)
-       return "locale/";
-#else
-       return "../locale/";
-#endif
-}
-
-
-// The system lyxdir is relative to the directory containing the LyX binary.
-string const relative_system_support_dir()
-{
-       string result;
-
-#if defined (USE_WINDOWS_PACKAGING) || defined (USE_MACOSX_PACKAGING)
-       result = "../Resources/";
-#else // Posix-like.
-       result = addPath("../share/", PACKAGE);
-#endif
-
-       return result;
-}
-
-} // namespace anon
-
-} // namespace support
-} // namespace lyx