]> git.lyx.org Git - lyx.git/blobdiff - src/LyX.cpp
Avoid compiler warning about overloaded virtual function.
[lyx.git] / src / LyX.cpp
index 98c57059176896c81a9d0d30e55b9d8f07d585e2..b57245bb1e1fc2226964082db05838a89fa630fe 100644 (file)
@@ -50,6 +50,7 @@
 #include "frontends/alert.h"
 #include "frontends/Application.h"
 
+#include "support/ConsoleApplication.h"
 #include "support/lassert.h"
 #include "support/debug.h"
 #include "support/environment.h"
@@ -60,8 +61,6 @@
 #include "support/Messages.h"
 #include "support/os.h"
 #include "support/Package.h"
-#include "support/PathChanger.h"
-#include "support/Systemcall.h"
 
 #include "support/bind.h"
 #include <boost/scoped_ptr.hpp>
 using namespace std;
 using namespace lyx::support;
 
+#if defined (USE_MACOSX_PACKAGING)
+#include <crt_externs.h>
+#endif
+
 namespace lyx {
 
 namespace Alert = frontend::Alert;
@@ -123,18 +126,6 @@ void showFileError(string const & error)
                           "Please check your installation."), from_utf8(error)));
 }
 
-
-void reconfigureUserLyXDir()
-{
-       string const configure_command = package().configure_command();
-
-       lyxerr << to_utf8(_("LyX: reconfiguring user directory")) << endl;
-       PathChanger p(package().user_support());
-       Systemcall one;
-       one.startscript(Systemcall::Wait, configure_command);
-       lyxerr << "LyX: " << to_utf8(_("Done!")) << endl;
-}
-
 } // namespace anon
 
 /// The main application class private implementation.
@@ -184,8 +175,6 @@ struct LyX::Impl {
        ///
        Movers system_movers_;
 
-       /// has this user started lyx for the first time?
-       bool first_start;
        /// the parsed command line batch command if any
        vector<string> batch_commands;
 
@@ -205,6 +194,27 @@ struct LyX::Impl {
 };
 
 
+/// The main application class for console mode
+class LyXConsoleApp : public ConsoleApplication
+{
+public:
+       LyXConsoleApp(LyX * lyx, int & argc, char * argv[])
+               : ConsoleApplication(lyx_package, argc, argv), lyx_(lyx),
+                 argc_(argc), argv_(argv)
+       {
+       }
+       void doExec()
+       {
+               int const exit_status = lyx_->execWithoutGui(argc_, argv_);
+               exit(exit_status);
+       }
+private:
+       LyX * lyx_;
+       int & argc_;
+       char ** argv_;
+};
+
+
 ///
 frontend::Application * theApp()
 {
@@ -297,39 +307,13 @@ int LyX::exec(int & argc, char * argv[])
        setLocale();
 
        if (!use_gui) {
-               // FIXME: create a ConsoleApplication
-               int exit_status = init(argc, argv);
-               if (exit_status) {
-                       prepareExit();
-                       return exit_status;
-               }
+               LyXConsoleApp app(this, argc, argv);
 
-               // this is correct, since return values are inverted.
-               exit_status = !loadFiles();
-
-               if (pimpl_->batch_commands.empty() || pimpl_->buffer_list_.empty()) {
-                       prepareExit();
-                       return exit_status;
-               }
+               // Reestablish our defaults, as Qt overwrites them
+               // after creating app
+               setLocale();//???
 
-               BufferList::iterator begin = pimpl_->buffer_list_.begin();
-
-               bool final_success = false;
-               for (BufferList::iterator I = begin; I != pimpl_->buffer_list_.end(); ++I) {
-                       Buffer * buf = *I;
-                       if (buf != buf->masterBuffer())
-                               continue;
-                       vector<string>::const_iterator bcit  = pimpl_->batch_commands.begin();
-                       vector<string>::const_iterator bcend = pimpl_->batch_commands.end();
-                       DispatchResult dr;
-                       for (; bcit != bcend; ++bcit) {
-                               LYXERR(Debug::ACTION, "Buffer::dispatch: cmd: " << *bcit);
-                               buf->dispatch(*bcit, dr);
-                               final_success |= !dr.error();
-                       }
-               }
-               prepareExit();
-               return !final_success;
+               return app.exec();
        }
 
        // Let the frontend parse and remove all arguments that it knows
@@ -357,7 +341,7 @@ int LyX::exec(int & argc, char * argv[])
 
        // FIXME
        /* Create a CoreApplication class that will provide the main event loop
-       * and the socket callback registering. With Qt4, only QtCore
+       * and the socket callback registering. With Qt, only QtCore
        * library would be needed.
        * When this is done, a server_mode could be created and the following two
        * line would be moved out from here.
@@ -482,6 +466,43 @@ int LyX::init(int & argc, char * argv[])
 }
 
 
+int LyX::execWithoutGui(int & argc, char * argv[])
+{
+       int exit_status = init(argc, argv);
+       if (exit_status) {
+               prepareExit();
+               return exit_status;
+       }
+
+       // this is correct, since return values are inverted.
+       exit_status = !loadFiles();
+
+       if (pimpl_->batch_commands.empty() || pimpl_->buffer_list_.empty()) {
+               prepareExit();
+               return exit_status;
+       }
+
+       BufferList::iterator begin = pimpl_->buffer_list_.begin();
+
+       bool final_success = false;
+       for (BufferList::iterator I = begin; I != pimpl_->buffer_list_.end(); ++I) {
+               Buffer * buf = *I;
+               if (buf != buf->masterBuffer())
+                       continue;
+               vector<string>::const_iterator bcit  = pimpl_->batch_commands.begin();
+               vector<string>::const_iterator bcend = pimpl_->batch_commands.end();
+               DispatchResult dr;
+               for (; bcit != bcend; ++bcit) {
+                       LYXERR(Debug::ACTION, "Buffer::dispatch: cmd: " << *bcit);
+                       buf->dispatch(*bcit, dr);
+                       final_success |= !dr.error();
+               }
+       }
+       prepareExit();
+       return !final_success;
+}
+
+
 bool LyX::loadFiles()
 {
        LATTEST(!use_gui);
@@ -706,6 +727,57 @@ void LyX::printError(ErrorItem const & ei)
        cerr << to_utf8(tmp) << endl;
 }
 
+#if defined (USE_MACOSX_PACKAGING)
+namespace {
+       // Unexposed--extract an environment variable name from its NAME=VALUE
+       // representation
+       std::string varname(const char* line)
+       {
+               size_t nameLen = strcspn(line, "=");
+               if (nameLen == strlen(line)) {
+                       return std::string();
+               } else {
+                       return std::string(line, nameLen);
+               }
+       }
+}
+
+void cleanDuplicateEnvVars()
+{
+       std::set<std::string> seen;
+       std::set<std::string> dupes;
+
+       // Create a list of the environment variables that appear more than once
+       for (char **read = *_NSGetEnviron(); *read; read++) {
+               std::string name = varname(*read);
+               if (name.size() == 0) {
+                       continue;
+               }
+               if (seen.find(name) != seen.end()) {
+                       dupes.insert(name);
+               } else {
+                       seen.insert(name);
+               }
+       }
+
+       // Loop over the list of duplicated variables
+       std::set<std::string>::iterator dupe = dupes.begin();
+       std::set<std::string>::iterator const dend = dupes.end();
+       for (; dupe != dend; ++dupe) {
+               const char *name = (*dupe).c_str();
+               char *val = getenv(name);
+               if (val != NULL) {
+                       LYXERR(Debug::INIT, "Duplicate environment variable: " << name);
+                       // unsetenv removes *all* instances of the variable from the environment
+                       unsetenv(name);
+
+                       // replace with the value from getenv (in practice appears to be the
+                       // first value in the list)
+                       setenv(name, val, 0);
+               }
+       }
+}
+#endif
 
 bool LyX::init()
 {
@@ -718,6 +790,10 @@ bool LyX::init()
        signal(SIGTERM, error_handler);
        // SIGPIPE can be safely ignored.
 
+#if defined (USE_MACOSX_PACKAGING)
+       cleanDuplicateEnvVars();
+#endif
+
        lyxrc.tempdir_path = package().temp_dir().absFileName();
        lyxrc.document_path = package().document_dir().absFileName();
 
@@ -768,11 +844,11 @@ bool LyX::init()
 
        // Check that user LyX directory is ok.
        {
-               string const lock_file = package().user_support().absFileName() + ".lyx_configure_lock";
+               string const lock_file = package().getConfigureLockName();
                int fd = fileLock(lock_file.c_str());
 
                if (queryUserLyXDir(package().explicit_user_support())) {
-                       reconfigureUserLyXDir();
+                       package().reconfigureUserLyXDir("");
                }
                fileUnlock(fd, lock_file.c_str());
        }
@@ -899,27 +975,6 @@ void emergencyCleanup()
 }
 
 
-// return true if file does not exist or is older than configure.py.
-static bool needsUpdate(string const & file)
-{
-       // We cannot initialize configure_script directly because the package
-       // is not initialized yet when static objects are constructed.
-       static FileName configure_script;
-       static bool firstrun = true;
-       if (firstrun) {
-               configure_script =
-                       FileName(addName(package().system_support().absFileName(),
-                               "configure.py"));
-               firstrun = false;
-       }
-
-       FileName absfile =
-               FileName(addName(package().user_support().absFileName(), file));
-       return !absfile.exists()
-               || configure_script.lastModified() > absfile.lastModified();
-}
-
-
 bool LyX::queryUserLyXDir(bool explicit_userdir)
 {
        // Does user directory exist?
@@ -927,10 +982,10 @@ bool LyX::queryUserLyXDir(bool explicit_userdir)
        if (sup.exists() && sup.isDirectory()) {
                first_start = false;
 
-               return needsUpdate("lyxrc.defaults")
-                       || needsUpdate("lyxmodules.lst")
-                       || needsUpdate("textclass.lst")
-                       || needsUpdate("packages.lst");
+               return configFileNeedsUpdate("lyxrc.defaults")
+                       || configFileNeedsUpdate("lyxmodules.lst")
+                       || configFileNeedsUpdate("textclass.lst")
+                       || configFileNeedsUpdate("packages.lst");
        }
 
        first_start = !explicit_userdir;
@@ -1089,9 +1144,9 @@ int parse_version(string const &, string const &, string &)
 {
        cout << "LyX " << lyx_version
               << " (" << lyx_release_date << ")" << endl;
-       cout << to_utf8(bformat(_("Built on %1$s[[date]], %2$s[[time]]"),
-               from_ascii(__DATE__), from_ascii(__TIME__))) << endl;
-
+       if (string(lyx_git_commit_hash) != "none")
+               cout << to_utf8(_("  Git commit hash "))
+                    << string(lyx_git_commit_hash).substr(0,8) << endl;
        cout << lyx_version_info << endl;
        exit(0);
        return 0;
@@ -1244,7 +1299,7 @@ void LyX::easyParse(int & argc, char * argv[])
        cmdmap["-userdir"] = parse_userdir;
        cmdmap["-x"] = parse_execute;
        cmdmap["--execute"] = parse_execute;
-       cmdmap["-e"] = parse_export;
+       cmdmap["-e"] = parse_export;
        cmdmap["--export"] = parse_export;
        cmdmap["-E"] = parse_export_to;
        cmdmap["--export-to"] = parse_export_to;