diff --git a/config/ChangeLog b/config/ChangeLog index 20df4fe7af..42016f1fc3 100644 --- a/config/ChangeLog +++ b/config/ChangeLog @@ -1,3 +1,10 @@ +2005-01-06 Jean-Marc Lasgouttes + + * configure.ac: + * configure.in: use LYX_USE_PACKAGING + + * lyxinclude.m4 (LYX_USE_PACKAGING): new macro. + 2005-01-04 Angus Leeming * configure.ac, configure.in (AC_CHECK_FUNCS): test for the diff --git a/config/configure.ac b/config/configure.ac index 97c551b697..1824409324 100644 --- a/config/configure.ac +++ b/config/configure.ac @@ -22,10 +22,6 @@ AM_INIT_AUTOMAKE($lyxname, $VERSION) # that are complete enough to be useful). This is needed by GNU gettext ALL_LINGUAS="da de es eu fi fr it nl nn no pl ro ru sk sl" -# fix the value of the prefixes. -test "x$prefix" = xNONE && prefix=$ac_default_prefix -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - ### Set the execute permissions of the various scripts correctly for file in config/install-sh config/mkinstalldirs lib/configure ; do chmod 755 ${srcdir}/${file} @@ -208,6 +204,12 @@ dnl ;; LYX_ERROR(Unknown frontend $lyx_use_frontend);; esac +### Check how the files should be packaged +LYX_USE_PACKAGING +# fix the value of the prefixes. +test "x$prefix" = xNONE && prefix=$default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ### Setup GNU gettext dnl GNU gettext is written in C AC_LANG_PUSH(C) @@ -281,8 +283,9 @@ VERSION_INFO="Configuration\n\ Linker flags: ${LDFLAGS}\n\ Frontend: ${lyx_use_frontend}\n\ ${FRONTEND_INFO}\ - LyX binary dir: ${real_bindir}\n\ - LyX files dir: ${real_datadir}\n" + Packaging: ${lyx_use_packaging}\n\ + LyX binary dir: ${real_bindir}\n\ + LyX files dir: ${real_datadir}\n" AC_SUBST(VERSION_INFO) diff --git a/config/configure.in b/config/configure.in index 5a3c9e9f7e..dfeec24795 100644 --- a/config/configure.in +++ b/config/configure.in @@ -22,10 +22,6 @@ AM_INIT_AUTOMAKE($lyxname, $VERSION) # that are complete enough to be useful). This is needed by GNU gettext ALL_LINGUAS="da de es eu fi fr it nl nn no pl ro ru sk sl" -# fix the value of the prefixes. -test "x$prefix" = xNONE && prefix=$ac_default_prefix -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - ### Set the execute permissions of the various scripts correctly for file in config/install-sh config/mkinstalldirs lib/configure ; do chmod 755 ${srcdir}/${file} @@ -215,6 +211,12 @@ dnl FRONTEND_LIBS="@XPM_LIB@ @XFORMS_LIB@ ${GNOME_FRONTEND_LIBS}";; LYX_ERROR(Unknown frontend $lyx_use_frontend);; esac +### Check how the files should be packaged +LYX_USE_PACKAGING +# fix the value of the prefixes. +test "x$prefix" = xNONE && prefix=$default_prefix +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + ### Setup GNU gettext dnl GNU gettext is written in C AC_LANG_C @@ -285,9 +287,9 @@ VERSION_INFO="Configuration\n\ Linker flags: ${LDFLAGS}\n\ Frontend: ${lyx_use_frontend}\n\ ${FRONTEND_INFO}\ - LyX binary dir: ${real_bindir}\n\ - LyX files dir: ${real_datadir}\n" - + Packaging: ${lyx_use_packaging}\n\ + LyX binary dir: ${real_bindir}\n\ + LyX files dir: ${real_datadir}\n" AC_SUBST(VERSION_INFO) AC_SUBST(RPM_FRONTEND) diff --git a/config/lyxinclude.m4 b/config/lyxinclude.m4 index 8de4eebd87..4fe50d74b6 100644 --- a/config/lyxinclude.m4 +++ b/config/lyxinclude.m4 @@ -657,6 +657,37 @@ AC_SUBST(FRONTEND_INCLUDES) AC_SUBST(FRONTEND_LIBS) ]) +## Check what kind of packaging should be used at install time. +## The default is autodetected. +AC_DEFUN([LYX_USE_PACKAGING], +[AC_MSG_CHECKING([what packaging should be used]) +AC_ARG_WITH(packaging, + [ --with-packaging=THIS Use THIS packaging for installation: + Possible values: posix, windows, macosx], + [lyx_use_packaging="$withval"], [ + case $host in + *-apple-darwin*) lyx_use_packaging=macosx ;; + *-pc-mingw32*) lyx_use_packaging=windows;; + *) lyx_use_packaging=posix;; + esac]) +AC_MSG_RESULT($lyx_use_packaging) +case $lyx_use_packaging in + macosx) AC_DEFINE(USE_MACOSX_PACKAGING, 1, [Define to 1 if LyX should use a MacOS X application bundle file layout]) + default_prefix="/Applications/LyX.app" + bindir='${prefix}/Contents/MacOS' + datadir='${prefix}/Contents/Resources' + mandir='${prefix}/Contents/Resources/man' ;; + windows) AC_DEFINE(USE_WINDOWS_PACKAGING, 1, [Define to 1 if LyX should use a Windows-style file layout]) + default_prefix="'C:Program Files/LyX'" + bindir='${prefix}/bin' + datadir='${prefix}/Resources' + mandir='${prefix}/Resources/man' ;; + posix) AC_DEFINE(USE_POSIX_PACKAGING, 1, [Define to 1 if LyX should use a POSIX-style file layout]) + default_prefix=$ac_default_prefix ;; + *) LYX_ERROR([Unknown packaging type $lyx_use_packaging]) ;; +esac +]) + ## ------------------------------------------------------------------------ diff --git a/po/POTFILES.in b/po/POTFILES.in index a3c948f647..1227a8cfea 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -175,6 +175,7 @@ src/mathed/math_parboxinset.C src/mathed/ref_inset.C src/paragraph.C src/support/filetools.C +src/support/package.C src/tabular.C src/text.C src/text2.C diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 4ba2eacd4f..0a62d2a2dc 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -31,7 +31,6 @@ #include "intl.h" // added for Dispatch functions #include "lyx_cb.h" -#include "lyx_main.h" #include "FloatList.h" #include "gettext.h" #include "ParagraphParameters.h" @@ -54,9 +53,10 @@ #include "graphics/Previews.h" +#include "support/filetools.h" #include "support/LAssert.h" #include "support/lstrings.h" -#include "support/filetools.h" +#include "support/package.h" #include #include @@ -855,13 +855,14 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen) initpath = trypath; } + string const & system_support = lyx::package().system_support(); FileDialog fileDlg(bv_->owner(), _("Select LyX document to insert"), LFUN_FILE_INSERT, make_pair(string(_("Documents|#o#O")), string(lyxrc.document_path)), make_pair(string(_("Examples|#E#e")), - string(AddPath(system_lyxdir, "examples")))); + string(AddPath(system_support, "examples")))); FileDialog::Result result = fileDlg.open(initpath, diff --git a/src/ChangeLog b/src/ChangeLog index 0d86860062..70407c6ce4 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,25 @@ +2005-01-10 Angus Leeming + + * Makefile.am: remove the lyx_main.C special casing. + + * BufferView_pimpl.C: + * bufferlist.C: + * lyx_cb.C: + * lyxfunc.C: use support/package.h to provide the paths to the + various directories used by LyX. + + * lyx_main.C: remove all code to determine the paths + to the various directories used by LyX. Use support/package.h + instead. + + * lyx_main.h: remove the declarations of the user_lyxdir, + system_lyxdir and system_tempdir global variables. + + * lyxserver.C: no need to #include lyx_main.h. + + * main.C: don't use GetEnvPath to extract the LYX_LOCALEDIR + environment variable. + 2005-01-05 Angus Leeming * BufferView.C: @@ -61,8 +83,8 @@ * *.[Ch]: remove all traces of #pragma interface/implementation 2004-11-15 Jean-Marc Lasgouttes - - * text.C (cursorLeftOneWord): + + * text.C (cursorLeftOneWord): (getWord): simplify by using Paragraph::isWord * paragraph.C (isWord): invoke Inset::isLetter on insets @@ -92,7 +114,7 @@ * bufferlist.C (previous, next): new methods - * commandtags.h: + * commandtags.h: * LyXAction.C (init): add LFUN_NEXTBUFFER and LFUN_PREVIOUSBUFFER 2004-10-22 Jürgen Spitzmüller @@ -108,7 +130,7 @@ * paragraph.C (TeXOnePar): Make sure font setting is the first thing that gets output (and the last at the end). Should fix bug - 1404. + 1404. 2004-07-15 Georg Baum @@ -128,10 +150,10 @@ 2004-04-29 Jean-Marc Lasgouttes - * text2.C (setCounter): - * lyxfunc.C (dispatch): - * exporter.C (Export): - * converter.C (runLaTeX): + * text2.C (setCounter): + * lyxfunc.C (dispatch): + * exporter.C (Export): + * converter.C (runLaTeX): * buffer.C (redraw, runChktex): fix #warning directives * BoostFormat.h: fix compilation with gcc 3.4 @@ -166,7 +188,7 @@ * BufferView_pimpl.C (dispatch): use parentFilename_ instead of masterFilename_ - * buffer.C (getLabelList): + * buffer.C (getLabelList): (getBibkeyList): use getMasterBuffer() (getMasterBuffer): new method. Returns the main document in the case where one is using included documents. @@ -302,7 +324,7 @@ * LaTeX.C (run): Fix a bug where the DVI file was not updated due to an old format .dep file. - + 2003-02-17 John Levon * SpellBase.h: @@ -329,15 +351,15 @@ * paragraph.C (asString): remove two unused variables - * lyxtextclass.C (readTitleType): - (Read): + * lyxtextclass.C (readTitleType): + (Read): (LyXTextClass): handle new members titletype_ and titlename_ * buffer.C (latexParagraphs): honor LyXTextClass::titletype 2003-02-07 Jean-Marc Lasgouttes - * text.C (getLengthMarkerHeight): + * text.C (getLengthMarkerHeight): (drawLengthMarker): make the `symbolic' lengths (small/med/big) visible on screen too. diff --git a/src/Makefile.am b/src/Makefile.am index f8a51110f0..a8514725a9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -219,13 +219,6 @@ lyx_SOURCES = \ vspace.C \ vspace.h -lyx_main.$(OBJEXT): lyx_main.C lyx_main.h config.h version.h \ - lyxrc.h support/path.h support/filetools.h \ - bufferlist.h debug.h support/FileInfo.h lastfiles.h intl.h \ - lyxserver.h layout.h gettext.h kbmap.h commandtags.h language.h - $(CXXCOMPILE) -DLYX_DIR=\"$(pkgdatadir)\" \ - -DTOP_SRCDIR=\"$(top_srcdir)\" -c $(top_srcdir)/src/lyx_main.C - main.$(OBJEXT): main.C config.h lyx_main.h gettext.h LString.h \ support/filetools.h support/os.h $(CXXCOMPILE) -DLOCALEDIR=\"$(localedir)\" -c $(top_srcdir)/src/main.C diff --git a/src/bufferlist.C b/src/bufferlist.C index ab2b20df95..78726db0ce 100644 --- a/src/bufferlist.C +++ b/src/bufferlist.C @@ -36,7 +36,7 @@ #include "support/lyxmanip.h" #include "support/lyxfunctional.h" #include "support/LAssert.h" -#include "support/os.h" +#include "support/package.h" #include #include "BoostFormat.h" @@ -361,7 +361,7 @@ void BufferList::emergencyWrite(Buffer * buf) } // 2) In HOME directory. - string s = AddName(os::homepath(), buf->fileName()); + string s = AddName(lyx::package().home_dir(), buf->fileName()); s += ".emergency"; lyxerr << ' ' << s << endl; if (buf->writeFile(s)) { diff --git a/src/frontends/controllers/ChangeLog b/src/frontends/controllers/ChangeLog index 874cf4b078..c53b9e9a94 100644 --- a/src/frontends/controllers/ChangeLog +++ b/src/frontends/controllers/ChangeLog @@ -1,3 +1,14 @@ +2005-01-10 Angus Leeming + + * ControlAboutlyx.C: + * ControlDocument.C: + * ControlGraphics.C: + * ControlPrefs.C: + * tex_helpers.C: use support/package.h to provide the paths to the + various directories used by LyX. + + * ControlTexinfo.C: remove reference to user_lyxdir. + 2005-01-05 Angus Leeming * ControlGraphics.C: add "using lyx::FileInfo;" directive. diff --git a/src/frontends/controllers/ControlAboutlyx.C b/src/frontends/controllers/ControlAboutlyx.C index 4f15481f10..e1648af5de 100644 --- a/src/frontends/controllers/ControlAboutlyx.C +++ b/src/frontends/controllers/ControlAboutlyx.C @@ -18,15 +18,12 @@ #include "support/LOstream.h" #include "support/filetools.h" // FileSearch +#include "support/package.h" #include using std::ostream; -// needed for the browser -extern string system_lyxdir; -extern string user_lyxdir; - ControlAboutlyx::ControlAboutlyx(LyXView & lv, Dialogs & d) : ControlDialogBI(lv, d) @@ -35,7 +32,8 @@ ControlAboutlyx::ControlAboutlyx(LyXView & lv, Dialogs & d) void ControlAboutlyx::getCredits(ostream & ss) const { - string const name = FileSearch(system_lyxdir, "CREDITS"); + string const & system_support = lyx::package().system_support(); + string const name = FileSearch(system_support, "CREDITS"); bool found(!name.empty()); @@ -75,6 +73,7 @@ string const ControlAboutlyx::getDisclaimer() const string const ControlAboutlyx::getVersion() const { ostringstream ss; + lyx::Package const & package = lyx::package(); ss << _("LyX Version ") << lyx_version @@ -82,10 +81,10 @@ string const ControlAboutlyx::getVersion() const << lyx_release_date << "\n" << _("Library directory: ") - << MakeDisplayPath(system_lyxdir) + << MakeDisplayPath(package.system_support()) << "\n" << _("User directory: ") - << MakeDisplayPath(user_lyxdir); + << MakeDisplayPath(package.user_support()); return STRCONV(ss.str()); } diff --git a/src/frontends/controllers/ControlDocument.C b/src/frontends/controllers/ControlDocument.C index 3f48a95198..76d4817c55 100644 --- a/src/frontends/controllers/ControlDocument.C +++ b/src/frontends/controllers/ControlDocument.C @@ -20,7 +20,6 @@ #include "buffer.h" #include "language.h" -#include "lyx_main.h" #include "lyxtextclass.h" #include "lyxtextclasslist.h" #include "CutAndPaste.h" @@ -28,8 +27,9 @@ #include "frontends/LyXView.h" #include "frontends/Alert.h" -#include "support/lstrings.h" #include "support/filetools.h" +#include "support/lstrings.h" +#include "support/package.h" #include "BoostFormat.h" @@ -164,7 +164,8 @@ void ControlDocument::saveAsDefault() lv_.buffer()->params.preamble = bp_->preamble; - string const fname = AddName(AddPath(user_lyxdir, "templates/"), + string const & user_support = lyx::package().user_support(); + string const fname = AddName(AddPath(user_support, "templates/"), "defaults.lyx"); Buffer defaults(fname); defaults.params = params(); diff --git a/src/frontends/controllers/ControlGraphics.C b/src/frontends/controllers/ControlGraphics.C index 7c7c20b113..e9080b2cd4 100644 --- a/src/frontends/controllers/ControlGraphics.C +++ b/src/frontends/controllers/ControlGraphics.C @@ -28,9 +28,10 @@ #include "insets/insetgraphics.h" #include "insets/insetgraphicsParams.h" -#include "support/lstrings.h" -#include "support/filetools.h" #include "support/FileInfo.h" +#include "support/filetools.h" +#include "support/lstrings.h" +#include "support/package.h" using lyx::FileInfo; @@ -38,10 +39,6 @@ using std::pair; using std::make_pair; using std::vector; -// We need these in the file browser. -extern string system_lyxdir; -extern string user_lyxdir; - ControlGraphics::ControlGraphics(LyXView & lv, Dialogs & d) : ControlInset(lv, d) @@ -82,11 +79,12 @@ string const ControlGraphics::Browse(string const & in_name) string const title = _("Select graphics file"); // Does user clipart directory exist? - string clipdir = AddName (user_lyxdir, "clipart"); + lyx::Package const & package = lyx::package(); + string clipdir = AddName (package.user_support(), "clipart"); FileInfo fileInfo(clipdir); if (!(fileInfo.isOK() && fileInfo.isDir())) // No - bail out to system clipart directory - clipdir = AddName (system_lyxdir, "clipart"); + clipdir = AddName (package.system_support(), "clipart"); pair dir1(_("Clipart|#C#c"), clipdir); pair dir2(_("Documents|#o#O"), string(lyxrc.document_path)); // Show the file browser dialog diff --git a/src/frontends/controllers/ControlPrefs.C b/src/frontends/controllers/ControlPrefs.C index ab25e4b574..23300db9e4 100644 --- a/src/frontends/controllers/ControlPrefs.C +++ b/src/frontends/controllers/ControlPrefs.C @@ -14,21 +14,22 @@ #include "ControlPrefs.h" #include "ViewBase.h" - -#include "frontends/LyXView.h" #include "helper_funcs.h" -#include "gettext.h" -#include "support/filetools.h" -#include "frontends/Dialogs.h" + #include "converter.h" #include "debug.h" +#include "gettext.h" -extern string system_lyxdir; -extern string user_lyxdir; +#include "frontends/Dialogs.h" +#include "frontends/LyXView.h" + +#include "support/filetools.h" +#include "support/package.h" using std::endl; using std::pair; + ControlPrefs::ControlPrefs(LyXView & lv, Dialogs & d) : ControlDialogBI(lv, d) {} @@ -54,12 +55,13 @@ void ControlPrefs::apply() string const ControlPrefs::browsebind(string const & file) { - string dir = AddName(system_lyxdir, "bind"); + lyx::Package const & package = lyx::package(); + string dir = AddName(package.system_support(), "bind"); // FIXME: stupid name string name = _("System Bind|#S#s"); pair dir1(name, dir); - dir = AddName(user_lyxdir, "bind"); + dir = AddName(package.user_support(), "bind"); // FIXME: stupid name name = _("User Bind|#U#u"); pair dir2(name, dir); @@ -70,12 +72,13 @@ string const ControlPrefs::browsebind(string const & file) string const ControlPrefs::browseUI(string const & file) { - string dir = AddName(system_lyxdir, "ui"); + lyx::Package const & package = lyx::package(); + string dir = AddName(package.system_support(), "ui"); // FIXME: stupid name string name = _("Sys UI|#S#s"); pair dir1(name, dir); - dir = AddName(user_lyxdir, "ui"); + dir = AddName(package.user_support(), "ui"); // FIXME: stupid name name = _("User UI|#U#u"); pair dir2(name, dir); @@ -86,7 +89,7 @@ string const ControlPrefs::browseUI(string const & file) string const ControlPrefs::browsekbmap(string const & file) { - string const dir = AddName(system_lyxdir, "kbd"); + string const dir = AddName(lyx::package().system_support(), "kbd"); string const name = _("Key maps|#K#k"); pair dir1(name, dir); diff --git a/src/frontends/controllers/ControlTexinfo.C b/src/frontends/controllers/ControlTexinfo.C index cc24612a7e..684781bf79 100644 --- a/src/frontends/controllers/ControlTexinfo.C +++ b/src/frontends/controllers/ControlTexinfo.C @@ -22,7 +22,6 @@ #include "support/path.h" #include "support/lstrings.h" -extern string user_lyxdir; // home of *Files.lst namespace { diff --git a/src/frontends/controllers/tex_helpers.C b/src/frontends/controllers/tex_helpers.C index c32776568f..06df6dc52b 100644 --- a/src/frontends/controllers/tex_helpers.C +++ b/src/frontends/controllers/tex_helpers.C @@ -17,9 +17,10 @@ #include "support/filetools.h" #include "support/lstrings.h" -#include "support/systemcall.h" -#include "support/path.h" #include "support/lyxalgo.h" +#include "support/package.h" +#include "support/path.h" +#include "support/systemcall.h" #include #include @@ -30,7 +31,6 @@ using std::endl; using std::sort; using std::unique; -extern string user_lyxdir; // home of *Files.lst namespace { @@ -50,7 +50,7 @@ vector listWithoutPath(vector & dbase) void rescanTexStyles() { // Run rescan in user lyx directory - Path p(user_lyxdir); + Path p(lyx::package().user_support()); Systemcall one; one.startscript(Systemcall::Wait, LibFileSearch("scripts", "TeXFiles.sh")); @@ -60,7 +60,7 @@ void rescanTexStyles() void texhash() { // Run texhash in user lyx directory - Path p(user_lyxdir); + Path p(lyx::package().user_support()); //path to texhash through system Systemcall one; diff --git a/src/frontends/xforms/ChangeLog b/src/frontends/xforms/ChangeLog index 789efd0bbd..b1b88b22ff 100644 --- a/src/frontends/xforms/ChangeLog +++ b/src/frontends/xforms/ChangeLog @@ -1,3 +1,12 @@ +2005-01-10 Angus Leeming + + * FormFiledialog.C: + * FormPreferences.C: + * lyx_gui.C: use support/package.h to provide the paths to the + various directories used by LyX. + + * FormDocument.C: remove some unused #includes. + 2005-01-05 Angus Leeming * FormFiledialog.C: diff --git a/src/frontends/xforms/FormDocument.C b/src/frontends/xforms/FormDocument.C index 89e28698d5..75de3ebfa3 100644 --- a/src/frontends/xforms/FormDocument.C +++ b/src/frontends/xforms/FormDocument.C @@ -22,12 +22,9 @@ #include "input_validators.h" // fl_unsigned_float_filter #include "xforms_helpers.h" -//#include "buffer.h" -//#include "BufferView.h" #include "CutAndPaste.h" #include "debug.h" #include "language.h" -//#include "lyx_main.h" // for user_lyxdir #include "lyxrc.h" #include "lyxtextclasslist.h" #include "tex-strings.h" diff --git a/src/frontends/xforms/FormFiledialog.C b/src/frontends/xforms/FormFiledialog.C index 455803730a..3bb2e80d56 100644 --- a/src/frontends/xforms/FormFiledialog.C +++ b/src/frontends/xforms/FormFiledialog.C @@ -18,15 +18,18 @@ #include #include +#include "forms_gettext.h" +#include "xforms_helpers.h" + +#include "gettext.h" + #include "frontends/Alert.h" +#include "frontends/Dialogs.h" + #include "support/FileInfo.h" #include "support/lyxlib.h" #include "support/lstrings.h" -#include "support/os.h" -#include "gettext.h" -#include "frontends/Dialogs.h" -#include "forms_gettext.h" -#include "xforms_helpers.h" +#include "support/package.h" #include @@ -536,7 +539,7 @@ void FileDialog::Private::FileDlgCB(FL_OBJECT *, long arg) break; case 11: // home - current_dlg_->SetDirectory(os::homepath()); + current_dlg_->SetDirectory(lyx::package().home_dir()); current_dlg_->SetMask(fl_get_input(file_dlg_form_->PatBox)); current_dlg_->Reread(); break; diff --git a/src/frontends/xforms/FormPreferences.C b/src/frontends/xforms/FormPreferences.C index b9546080c4..693f4d22a8 100644 --- a/src/frontends/xforms/FormPreferences.C +++ b/src/frontends/xforms/FormPreferences.C @@ -33,10 +33,11 @@ #include "Lsstream.h" #include "funcrequest.h" -#include "support/lyxfunctional.h" -#include "support/lyxmanip.h" #include "support/filetools.h" #include "support/LAssert.h" +#include "support/lyxfunctional.h" +#include "support/lyxmanip.h" +#include "support/package.h" #include "graphics/GraphicsCache.h" #include "graphics/GraphicsTypes.h" @@ -57,8 +58,6 @@ using std::vector; using std::setw; using std::setfill; -extern string system_lyxdir; -extern string user_lyxdir; namespace { @@ -308,8 +307,9 @@ void FormPreferences::apply() // The "Save" button has been pressed. if (controller().isClosing() && colors_.modifiedXformsPrefs) { + string const & user_support = lyx::package().user_support(); string const filename = - AddName(user_lyxdir, "preferences.xform"); + AddName(user_support, "preferences.xform"); colors_.modifiedXformsPrefs = !XformsColor::write(filename); } } diff --git a/src/frontends/xforms/lyx_gui.C b/src/frontends/xforms/lyx_gui.C index 6714d91616..f9caf3a66c 100644 --- a/src/frontends/xforms/lyx_gui.C +++ b/src/frontends/xforms/lyx_gui.C @@ -13,16 +13,16 @@ #include "lyx_gui.h" -#include "support/lyxlib.h" -#include "support/os.h" #include "support/filetools.h" +#include "support/lyxlib.h" +#include "support/package.h" #include "debug.h" #include "gettext.h" #include "lyx_main.h" -#include "lyxrc.h" #include "lyxfont.h" +#include "lyxrc.h" // FIXME: move this stuff out again #include "bufferlist.h" @@ -153,7 +153,6 @@ void lyx_gui::parse_init(int & argc, char * argv[]) if (!display) { lyxerr << "LyX: unable to access X display, exiting" << endl; - os::warn("Unable to access X display, exiting"); ::exit(1); } @@ -176,7 +175,8 @@ void lyx_gui::parse_init(int & argc, char * argv[]) void lyx_gui::parse_lyxrc() { - XformsColor::read(AddName(user_lyxdir, "preferences.xform")); + string const & user_support = lyx::package().user_support(); + XformsColor::read(AddName(user_support, "preferences.xform")); if (lyxrc.popup_font_encoding.empty()) lyxrc.popup_font_encoding = lyxrc.font_norm; diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index b03dca5938..2e2dafc523 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,3 +1,11 @@ +2005-01-10 Angus Leeming + + * ExternalTemplate.C: + * insetexternal.C: use support/package.h to provide the paths to the + various directories used by LyX. + + * insetgraphics.C: remove reference to system_lyxdir. + 2005-01-05 Angus Leeming * insetexternal.C: diff --git a/src/insets/ExternalTemplate.C b/src/insets/ExternalTemplate.C index 06118fa9a6..c9471a8a35 100644 --- a/src/insets/ExternalTemplate.C +++ b/src/insets/ExternalTemplate.C @@ -16,16 +16,15 @@ #include "lyxlex.h" #include "debug.h" -#include "support/path.h" -#include "support/LAssert.h" #include "support/filetools.h" +#include "support/LAssert.h" +#include "support/package.h" +#include "support/path.h" using std::endl; using std::ostream; using std::for_each; -extern string user_lyxdir; - // We have to have dummy default commands for security reasons! @@ -40,7 +39,7 @@ ExternalTemplate::FormatTemplate::FormatTemplate() ExternalTemplateManager::ExternalTemplateManager() { // gimp gnuchess gnuplot ical netscape tetris xpaint - readTemplates(user_lyxdir); + readTemplates(lyx::package().user_support()); if (lyxerr.debugging()) dumpTemplates(); } diff --git a/src/insets/insetexternal.C b/src/insets/insetexternal.C index 0eaf719ab5..c3d3c3d7d2 100644 --- a/src/insets/insetexternal.C +++ b/src/insets/insetexternal.C @@ -15,7 +15,6 @@ #include "BufferView.h" #include "buffer.h" #include "frontends/LyXView.h" -#include "lyx_main.h" #include "LaTeXFeatures.h" #include "gettext.h" #include "debug.h" @@ -23,11 +22,12 @@ #include "frontends/Dialogs.h" -#include "support/filetools.h" -#include "support/lstrings.h" -#include "support/path.h" -#include "support/forkedcall.h" #include "support/FileInfo.h" +#include "support/filetools.h" +#include "support/forkedcall.h" +#include "support/lstrings.h" +#include "support/package.h" +#include "support/path.h" #include #include @@ -242,7 +242,7 @@ string const InsetExternal::doSubstitution(Buffer const * buffer, result = subst(result, "$$Parameters", params_.parameters); result = subst(result, "$$FPath", filepath); result = subst(result, "$$Tempname", tempname_); - result = subst(result, "$$Sysdir", system_lyxdir); + result = subst(result, "$$Sysdir", lyx::package().system_support()); // Handle the $$Contents(filename) syntax if (contains(result, "$$Contents(\"")) { diff --git a/src/insets/insetgraphics.C b/src/insets/insetgraphics.C index 997ff5b110..d1c2aff1e6 100644 --- a/src/insets/insetgraphics.C +++ b/src/insets/insetgraphics.C @@ -92,8 +92,6 @@ TODO #include // For the std::max -extern string system_tempdir; - using std::ostream; using std::endl; diff --git a/src/lyx_cb.C b/src/lyx_cb.C index 0e83cb8669..a2f821756e 100644 --- a/src/lyx_cb.C +++ b/src/lyx_cb.C @@ -32,6 +32,7 @@ #include "support/FileInfo.h" #include "support/filetools.h" #include "support/forkedcall.h" +#include "support/package.h" #include "support/path.h" #include "support/systemcall.h" #include "support/lstrings.h" @@ -239,9 +240,10 @@ void QuitLyX() bufferlist.closeAll(); // do any other cleanup procedures now - lyxerr[Debug::INFO] << "Deleting tmp dir " << system_tempdir << endl; + lyxerr[Debug::INFO] << "Deleting tmp dir " + << lyx::package().temp_dir() << endl; - DestroyLyXTmpDir(system_tempdir); + DestroyLyXTmpDir(lyx::package().temp_dir()); lyx_gui::exit(); } @@ -531,9 +533,13 @@ void Reconfigure(BufferView * bv) bv->owner()->message(_("Running configure...")); // Run configure in user lyx directory - Path p(user_lyxdir); - string const configure_script = AddName(system_lyxdir, "configure"); + lyx::Package const & package = lyx::package(); + Path p(package.user_support()); + + string const configure_script = + AddName(package.system_support(), "configure"); string const configure_command = "sh " + QuoteName(configure_script); + Systemcall one; one.startscript(Systemcall::Wait, configure_command); p.pop(); diff --git a/src/lyx_main.C b/src/lyx_main.C index 8ee8502547..83a1380a68 100644 --- a/src/lyx_main.C +++ b/src/lyx_main.C @@ -11,38 +11,36 @@ #include "lyx_main.h" -#include "support/filetools.h" -#include "support/lyxlib.h" -#include "support/os.h" -#include "support/FileInfo.h" -#include "support/path.h" -#include "debug.h" -#include "gettext.h" -#include "lyxlex.h" - -#include "graphics/GraphicsTypes.h" - -#include "bufferlist.h" #include "buffer.h" -#include "lyxserver.h" +#include "bufferlist.h" +#include "commandtags.h" +#include "converter.h" +#include "debug.h" +#include "encoding.h" +#include "gettext.h" #include "kbmap.h" -#include "lyxfunc.h" -#include "ToolbarDefaults.h" -#include "MenuBackend.h" #include "language.h" #include "lastfiles.h" -#include "encoding.h" -#include "converter.h" +#include "lyxlex.h" +#include "lyxrc.h" +#include "lyxserver.h" #include "lyxtextclasslist.h" +#include "MenuBackend.h" +#include "ToolbarDefaults.h" #include "frontends/Alert.h" #include "frontends/lyx_gui.h" +#include "support/FileInfo.h" +#include "support/filetools.h" +#include "support/package.h" +#include "support/path.h" + #include "BoostFormat.h" #include -#include #include +#include using lyx::FileInfo; @@ -60,11 +58,6 @@ extern void QuitLyX(); extern LyXServer * lyxserver; -string system_lyxdir; -string build_lyxdir; -string system_tempdir; -string user_lyxdir; - DebugStream lyxerr; boost::scoped_ptr lastfiles; @@ -76,12 +69,24 @@ BufferList bufferlist; boost::scoped_ptr toplevel_keymap; +namespace { + +// Filled with the command line arguments "foo" of "-sysdir foo" or +// "-userdir foo". +string cl_system_support; +string cl_user_support; + +} // namespace anon + + LyX::LyX(int & argc, char * argv[]) { // Here we need to parse the command line. At least // we need to parse for "-dbg" and "-help" bool const want_gui = easyParse(argc, argv); + lyx::init_package(argv[0], cl_system_support, cl_user_support); + // Global bindings (this must be done as early as possible.) (Lgb) toplevel_keymap.reset(new kb_keymap); defaultKeyBindings(toplevel_keymap.get()); @@ -223,257 +228,60 @@ void LyX::init(bool gui) // Determine path of binary // - string binpath = os::binpath(); - string binname = os::binname(); - string fullbinname = MakeAbsPath(binname, binpath); + lyx::Package const & package = lyx::package(); - if (binpath.empty()) { - lyxerr << _("Warning: could not determine path of binary.") - << "\n" - << _("If you have problems, try starting LyX with an absolute path.") - << endl; - } - lyxerr[Debug::INIT] << "Name of binary: " << binname << endl; - lyxerr[Debug::INIT] << "Path of binary: " << binpath << endl; - - // - // Determine system directory. - // - - // Directories are searched in this order: - // 1) -sysdir command line parameter - // 2) LYX_DIR_13x environment variable - // 3) Maybe /TOP_SRCDIR/lib - // 4) /../Resources// [for LyX/Mac] - // 5) /../share// - // 5a) repeat 4 after following the Symlink if is a symbolic link. - // 6) hardcoded lyx_dir - // The directory is checked for the presence of the file - // "chkconfig.ltx", and if that is present, the directory - // is accepted as the system directory. - // If no chkconfig.ltx file is found, a warning is given, - // and the hardcoded lyx_dir is used. - - // If we had a command line switch, system_lyxdir is already set - string searchpath; - if (!system_lyxdir.empty()) - searchpath = MakeAbsPath(system_lyxdir) + ';'; - - string const lyxdir = GetEnvPath("LYX_DIR_13x"); - - if (!lyxdir.empty()) { - lyxerr[Debug::INIT] << "LYX_DIR_13x: " << lyxdir << endl; - searchpath += lyxdir + ';'; - } - - // Path of binary/../Resources/ - searchpath += NormalizePath(AddPath(binpath, "../Resources/") + - OnlyFilename(binname)) + ';'; - - string fullbinpath = binpath; - FileInfo file(fullbinname, true); - if (file.isLink()) { - lyxerr[Debug::INIT] << "binary is a link" << endl; - string link; - if (LyXReadLink(fullbinname, link, true)) { - // Path of binary/../share/name of binary/ - searchpath += NormalizePath(AddPath(binpath, - "../share/") - + OnlyFilename(binname)); - searchpath += ';'; - fullbinpath = link; - binpath = MakeAbsPath(OnlyPath(fullbinpath)); - } - } - - bool followlink; - do { - // Path of binary/../share/name of binary/ - string const exe_name = OnlyFilename(binname); -#ifdef _WIN32 - string const lyx_system_dir_name = - suffixIs(exe_name, ".exe") ? - ChangeExtension(exe_name, "") : - exe_name; -#else - string const lyx_system_dir_name = exe_name; -#endif - string const shared_dir_name = - NormalizePath(AddPath(binpath, "../share/")); - searchpath += shared_dir_name + lyx_system_dir_name + ';'; - - // Follow Symlinks - FileInfo file(fullbinpath, true); - followlink = file.isLink(); - if (followlink) { - lyxerr[Debug::INIT] << " directory " << fullbinpath - << " is a link" << endl; - string link; - if (LyXReadLink(fullbinpath, link, true)) { - fullbinpath = link; - binpath = MakeAbsPath(OnlyPath(fullbinpath)); - } - else { - followlink = false; - } - } - } while (followlink); - - // /TOP_SRCDIR/lib - build_lyxdir = MakeAbsPath("../lib", binpath); - if (!FileSearch(build_lyxdir, "lyxrc.defaults").empty()) { - searchpath += MakeAbsPath(AddPath(TOP_SRCDIR, "lib"), - binpath) + ';'; - lyxerr[Debug::INIT] << "Checking whether LyX is run in " - "place... yes" << endl; - } else { - lyxerr[Debug::INIT] - << "Checking whether LyX is run in place... no" - << endl; - build_lyxdir.erase(); - } - - // Hardcoded dir - searchpath += LYX_DIR; - - lyxerr[Debug::INIT] << "System directory search path: " - << searchpath << endl; - - string const filename = "chkconfig.ltx"; - string const temp = FileOpenSearch(searchpath, filename, string()); - system_lyxdir = OnlyPath(temp); - - // Reduce "path/../path" stuff out of system directory - system_lyxdir = NormalizePath(system_lyxdir); - - bool path_shown = false; - - // Warn if environment variable is set, but unusable - if (!lyxdir.empty()) { - if (system_lyxdir != NormalizePath(lyxdir)) { - lyxerr <<_("LYX_DIR_13x environment variable no good.") - << '\n' - << _("System directory set to: ") - << system_lyxdir << endl; - path_shown = true; - } - } - - // Warn the user if we couldn't find "chkconfig.ltx" - if (system_lyxdir == "./") { - lyxerr <<_("LyX Warning! Couldn't determine system directory. ") - <<_("Try the '-sysdir' command line parameter or ") - <<_("set the environment variable LYX_DIR_13x to the " - "LyX system directory ") - << _("containing the file `chkconfig.ltx'.") << endl; - if (!path_shown) { - FileInfo fi(LYX_DIR); - if (!fi.exist()) { - lyxerr << "Couldn't even find the default LYX_DIR." << endl - << "Giving up." << endl; - exit(1); - } -#if USE_BOOST_FORMAT - char const * const lyx_dir = LYX_DIR; - lyxerr << boost::format(_("Using built-in default %1$s" - " but expect problems.")) - % lyx_dir - << endl; -#else - lyxerr << _("Using built-in default ") << LYX_DIR - << _(" but expect problems.") - << endl; -#endif - } else { - lyxerr << _("Expect problems.") << endl; - } - system_lyxdir = LYX_DIR; - path_shown = true; - } - - if (!path_shown) - lyxerr[Debug::INIT] << "System directory: '" - << system_lyxdir << '\'' << endl; - - // - // Set PATH and localedir for LyX/Mac +#if defined (USE_MACOSX_PACKAGING) + // Set PATH for LyX/Mac // // LyX/Mac is a relocatable application bundle; here we add to // the PATH so it can find binaries like reLyX inside its own // application bundle, and also append PATH elements that it - // needs to run latex, previewers, etc. We also set the - // localedir inside the application bundle. - // + // needs to run latex, previewers, etc. - if (system_lyxdir == NormalizePath(AddPath(binpath, "../Resources/") + - OnlyFilename(binname))) { - string oldpath = GetEnv("PATH"); - string newpath = "PATH=" + oldpath + ":" + binpath + ":"; - newpath += "/sw/bin:/usr/local/bin:/usr/local/teTeX/bin/powerpc-apple-darwin-current"; - PutEnv(newpath); - lyxerr[Debug::INIT] << "Running from LyX/Mac bundle. " - "Setting PATH to: " << GetEnv("PATH") << endl; - if (GetEnvPath("LYX_LOCALEDIR").empty()) { - string const maybe_localedir = - NormalizePath(AddPath(system_lyxdir, - "../locale")); - FileInfo fi(maybe_localedir); - if (fi.isOK() && fi.isDir()) { - lyxerr[Debug::INIT] - << "Setting locale directory to " - << maybe_localedir << endl; - gettext_init(maybe_localedir); - } - } + string oldpath = GetEnv("PATH"); + string newpath = "PATH=" + oldpath + ":" + + lyx::package().binary_dir() + ":"; + newpath += "/sw/bin:/usr/local/bin:" + "/usr/local/teTeX/bin/powerpc-apple-darwin-current"; + PutEnv(newpath); + lyxerr[Debug::INIT] << "Running from LyX/Mac bundle. " + "Setting PATH to: " << GetEnv("PATH") << endl; +#endif + + // Set the locale_dir. + string locale_dir = package.locale_dir(); + FileInfo fi(locale_dir); + if (fi.isOK() && fi.isDir()) { + lyxerr[Debug::INIT] + << "Setting locale directory to " + << locale_dir << endl; + gettext_init(locale_dir); } - // - // Determine user lyx-dir - // - - // Directories are searched in this order: - // 1) -userdir command line parameter - // 2) LYX_USERDIR_13x environment variable - // 3) $HOME/. - - // If we had a command line switch, user_lyxdir is already set - bool explicit_userdir = true; - if (user_lyxdir.empty()) { - - // LYX_USERDIR_13x environment variable - user_lyxdir = GetEnvPath("LYX_USERDIR_13x"); - - // default behaviour - if (user_lyxdir.empty()) - user_lyxdir = AddPath(os::homepath(), - string(".") + PACKAGE); - explicit_userdir = false; - } - - lyxerr[Debug::INIT] << "User LyX directory: '" - << user_lyxdir << '\'' << endl; - // Check that user LyX directory is ok. We don't do that if // running in batch mode. if (gui) { - queryUserLyXDir(explicit_userdir); + queryUserLyXDir(package.explicit_user_support()); } else { first_start = false; } // // Shine up lyxrc defaults - // + + lyxrc.tempdir_path = package.temp_dir(); + lyxrc.document_path = package.document_dir(); // Default template path: system_dir/templates if (lyxrc.template_path.empty()) { - lyxrc.template_path = AddPath(system_lyxdir, "templates"); + lyxrc.template_path = + AddPath(package.system_support(), "templates"); } // Default lastfiles file: $HOME/.lyx/lastfiles if (lyxrc.lastfiles.empty()) { - lyxrc.lastfiles = AddName(user_lyxdir, "lastfiles"); + lyxrc.lastfiles = AddName(package.user_support(), + "lastfiles"); } // Disable gui when either lyxrc or easyparse says so @@ -513,10 +321,12 @@ void LyX::init(bool gui) lyxrc.print(); } - os::setTmpDir(CreateLyXTmpDir(lyxrc.tempdir_path)); - system_tempdir = os::getTmpDir(); + package.document_dir() = lyxrc.document_path; + + package.temp_dir() = CreateLyXTmpDir(lyxrc.tempdir_path); if (lyxerr.debugging(Debug::INIT)) { - lyxerr << "LyX tmp dir: `" << system_tempdir << '\'' << endl; + lyxerr << "LyX tmp dir: `" << package.temp_dir() << '\'' + << endl; } lyxerr[Debug::INIT] << "Reading lastfiles `" @@ -626,20 +436,23 @@ void LyX::deadKeyBindings(kb_keymap * kbmap) void LyX::queryUserLyXDir(bool explicit_userdir) { - string const configure_script = AddName(system_lyxdir, "configure"); + lyx::Package const & package = lyx::package(); + string const configure_script = + AddName(package.system_support(), "configure"); string const configure_command = "sh " + QuoteName(configure_script); // Does user directory exist? - FileInfo fileInfo(user_lyxdir); + string const & user_support = package.user_support(); + FileInfo fileInfo(user_support); if (fileInfo.isOK() && fileInfo.isDir()) { first_start = false; FileInfo script(configure_script); - FileInfo defaults(AddName(user_lyxdir, "lyxrc.defaults")); + FileInfo defaults(AddName(user_support, "lyxrc.defaults")); if (defaults.isOK() && script.isOK() && defaults.getModificationTime() < script.getModificationTime()) { lyxerr << _("LyX: reconfiguring user directory") << endl; - Path p(user_lyxdir); + Path p(user_support); ::system(configure_command.c_str()); lyxerr << "LyX: " << _("Done!") << endl; } @@ -649,45 +462,36 @@ void LyX::queryUserLyXDir(bool explicit_userdir) first_start = !explicit_userdir; // If the user specified explicitly a directory, ask whether - // to create it (otherwise, always create it) + // to create it. If the user says "no", then exit. if (explicit_userdir && - !Alert::askQuestion(_("You have specified an invalid LyX directory."), - _("It is needed to keep your own configuration."), - _("Should I try to set it up for you (recommended)?"))) { - lyxerr << _("Running without personal LyX directory.") << endl; - // No, let's use $HOME instead. - user_lyxdir = os::homepath(); - return; + !Alert::askQuestion( + _("You have specified a non-existent user LyX directory."), + _("It is needed to keep your own configuration."), + _("Should I try to set it up for you? I'll exit if \"No\"."))) { + lyxerr << _("No user LyX directory. Exiting.") << endl; + exit(1); } #if USE_BOOST_FORMAT lyxerr << boost::format(_("LyX: Creating directory %1$s" " and running configure...")) - % user_lyxdir + % package.user_support() << endl; #else - lyxerr << _("LyX: Creating directory ") << user_lyxdir + lyxerr << _("LyX: Creating directory ") << package.user_support() << _(" and running configure...") << endl; #endif - if (!createDirectory(user_lyxdir, 0755)) { - // Failed, let's use $HOME instead. - user_lyxdir = os::homepath(); -#if USE_BOOST_FORMAT - lyxerr << boost::format(_("Failed. Will use %1$s instead.")) - % user_lyxdir + if (!createDirectory(package.user_support(), 0755)) { + // Failed, so let's exit. + lyxerr << _("Failed to create directory. Exiting.") << endl; -#else - lyxerr << _("Failed. Will use ") << user_lyxdir << - _(" instead.") - << endl; -#endif - return; + exit(1); } // Run configure in user lyx directory - Path p(user_lyxdir); + Path p(package.user_support()); ::system(configure_command.c_str()); lyxerr << "LyX: " << _("Done!") << endl; } @@ -877,7 +681,7 @@ int parse_sysdir(string const & arg, string const &) lyxerr << _("Missing directory for -sysdir switch") << endl; exit(1); } - system_lyxdir = arg; + cl_system_support = arg; return 1; } @@ -887,7 +691,7 @@ int parse_userdir(string const & arg, string const &) lyxerr << _("Missing directory for -userdir switch") << endl; exit(1); } - user_lyxdir = arg; + cl_user_support = arg; return 1; } diff --git a/src/lyx_main.h b/src/lyx_main.h index f3b0f3c3b9..e9d380a7fe 100644 --- a/src/lyx_main.h +++ b/src/lyx_main.h @@ -23,12 +23,6 @@ class Buffer; class kb_keymap; -/// e.g. $HOME/.lyx/ -extern string user_lyxdir; -/// e.g. /usr/share/lyx/ -extern string system_lyxdir; -/// e.g. /tmp -extern string system_tempdir; /// last files loaded extern boost::scoped_ptr lastfiles; diff --git a/src/lyxfunc.C b/src/lyxfunc.C index b51662721b..75b36adfd3 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -18,7 +18,6 @@ #include "BufferView.h" #include "lyxserver.h" #include "intl.h" -#include "lyx_main.h" #include "lyx_cb.h" #include "LyXAction.h" #include "debug.h" @@ -63,6 +62,7 @@ #include "support/FileInfo.h" #include "support/forkedcontr.h" #include "support/lstrings.h" +#include "support/package.h" #include "support/path.h" #include "support/lyxfunctional.h" @@ -1450,7 +1450,7 @@ void LyXFunc::dispatch(FuncRequest const & ev, bool verbose) case LFUN_SAVEPREFERENCES: { - Path p(user_lyxdir); + Path p(lyx::package().user_support()); lyxrc.write("preferences"); } break; @@ -1686,12 +1686,13 @@ void LyXFunc::open(string const & fname) string filename; if (fname.empty()) { + string const & system_support = lyx::package().system_support(); FileDialog fileDlg(owner, _("Select document to open"), LFUN_FILE_OPEN, make_pair(string(_("Documents|#o#O")), string(lyxrc.document_path)), make_pair(string(_("Examples|#E#e")), - string(AddPath(system_lyxdir, "examples")))); + string(AddPath(system_support, "examples")))); FileDialog::Result result = fileDlg.open(initpath, @@ -1791,12 +1792,13 @@ void LyXFunc::doImport(string const & argument) + _(" file to import");; #endif + string const & system_support = lyx::package().system_support(); FileDialog fileDlg(owner, text, LFUN_IMPORT, make_pair(string(_("Documents|#o#O")), string(lyxrc.document_path)), make_pair(string(_("Examples|#E#e")), - string(AddPath(system_lyxdir, "examples")))); + string(AddPath(system_support, "examples")))); string const extension = "*." + formats.extension(format) + "| " + formats.prettyName(format) diff --git a/src/lyxserver.C b/src/lyxserver.C index d7044b146f..4ec7a43dda 100644 --- a/src/lyxserver.C +++ b/src/lyxserver.C @@ -43,7 +43,6 @@ #include #include "lyxserver.h" -#include "lyx_main.h" #include "debug.h" #include "lyxfunc.h" #include "support/lstrings.h" diff --git a/src/main.C b/src/main.C index dbf52f9420..43cf15c781 100644 --- a/src/main.C +++ b/src/main.C @@ -20,7 +20,7 @@ int main(int argc, char * argv[]) // lyx_localedir is used by gettext_init() is we have // i18n support built-in - string lyx_localedir = GetEnvPath("LYX_LOCALEDIR"); + string lyx_localedir = os::internal_path(GetEnv("LYX_LOCALEDIR")); if (lyx_localedir.empty()) lyx_localedir = LOCALEDIR; diff --git a/src/support/ChangeLog b/src/support/ChangeLog index b90fe11754..3de1e5526d 100644 --- a/src/support/ChangeLog +++ b/src/support/ChangeLog @@ -1,3 +1,25 @@ +2005-01-10 Angus Leeming + + * os.h: + * os_os2.C: + * os_unix.C: + * os_win32.C (binpath, binname, homepath, setTmpDir, getTmpDir): + removed. Remove also all code to set the associated member variables. + + * package.[Ch]: new files to ascertain the paths to the + various directories used by LyX. Does nothing with these paths, + just determines the strings themselves. + + * Makefile.am: add package.[Ch]. Add special casing to compile + package.lo. + + * filetools.C[Ch] (GetEnvPath): remove. + (getEnvPath): replacement. Returns a vector of paths. + + * filetools.C: + * tempname.C: use support/package.h to provide the paths to the + various directories used by LyX. + 2005-01-05 Angus Leeming * os_win32.C (external_path, internal_path): s/MAX_PATH/PATH_MAX/. diff --git a/src/support/Makefile.am b/src/support/Makefile.am index 405886440f..4cbe011034 100644 --- a/src/support/Makefile.am +++ b/src/support/Makefile.am @@ -11,6 +11,8 @@ if USE_LYXSTRING LYXSTRING = lyxstring.C lyxstring.h endif +localedir = $(datadir)/locale + libsupport_la_SOURCES = \ DebugStream.C \ DebugStream.h \ @@ -48,6 +50,8 @@ libsupport_la_SOURCES = \ nt_defines.h \ os2_defines.h \ os2_errortable.h \ + package.C \ + package.h \ path.C \ path.h \ putenv.C \ @@ -63,3 +67,18 @@ libsupport_la_SOURCES = \ translator.h \ types.h \ unlink.C + +package.lo: ../config.h \ + package.C package.h DebugStream.h FileInfo.h \ + filetools.h LAssert.h LOstream.h lstrings.h lyxlib.h os.h \ + $(top_srcdir)/src/BoostFormat.h $(top_srcdir)/src/debug.h \ + $(top_srcdir)/src/gettext.h $(top_srcdir)/src/Lsstream.h \ + $(top_srcdir)/src/LString.h + $(CXXCOMPILE) \ + -DLYX_DIR=\"$(pkgdatadir)\" \ + -DTOP_SRCDIR=\"$(top_srcdir)\" \ + -DLOCALEDIR=\"$(localedir)\" \ + -c $(top_srcdir)/src/support/package.C && \ + echo "timestamp" > $@ + + diff --git a/src/support/filetools.C b/src/support/filetools.C index 159d1567e5..1b207e4e37 100644 --- a/src/support/filetools.C +++ b/src/support/filetools.C @@ -18,21 +18,23 @@ #include -#include "debug.h" +#include "support/filetools.h" +#include "support/FileInfo.h" #include "support/lstrings.h" +#include "support/lyxlib.h" +#include "support/os.h" +#include "support/package.h" +#include "support/path.h" // I know it's OS/2 specific (SMiyata) #include "support/systemcall.h" -#include "filetools.h" -#include "lstrings.h" -#include "frontends/Alert.h" -#include "FileInfo.h" -#include "support/path.h" // I know it's OS/2 specific (SMiyata) +#include "debug.h" #include "gettext.h" -#include "lyxlib.h" -#include "os.h" - #include "Lsstream.h" +#include "frontends/Alert.h" + +#include + #include #include #include @@ -76,10 +78,6 @@ using std::ifstream; using std::vector; using std::getline; -extern string system_lyxdir; -extern string build_lyxdir; -extern string user_lyxdir; - bool IsLyXFilename(string const & filename) { @@ -167,8 +165,8 @@ bool IsDirWriteable(string const & path) // Uses a string of paths separated by ";"s to find a file to open. // Can't cope with pathnames with a ';' in them. Returns full path to file. -// If path entry begins with $$LyX/, use system_lyxdir -// If path entry begins with $$User/, use user_lyxdir +// If path entry begins with $$LyX/, use system_support +// If path entry begins with $$User/, use user_support // Example: "$$User/doc;$$LyX/doc" string const FileOpenSearch(string const & path, string const & name, string const & ext) @@ -178,12 +176,16 @@ string const FileOpenSearch(string const & path, string const & name, bool notfound = true; string tmppath = split(path, path_element, ';'); + lyx::Package const & package = lyx::package(); + string const & system_support = package.system_support(); + string const & user_support = package.user_support(); + while (notfound && !path_element.empty()) { path_element = os::internal_path(path_element); if (!suffixIs(path_element, '/')) path_element+= '/'; - path_element = subst(path_element, "$$LyX", system_lyxdir); - path_element = subst(path_element, "$$User", user_lyxdir); + path_element = subst(path_element, "$$LyX", system_support); + path_element = subst(path_element, "$$User", user_support); real_file = FileSearch(path_element, name, ext); @@ -282,22 +284,27 @@ string const FileSearch(string const & path, string const & name, // Search the file name.ext in the subdirectory dir of -// 1) user_lyxdir -// 2) build_lyxdir (if not empty) -// 3) system_lyxdir +// 1) user_support +// 2) build_support (if not empty) +// 3) system_support string const LibFileSearch(string const & dir, string const & name, string const & ext) { - string fullname = FileSearch(AddPath(user_lyxdir, dir), name, ext); + lyx::Package const & package = lyx::package(); + + string const & user_support = package.user_support(); + string fullname = FileSearch(AddPath(user_support, dir), + name, ext); if (!fullname.empty()) return fullname; - if (!build_lyxdir.empty()) - fullname = FileSearch(AddPath(build_lyxdir, dir), name, ext); + string const & build_support = package.build_support(); + if (!build_support.empty()) + fullname = FileSearch(AddPath(build_support, dir), name, ext); if (!fullname.empty()) return fullname; - return FileSearch(AddPath(system_lyxdir, dir), name, ext); + return FileSearch(AddPath(package.system_support(), dir), name, ext); } @@ -366,14 +373,27 @@ string const GetEnv(string const & envname) } -string const GetEnvPath(string const & name) +vector const getEnvPath(string const & name) { -#ifndef __EMX__ - string const pathlist = subst(GetEnv(name), ':', ';'); + typedef boost::char_separator Separator; + typedef boost::tokenizer Tokenizer; + +#if defined (__EMX__) || defined (_WIN32) + Separator const separator(";"); #else - string const pathlist = os::internal_path(GetEnv(name)); + Separator const separator(":"); #endif - return rtrim(pathlist, ";"); + + string const env_var = GetEnv(name); + Tokenizer const tokens(env_var, separator); + Tokenizer::const_iterator it = tokens.begin(); + Tokenizer::const_iterator const end = tokens.end(); + + std::vector vars; + for (; it != end; ++it) + vars.push_back(os::internal_path(*it)); + + return vars; } @@ -507,7 +527,7 @@ string const CreateTmpDir(string const & tempdir, string const & mask) int DestroyTmpDir(string const & tmpdir, bool Allfiles) { #ifdef __EMX__ - Path p(user_lyxdir); + Path p(lyx::package().user_support()); #endif if (Allfiles && DeleteAllFilesInDir(tmpdir)) { return -1; @@ -526,7 +546,9 @@ int DestroyTmpDir(string const & tmpdir, bool Allfiles) string const CreateBufferTmpDir(string const & pathfor) { static int count; - static string const tmpdir(pathfor.empty() ? os::getTmpDir() : pathfor); + static string const tmpdir = pathfor.empty() ? + lyx::package().temp_dir() : pathfor; + // We are in our own directory. Why bother to mangle name? // In fact I wrote this code to circumvent a problematic behaviour (bug?) // of EMX mkstemp(). @@ -551,14 +573,14 @@ string const CreateLyXTmpDir(string const & deflt) if ((!deflt.empty()) && (deflt != "/tmp")) { if (lyx::mkdir(deflt, 0777)) { #ifdef __EMX__ - Path p(user_lyxdir); + Path p(lyx::package().user_support()); #endif return CreateTmpDir(deflt, "lyx_tmpdir"); } else return deflt; } else { #ifdef __EMX__ - Path p(user_lyxdir); + Path p(lyx::package().user_support()); #endif return CreateTmpDir("/tmp", "lyx_tmpdir"); } @@ -732,7 +754,7 @@ string const ExpandPath(string const & path) return lyx::getcwd() /*GetCWD()*/ + '/' + RTemp; } if (Temp == "~") { - return os::homepath() + '/' + RTemp; + return lyx::package().home_dir() + '/' + RTemp; } if (Temp == "..") { return MakeAbsPath(copy); @@ -1215,7 +1237,7 @@ string const MakeDisplayPath(string const & path, unsigned int threshold) { string str = path; - string const home(os::homepath()); + string const home(lyx::package().home_dir()); // replace /home/blah with ~/ if (prefixIs(str, home)) diff --git a/src/support/filetools.h b/src/support/filetools.h index 40ca956026..e5a72b103b 100644 --- a/src/support/filetools.h +++ b/src/support/filetools.h @@ -31,8 +31,8 @@ int DestroyLyXTmpDir(string const & tmpdir); /** Find file by searching several directories. Uses a string of paths separated by ";"s to find a file to open. Can't cope with pathnames with a ';' in them. Returns full path to file. - If path entry begins with $$LyX/, use system_lyxdir. - If path entry begins with $$User/, use user_lyxdir. + If path entry begins with $$LyX/, use system_support. + If path entry begins with $$User/, use user_support. Example: "$$User/doc;$$LyX/doc". */ string const FileOpenSearch(string const & path, string const & name, @@ -79,9 +79,9 @@ bool IsSGMLFilename(string const & filename); /** Returns the path of a library data file. Search the file name.ext in the subdirectory dir of \begin{enumerate} - \item user_lyxdir - \item build_lyxdir (if not empty) - \item system_lyxdir + \item user_support + \item build_support (if not empty) + \item system_support \end{enumerate} The third parameter `ext' is optional. */ @@ -105,8 +105,13 @@ string const LibScriptSearch(string const & command); /// string const GetEnv(string const & envname); -/// A helper function. -string const GetEnvPath(string const & name); +/** Return the contents of the environment variable \c name, + * split using the OS-dependent token separating elements. + * Each element is then passed through os::internal_path to + * guarantee that it is in the form of a unix-stype path. + * If the environment variable is not set, then returns an empty vector. + */ +std::vector const getEnvPath(string const & name); /// bool PutEnv(string const & envstr); diff --git a/src/support/os.h b/src/support/os.h index 19b2622788..0f7f511d85 100644 --- a/src/support/os.h +++ b/src/support/os.h @@ -17,27 +17,14 @@ public: // static void init(int argc, char * argv[]); - // - static string const & binpath() {return binpath_;} - // - static string const & binname() {return binname_;} - // - static string const & homepath() {return homepath_;} // static string const & nulldev() {return nulldev_;} - // system_tempdir actually doesn't belong here. - // I put it here only to avoid a global variable. - static void setTmpDir(string p) {tmpdir_ = p;} - - // - static string const & getTmpDir() {return tmpdir_;} - // static string current_root(); // - static os::shell_type shell() {return _shell;} + static os::shell_type shell() {return shell_;} // DBCS aware! static string::size_type common_path(string const &p1, @@ -54,17 +41,13 @@ public: static char const * read_mode(); // same for popen(). static char const * popen_read_mode(); - // - static void warn(string mesg); private: - static string binpath_; - static string binname_; - static string tmpdir_; - static string homepath_; - static string nulldev_; - static os::shell_type _shell; + static string const nulldev_; + static os::shell_type shell_; +#ifdef __EMX__ // Used only on OS/2 to determine file system encoding. static unsigned long cp_; +#endif // Never initialize static variables in the header! // Anyway I bet this class will never be constructed. diff --git a/src/support/os_os2.C b/src/support/os_os2.C index 08d72a3fe6..9ef172934d 100644 --- a/src/support/os_os2.C +++ b/src/support/os_os2.C @@ -12,12 +12,7 @@ #define INCL_DOSERRORS #include -string os::binpath_ = string(); -string os::binname_ = string(); -string os::tmpdir_; -string os::homepath_; -string os::nulldev_; -os::shell_type os::_shell = os::UNIX; +os::shell_type os::shell_ = os::UNIX; unsigned long os::cp_ = 0; void os::init(int argc, char * argv[]) @@ -28,31 +23,21 @@ void os::init(int argc, char * argv[]) APIRET rc = DosGetInfoBlocks(&ptib, &ppib); if (rc != NO_ERROR) exit(rc); - char* tmp = new char[256]; - // This is the only reliable way to retrieve the executable name. - rc = DosQueryModuleName(ppib->pib_hmte, 256L, tmp); - if (rc != NO_ERROR) - exit(rc); - string p(tmp); - p = internal_path(p); - binname_ = OnlyFilename(p); - binname_.erase(binname_.length()-4, string::npos); - binpath_ = OnlyPath(p); // OS/2 cmd.exe has another use for '&' - string sh = OnlyFilename(GetEnvPath("EMXSHELL")); + string sh = OnlyFilename(os::internal_path(GetEnv("EMXSHELL"))); if (sh.empty()) { // COMSPEC is set, unless user unsets - sh = OnlyFilename(GetEnvPath("COMSPEC")); + sh = OnlyFilename(os::internal_path(GetEnv("COMSPEC"))); if (sh.empty()) sh = "cmd.exe"; } sh = lowercase(sh); // DosMapCase() is an overkill here if (contains(sh, "cmd.exe") || contains(sh, "4os2.exe")) - _shell = os::CMD_EXE; + shell_ = os::CMD_EXE; else - _shell = os::UNIX; + shell_ = os::UNIX; static bool initialized = false; if (initialized) return; @@ -65,17 +50,11 @@ void os::init(int argc, char * argv[]) // CPList[1] == system default codepage, the rest are auxilary. // Once cp_ is correctly set, you can call other routines. cp_ = CPList[1]; - - tmpdir_ = "/tmp"; - homepath_ = GetEnvPath("HOME"); - nulldev_ = "null"; } -void os::warn(string /*mesg*/) { - return; -} -string os::current_root() { +string os::current_root() +{ APIRET rc; ULONG drv_num, drv_map; rc = DosQueryCurrentDisk(&drv_num, &drv_map); @@ -87,6 +66,7 @@ string os::current_root() { return tmp; } + string::size_type os::common_path(string const &p1, string const &p2) { static bool initialized = false; if (!initialized) { @@ -120,7 +100,8 @@ string::size_type os::common_path(string const &p1, string const &p2) { return i; } -string os::internal_path(string const & p) { +string os::internal_path(string const & p) +{ static bool initialized = false; static bool leadbyte[256] = {false}; if (!initialized) { @@ -158,7 +139,8 @@ string os::internal_path(string const & p) { } -string os::external_path(string const & p) { +string os::external_path(string const & p) +{ return p; } diff --git a/src/support/os_unix.C b/src/support/os_unix.C index 02757899b1..b852b61463 100644 --- a/src/support/os_unix.C +++ b/src/support/os_unix.C @@ -4,56 +4,23 @@ #include #include "os.h" -#include "support/filetools.h" -#include "support/lstrings.h" -string os::binpath_ = string(); -string os::binname_ = string(); -string os::tmpdir_; -string os::homepath_; -string os::nulldev_; -os::shell_type os::_shell = os::UNIX; -unsigned long os::cp_ = 0; +string const os::nulldev_ = "/dev/null"; +os::shell_type os::shell_ = os::UNIX; -void os::init(int /*argc*/, char * argv[]) /* :cp_(0), _shell(os::UNIX) */ + +void os::init(int, char *[]) +{} + + +string os::current_root() { - static bool initialized = false; - - if (initialized) - return; - - initialized = true; - string tmp = argv[0]; - binname_ = OnlyFilename(tmp); - tmp = ExpandPath(tmp); // This expands ./ and ~/ - if (!os::is_absolute_path(tmp)) { - string binsearchpath = GetEnvPath("PATH"); - // This will make "src/lyx" work always :-) - binsearchpath += ";."; - tmp = FileOpenSearch(binsearchpath, tmp); - } - - tmp = MakeAbsPath(OnlyPath(tmp)); - - // In case we are running in place and compiled with shared libraries - if (suffixIs(tmp, "/.libs/")) - tmp.erase(tmp.length() - 6, string::npos); - binpath_ = tmp; - - tmpdir_ = "/tmp"; - homepath_ = GetEnvPath("HOME"); - nulldev_ = "/dev/null"; -} - -void os::warn(string /*mesg*/) { - return; -} - -string os::current_root() { return string("/"); } -string::size_type os::common_path(string const &p1, string const &p2) { + +string::size_type os::common_path(string const &p1, string const &p2) +{ string::size_type i = 0, p1_len = p1.length(), p2_len = p2.length(); @@ -67,19 +34,24 @@ string::size_type os::common_path(string const &p1, string const &p2) { return i; } -string os::internal_path(string const & p) { + +string os::internal_path(string const & p) +{ return p; } -string os::external_path(string const & p) { +string os::external_path(string const & p) +{ return p; } + bool os::is_absolute_path(string const & p) { return (!p.empty() && p[0] == '/'); } + // returns a string suitable to be passed to fopen when // reading a file char const * os::read_mode() @@ -87,6 +59,7 @@ char const * os::read_mode() return "r"; } + // returns a string suitable to be passed to popen when // reading a pipe char const * os::popen_read_mode() diff --git a/src/support/os_win32.C b/src/support/os_win32.C index 6825b483fd..64bd76ff8f 100644 --- a/src/support/os_win32.C +++ b/src/support/os_win32.C @@ -21,66 +21,17 @@ #endif -string os::binpath_ = string(); -string os::binname_ = string(); -string os::tmpdir_; -string os::homepath_; -string os::nulldev_; - #if defined(__CYGWIN__) || defined(__CYGWIN32__) -os::shell_type os::_shell = os::UNIX; +string const os::nulldev_ = "/dev/null"; +os::shell_type os::shell_ = os::UNIX; #else -os::shell_type os::_shell = os::CMD_EXE; +string const os::nulldev_ = "nul"; +os::shell_type os::shell_ = os::CMD_EXE; #endif -unsigned long os::cp_ = 0; -using std::endl; - -void os::init(int /* argc */, char * argv[]) -{ - static bool initialized = false; - if (initialized) return; - initialized = true; - string tmp = internal_path(argv[0]); - binname_ = OnlyFilename(tmp); - tmp = ExpandPath(tmp); // This expands ./ and ~/ - - if (!is_absolute_path(tmp)) { - string binsearchpath = GetEnvPath("PATH"); - // This will make "src/lyx" work always :-) - binsearchpath += ";."; - tmp = internal_path(argv[0]); - tmp = FileOpenSearch(binsearchpath, tmp); - } - - tmp = MakeAbsPath(OnlyPath(tmp)); - - // In case we are running in place and compiled with shared libraries - if (suffixIs(tmp, "/.libs/")) - tmp.erase(tmp.length()-6, string::npos); - binpath_ = tmp; - -#if defined(__CYGWIN__) || defined(__CYGWIN32__) - tmpdir_ = "/tmp"; - homepath_ = GetEnvPath("HOME"); - nulldev_ = "/dev/null"; -#else - // Use own tempdir - tmp.erase(tmp.length()-4,4); - tmpdir_ = tmp + "tmp"; - - homepath_ = GetEnvPath("HOMEDRIVE") + GetEnvPath("HOMEPATH"); - nulldev_ = "nul"; -#endif -} - - -void os::warn(string mesg) -{ - MessageBox(0, mesg.c_str(), "LyX error", - MB_OK|MB_ICONSTOP|MB_SYSTEMMODAL); -} +void os::init(int, char *[]) +{} string os::current_root() @@ -135,7 +86,7 @@ string os::external_path(string const & p) lyxerr[Debug::LATEX] << " [" << p << "]->>[" - << dos_path << ']' << endl; + << dos_path << ']' << std::endl; return dos_path; } diff --git a/src/support/package.C b/src/support/package.C new file mode 100644 index 0000000000..e75e4338c3 --- /dev/null +++ b/src/support/package.C @@ -0,0 +1,704 @@ +/** + * \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 + +#include "support/package.h" + +#include "BoostFormat.h" +#include "debug.h" +#include "gettext.h" + +#include "support/FileInfo.h" +#include "support/filetools.h" +#include "support/LAssert.h" +#include "support/lstrings.h" +#include "support/os.h" + +#include + +#include +#include + +#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_WINDOWS_PACKAGING) +# include +# include // SHGetFolderPath + + // Needed for MinGW: +# ifndef SHGFP_TYPE_CURRENT +# define SHGFP_TYPE_CURRENT 0 +# endif + +#elif defined (USE_MACOSX_PACKAGING) +# include // FSFindFolder, FSRefMakePath +#endif + + +namespace lyx { + +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) +{ + // Can do so only once. + if (initialised_) + return; + + package_ = Package(command_line_arg0, + command_line_system_support_dir, + command_line_user_support_dir); + initialised_ = true; +} + + +Package const & package() +{ + lyx::Assert(initialised_); + return package_; +} + + +namespace { + +string const abs_path_from_binary_name(string const & exe); + +std::pair const get_build_dirs(string const & abs_binary); + +string const get_document_dir(string const & home_dir); + +string const get_home_dir(); + +string const get_locale_dir(string const & system_support_dir); + +string const get_system_support_dir(string const & abs_binary, + string const & command_line_system_support_dir); + +string const get_temp_dir(); + +string const get_default_user_support_dir(string const & home_dir); + +std::pair const +get_user_support_dir(string const & default_user_support_dir, + string const & command_line_user_support_dir); + +} // namespace anon + + +Package::Package(string const & command_line_arg0, + string const & command_line_system_support_dir, + string const & command_line_user_support_dir) + : explicit_user_support_dir_(false) +{ + home_dir_ = get_home_dir(); + temp_dir_ = get_temp_dir(); + document_dir_ = get_document_dir(home_dir_); + + string const abs_binary = abs_path_from_binary_name(command_line_arg0); + binary_dir_ = OnlyPath(abs_binary); + + // Is LyX being run in-place from the build tree? + boost::tie(build_support_dir_, system_support_dir_) = + get_build_dirs(abs_binary); + + 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_); + + string 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); + + lyxerr[Debug::INIT] + << "\n" + << "\tbinary_dir " << binary_dir() << '\n' + << "\tsystem_support " << system_support() << '\n' + << "\tbuild_support " << build_support() << '\n' + << "\tuser_support " << user_support() << '\n' + << "\tlocale_dir " << locale_dir() << '\n' + << "\tdocument_dir " << document_dir() << '\n' + << "\ttemp_dir " << temp_dir() << '\n' + << "\thome_dir " << home_dir() << '\n' + << "<\\package>\n" << std::endl; +} + + +namespace { + +bool check_command_line_dir(string const & dir, + string const & file, + string const & command_line_switch); + +string const extract_env_var_dir(string const & env_var); + +bool check_env_var_dir(string const & dir, + string const & env_var); + +bool check_env_var_dir(string const & dir, + string const & file, + string const & env_var); + +string const relative_locale_dir(); + +string const relative_system_support_dir(); + + +#if defined (USE_WINDOWS_PACKAGING) +// Given a folder ID, returns the folder name (in unix-style format). +// Eg CSIDL_PERSONAL -> "C:/Documents and Settings/USERNAME/My Documents" +string const win32_folder_path(int folder_id) +{ + char folder_path[PATH_MAX + 1]; + if (SUCCEEDED(SHGetFolderPath(0, folder_id, 0, + SHGFP_TYPE_CURRENT, folder_path))) + return os::internal_path(folder_path); + return string(); +} +#endif + + +std::pair const get_build_dirs(string const & abs_binary) +{ + string const check_text = "Checking whether LyX is run in place..."; + + // We're looking for "lyxrc.defaults" in a directory + // binary_dir/../lib + // We're also looking for "chkconfig.ltx" in a directory + // binary_dir/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. + string binary = abs_binary; + while (true) { + // Try and find "lyxrc.defaults". + string const binary_dir = OnlyPath(binary); + string const build_support_dir = + NormalizePath(AddPath(binary_dir, "../lib")); + + if (!FileSearch(build_support_dir, "lyxrc.defaults").empty()) { + // Try and find "chkconfig.ltx". + string const system_support_dir = + MakeAbsPath(AddPath(TOP_SRCDIR, "lib"), + AddPath(binary_dir, "support")); + + 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. + lyx::FileInfo const file(binary, true); + if (!file.isOK() || !file.isLink()) + break; + + string link; + if (LyXReadLink(binary, link, true)) { + binary = link; + } else { + // Unable to resolve the link. + break; + } + } + + lyxerr[Debug::INIT] << check_text << " no" << std::endl; + return std::make_pair(string(), string()); +} + + +// Specification of document_dir_ may be reset by LyXRC, +// but the default is fixed for a given OS. +string const get_document_dir(string const & home_dir) +{ +#if defined (USE_WINDOWS_PACKAGING) + (void)home_dir; // Silence warning about unused variable. + return win32_folder_path(CSIDL_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". +string 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 os::internal_path(home_dir); +} + + +// Several sources are probed to ascertain the locale directory. +// The only requirement is that the result is indeed a directory. +string const get_locale_dir(string const & system_support_dir) +{ + // 1. Use the "LYX_LOCALEDIR" environment variable. + string path = extract_env_var_dir("LYX_LOCALEDIR"); + if (!path.empty() && check_env_var_dir(path, "LYX_LOCALEDIR")) + return path; + + // 2. Search for system_support_dir / + // The is OS-dependent. (On Unix, it will + // be "../locale/".) + path = NormalizePath(AddPath(system_support_dir, relative_locale_dir())); + + lyx::FileInfo fi(path); + if (fi.isOK() && fi.isDir()) + return path; + + // 3. Fall back to the hard-coded LOCALEDIR. + path = LOCALEDIR; + lyx::FileInfo fi2(path); + if (fi2.isOK() && fi2.isDir()) + return path; + + return string(); +} + + +// Specification of temp_dir_ may be reset by LyXRC, +// but the default is fixed for a given OS. +string const get_temp_dir() +{ +#if defined (USE_WINDOWS_PACKAGING) + // Typical example: C:/TEMP/. + char path[PATH_MAX + 1]; + GetTempPath(PATH_MAX, path); + return os::internal_path(path); +#else // Posix-like. + return "/tmp"; +#endif +} + + +// If we use a 'lazy' lyxerr in the hope of setting the locale before +// printing any messages, then we should ensure that it is flushed first. +void bail_out() +{ +#ifndef CXX_GLOBAL_CSTD + using std::exit; +#endif + exit(1); +} + + +// Extracts the absolute path from the foo of "-sysdir foo" or "-userdir foo" +string const abs_path_from_command_line(string const & command_line) +{ + if (command_line.empty()) + return string(); + + string const path = os::internal_path(command_line); + return os::is_absolute_path(path) ? path : MakeAbsPath(path); +} + + +// 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); + 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 (lyx::FileInfo(abs_exe_path, true).isOK()) + 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 string(); + + std::vector const path = getEnvPath("PATH"); + std::vector::const_iterator it = path.begin(); + std::vector::const_iterator const end = path.end(); + for (; it != end; ++it) { + if (!os::is_absolute_path(*it)) + // Someone is playing silly buggers. + continue; + + string const exe_path = AddName(*it, exe_name); + if (lyx::FileInfo(exe_path, true).isOK()) + return exe_path; + } + + // Didn't find anything. + return string(); +} + + +// Extracts the absolute path to the binary name received as argv[0]. +string const abs_path_from_binary_name(string const & exe) +{ + string const abs_binary = get_binary_path(exe); + if (abs_binary.empty()) { +#if USE_BOOST_FORMAT + using boost::format; + lyxerr << format(_("Unable to determine the path to the " + "LyX binary from the command line %1%")) + % exe + << std::endl; +#else + lyxerr << _("Unable to determine the path to the " + "LyX binary from the command line ") + << exe + << std::endl; +#endif + bail_out(); + } + 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". +string const +get_system_support_dir(string 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 searched_dirs; + + // 1. Use the -sysdir command line parameter. + string 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, chkconfig_ltx, "-sysdir")) + return path; + } + + // 2. Use the "LYX_DIR_13x" environment variable. + path = extract_env_var_dir("LYX_DIR_13x"); + if (!path.empty()) { + searched_dirs.push_back(path); + if (check_env_var_dir(path, chkconfig_ltx, "LYX_DIR_13x")) + return path; + } + + // 3. Search relative to the lyx binary. + // We're looking for "chkconfig.ltx" in a directory + // OnlyPath(abs_binary) / / PACKAGE / + // PACKAGE is hardcoded in config.h. Eg "lyx" or "lyx-1.3.6cvs". + // 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. + string binary = abs_binary; + while (true) { + // Try and find "chkconfig.ltx". + string const binary_dir = OnlyPath(binary); + + string const lyxdir = + NormalizePath(AddPath(binary_dir, relative_lyxdir)); + searched_dirs.push_back(lyxdir); + + if (!FileSearch(lyxdir, 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. + lyx::FileInfo const file(binary, true); + if (!file.isOK() || !file.isLink()) + break; + + string link; + if (LyXReadLink(binary, link, true)) { + binary = link; + } else { + // Unable to resolve the link. + break; + } + } + + // 4. Repeat the exercise on the directory itself. + string binary_dir = OnlyPath(abs_binary); + 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.) + lyx::FileInfo const file(binary_dir, true); + if (!file.isOK() || !file.isLink()) + break; + + string link; + if (LyXReadLink(binary_dir, link, true)) { + binary_dir = link; + } else { + // Unable to resolve the link. + break; + } + + // Try and find "chkconfig.ltx". + string const lyxdir = + NormalizePath(AddPath(binary_dir, relative_lyxdir)); + searched_dirs.push_back(lyxdir); + + if (!FileSearch(lyxdir, chkconfig_ltx).empty()) { + // Success! "chkconfig.ltx" has been found. + return lyxdir; + } + } + + // 5. In desparation, try the hard-coded LYX_DIR. + path = LYX_DIR; + if (!FileSearch(path, chkconfig_ltx).empty()) + return path; + + // Everything has failed :-( + // So inform the user and exit. + string searched_dirs_str; + typedef std::list::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; + } + +#if USE_BOOST_FORMAT + using boost::format; + lyxerr << format(_("Unable to determine the system directory " + "having searched\n" + "\t%1%\n" + "Try the '-sysdir' command line parameter or " + "set the environment variable LYX_DIR_13x to " + "the LyX system directory containing the file " + "`chkconfig.ltx'.")) + % searched_dirs_str + << std::endl; +#else + lyxerr << _("Unable to determine the system directory " + "having searched\n") + << '\t' << searched_dirs_str << '\n' + << _("Try the '-sysdir' command line parameter or " + "set the environment variable LYX_DIR_13x to the " + "LyX system directory containing the file " + "`chkconfig.ltx'.") + << std::endl; +#endif + + bail_out(); + // Keep the compiler happy. + return string(); +} + + +// 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 const +get_user_support_dir(string const & default_user_support_dir, + string const & command_line_user_support_dir) +{ + bool explicit_userdir = true; + + // 1. Use the -userdir command line parameter. + string 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_13x environment variable. + path = extract_env_var_dir("LYX_USERDIR_13x"); + 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 all platforms but Win32 where it will be something like +// "C:/Documents and Settings/USERNAME/Application Data/lyx" +string const get_default_user_support_dir(string const & home_dir) +{ +#if defined (USE_WINDOWS_PACKAGING) + (void)home_dir; // Silence warning about unused variable. + + return AddPath(win32_folder_path(CSIDL_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 string(); + + char store[PATH_MAX + 1]; + OSStatus const status_code = + FSRefMakePath(&fsref, + reinterpret_cast(store), PATH_MAX); + if (status_code != 0) + return string(); + + return AddPath(reinterpret_cast(store), PACKAGE); + +#else // USE_POSIX_PACKAGING + return AddPath(home_dir, 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) +{ + string const abs_path = FileSearch(dir, file); + if (abs_path.empty()) { +#if USE_BOOST_FORMAT + using boost::format; + lyxerr << format(_("Invalid %1% switch.\n" + "Directory %2% does not contain %3%.")) + % command_line_switch % dir % file + << std::endl; +#else + lyxerr << _("Invalid ") << command_line_switch + << _(" switch.\n") + << _("Directory ") << dir + << _(" does not contain ") << file + << std::endl; +#endif + } + + return !abs_path.empty(); +} + + +// 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)); + return dir.empty() ? dir : 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(string const & dir, + string const & file, + string const & env_var) +{ + string const abs_path = FileSearch(dir, file); + if (abs_path.empty()) { +#if USE_BOOST_FORMAT + using boost::format; + lyxerr << format(_("Invalid %1% environment variable.\n" + "Directory %2% does not contain %3%.")) + % env_var % dir % file + << std::endl; +#else + lyxerr << _("Invalid ") << env_var + << _(" environment variable.\n") + << _("Directory ") << dir + << _(" does not contain ") << file + << std::endl; +#endif + } + + 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(string const & dir, + string const & env_var) +{ + lyx::FileInfo fi(dir); + bool const success = (fi.isOK() && fi.isDir()); + + if (!success) { +#if USE_BOOST_FORMAT + using boost::format; + lyxerr << format(_("Invalid %1% environment variable.\n" + "%2% is not a directory.")) + % env_var % dir + << std::endl; +#else + lyxerr << _("Invalid ") << env_var + << _(" environment variable.\n") + << dir << _(" is not a directory.") + << std::endl; +#endif + } + + return success; +} + + +// The locale directory relative to the LyX system directory. +string const relative_locale_dir() +{ + return "../locale/"; +} + + +// 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 = AddPath("../Resources/", PACKAGE); +#else // Posix-like. + result = AddPath("../share/", PACKAGE); +#endif + + return result; +} + +} // namespace anon + +} // namespace lyx diff --git a/src/support/package.h b/src/support/package.h new file mode 100644 index 0000000000..c3a0b82a09 --- /dev/null +++ b/src/support/package.h @@ -0,0 +1,176 @@ +// -*- C++ -*- +/** + * \file package.h + * 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. + * + * A store of the paths to the various different directoies used + * by LyX. These paths differ markedly from one OS to another, + * following the local Windows, MacOS X or Posix conventions. + */ +#ifndef LYX_PACHAGE_H +#define LYX_PACHAGE_H + +#include "LString.h" + +namespace lyx { + +class Package; + +/** Initialise package() with the command line data. + * This data is exactly as it was passed in the argv[] array. + * + * @param command_line_arg0 argv[0], the name of the LyX executable + * as passed on the command line. + * + * @param command_line_system_support_dir, the LyX system dir, + * as specified on the command line with "-sysdir ". + * + * @param command_line_user_support_dir, the LyX user dir, + * as specified on the command line with "-userdir ". + */ +void init_package(string const & command_line_arg0, + string const & command_line_system_support_dir, + string const & command_line_user_support_dir); + +/** Accessor to the global data. + * Asserts that init_package() has been called first. + */ +Package const & package(); + +class Package { +public: + /// Default constructor does not lead to the paths being set. + Package(); + + /** Called by init_package, above. + * All paths will be initialized. + */ + Package(string const & command_line_arg0, + string const & command_line_system_support_dir, + string const & command_line_user_support_dir); + + /** The directory containing the LyX executable. + */ + string const & binary_dir() const; + + /** The path to the system-level support files + * we're actually going to use. + */ + string const & system_support() const; + + /** The path to the autogenerated support files + * when running in-place. + */ + string const & build_support() const; + + /** The path to the user-level support files. + */ + string const & user_support() const; + + /** The user_support directory was set explicitly using either + * the -userdir command line switch or + * the LYX_USERDIR_13x environment variable. + */ + bool explicit_user_support() const; + + /** The path to the locale directory. + */ + string const & locale_dir() const; + + /** The default document directory. + * Can be reset by LyXRC. + */ + string & document_dir() const; + + /** The path to the temporary directory. + * (Eg /tmp on *nix.) + * Can be reset by LyXRC. + */ + string & temp_dir() const; + + /** Used when setting the user_support directory. + * Used also when expanding "~/" or contracting to "~/". (filetools.C) + * Used by the XForms file dialog. + * Used in emergencyWrite (bufferlist.C) as one possible location + * for the dump. + */ + string const & home_dir() const; + +private: + string binary_dir_; + string system_support_dir_; + string build_support_dir_; + string user_support_dir_; + string locale_dir_; + mutable string document_dir_; + mutable string temp_dir_; + string home_dir_; + bool explicit_user_support_dir_; +}; + + +inline +Package::Package() {} + +inline +string const & Package::binary_dir() const +{ + return binary_dir_; +} + +inline +string const & Package::system_support() const +{ + return system_support_dir_; +} + +inline +string const & Package::build_support() const +{ + return build_support_dir_; +} + +inline +string const & Package::user_support() const +{ + return user_support_dir_; +} + +inline +bool Package::explicit_user_support() const +{ + return explicit_user_support_dir_; +} + +inline +string const & Package::locale_dir() const +{ + return locale_dir_; +} + +inline +string & Package::document_dir() const +{ + return document_dir_; +} + +inline +string & Package::temp_dir() const +{ + return temp_dir_; +} + +inline +string const & Package::home_dir() const +{ + return home_dir_; +} + +} // namespace lyx + +#endif // LYX_PACHAGE_H diff --git a/src/support/tempname.C b/src/support/tempname.C index 4c2ce91e59..82e30967b7 100644 --- a/src/support/tempname.C +++ b/src/support/tempname.C @@ -8,7 +8,7 @@ #include "support/filetools.h" #include "support/lstrings.h" #include "debug.h" -#include "os.h" +#include "package.h" #if !defined(HAVE_MKSTEMP) && defined(HAVE_MKTEMP) # include @@ -39,7 +39,7 @@ int make_tempfile(char * templ) string const lyx::tempName(string const & dir, string const & mask) { - string const tmpdir(dir.empty() ? os::getTmpDir() : dir); + string const tmpdir(dir.empty() ? lyx::package().temp_dir() : dir); string tmpfl(AddName(tmpdir, mask)); tmpfl += tostr(getpid()); tmpfl += "XXXXXX";