From 87fbbe0a5647f79f0620bd3811aee3392e67c985 Mon Sep 17 00:00:00 2001 From: Angus Leeming Date: Wed, 8 Jun 2005 13:14:50 +0000 Subject: [PATCH] Rewrite lyx_path_prefix.C to * generate a minimal "path_prefix" variable (cull repeated elements) * replace an existing "path_prefix" entry if one exists * run "sh configure" in blocking fashion so that the user can see what is going on. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_3_X@10014 a592a061-630c-0410-9148-cb99ea01b6c8 --- .../packaging/installer/lyx_installer.nsi | 7 +- .../installer/lyx_languages/english.nsh | 1 + .../installer/lyx_languages/french.nsh | 1 + .../installer/lyx_languages/german.nsh | 1 + .../packaging/installer/lyx_path_prefix.C | 249 +++++++++++++++--- 5 files changed, 216 insertions(+), 43 deletions(-) diff --git a/development/Win32/packaging/installer/lyx_installer.nsi b/development/Win32/packaging/installer/lyx_installer.nsi index d4cd6e485c..db9d9474df 100644 --- a/development/Win32/packaging/installer/lyx_installer.nsi +++ b/development/Win32/packaging/installer/lyx_installer.nsi @@ -209,11 +209,16 @@ Section "-Installation actions" SecInstallation File /r "${PRODUCT_SOURCEDIR}\bin" ${if} "$PathPrefix" != "" - lyx_path_prefix::set "$INSTDIR\Resources\lyx\configure" "$PathPrefix" + lyx_path_prefix::set_path_prefix "$INSTDIR\Resources\lyx\configure" "$PathPrefix" Pop $0 ${if} $0 != 0 MessageBox MB_OK "$(ModifyingConfigureFailed)" ${endif} + lyx_path_prefix::run_configure "$INSTDIR\Resources\lyx\configure" "$PathPrefix" + Pop $0 + ${if} $0 != 0 + MessageBox MB_OK "$(RunConfigureFailed)" + ${endif} ${endif} WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "${PRODUCT_EXE}" diff --git a/development/Win32/packaging/installer/lyx_languages/english.nsh b/development/Win32/packaging/installer/lyx_languages/english.nsh index ce02dc8cb5..99cbddc753 100644 --- a/development/Win32/packaging/installer/lyx_languages/english.nsh +++ b/development/Win32/packaging/installer/lyx_languages/english.nsh @@ -18,6 +18,7 @@ LangString SecFileAssocDescription "${LYX_LANG}" "Create associations between th LangString SecDesktopDescription "${LYX_LANG}" "A ${PRODUCT_NAME} icon on the desktop." LangString ModifyingConfigureFailed "${LYX_LANG}" "Failed attempting to set 'path_prefix' in the configure script" +LangString RunConfigureFailed "${LYX_LANG}" "Failed attempting to execute the configure script" LangString FinishPageMessage "${LYX_LANG}" "Congratulations! LyX has been installed successfully." LangString FinishPageRun "${LYX_LANG}" "Launch LyX" diff --git a/development/Win32/packaging/installer/lyx_languages/french.nsh b/development/Win32/packaging/installer/lyx_languages/french.nsh index 654933312e..abd5ce846b 100644 --- a/development/Win32/packaging/installer/lyx_languages/french.nsh +++ b/development/Win32/packaging/installer/lyx_languages/french.nsh @@ -19,6 +19,7 @@ LangString SecFileAssocDescription "${LYX_LANG}" "Cr LangString SecDesktopDescription "${LYX_LANG}" "Une icône ${PRODUCT_NAME} sur le bureau." LangString ModifyingConfigureFailed "${LYX_LANG}" "Échec de l'allocation 'path_prefix' lors de la configuration." +LangString RunConfigureFailed "${LYX_LANG}" "Failed attempting to execute the configure script" LangString FinishPageMessage "${LYX_LANG}" "Félicitations ! LyX est installé avec succès." LangString FinishPageRun "${LYX_LANG}" "Démarrer LyX" diff --git a/development/Win32/packaging/installer/lyx_languages/german.nsh b/development/Win32/packaging/installer/lyx_languages/german.nsh index 53653a55b7..7d913f7b83 100644 --- a/development/Win32/packaging/installer/lyx_languages/german.nsh +++ b/development/Win32/packaging/installer/lyx_languages/german.nsh @@ -18,6 +18,7 @@ LangString SecFileAssocDescription "${LYX_LANG}" "Create associations between th LangString SecDesktopDescription "${LYX_LANG}" "A ${PRODUCT_NAME} icon on the desktop." LangString ModifyingConfigureFailed "${LYX_LANG}" "Failed attempting to set 'path_prefix' in the configure script" +LangString RunConfigureFailed "${LYX_LANG}" "Failed attempting to execute the configure script" LangString FinishPageMessage "${LYX_LANG}" "Congratulations! LyX has been installed successfully." LangString FinishPageRun "${LYX_LANG}" "Launch LyX" diff --git a/development/Win32/packaging/installer/lyx_path_prefix.C b/development/Win32/packaging/installer/lyx_path_prefix.C index 305d32a131..601818600b 100644 --- a/development/Win32/packaging/installer/lyx_path_prefix.C +++ b/development/Win32/packaging/installer/lyx_path_prefix.C @@ -18,7 +18,7 @@ * Compile the code with * * g++ -I/c/Program\ Files/NSIS/Contrib -Wall -shared \ - * lyx_path_prefix.c -o lyx_path_prefix.dll + * lyx_path_prefix.C -o lyx_path_prefix.dll * * Move resulting .dll to /c/Program\ Files/NSIS/Plugins */ @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include namespace { @@ -42,12 +44,154 @@ std::string const subst(std::string const & a, std::string::size_type const olen = oldstr.length(); while ((i = lstr.find(oldstr, i)) != std::string::npos) { lstr.replace(i, olen, newstr); - i += newstr.length(); // We need to be sure that we dont - // use the same i over and over again. + i += newstr.length(); } return lstr; } + +std::string const basename(std::string const & path) +{ + std::string::size_type const final_slash = path.find_last_of('\\'); + if (final_slash == std::string::npos) + return path; + return path.substr(final_slash+1); +} + + +std::string const dirname(std::string const & path) +{ + std::string::size_type const final_slash = path.find_last_of('\\'); + if (final_slash == std::string::npos) + return std::string(); + return path.substr(0, final_slash); +} + + +std::string const pop_from_stack() +{ + char data[10*MAX_PATH]; + popstring(data); + return data; +} + + +std::list const tokenize(std::string data, + char const separator) +{ + std::list result; + while (true) { + std::string::size_type const end = data.find(separator); + if (end == std::string::npos) { + result.push_back(data); + break; + } + result.push_back(data.substr(0, end)); + data = data.substr(end+1); + } + return result; +} + + +void remove_duplicates(std::list & data) +{ + typedef std::list::iterator iterator; + for (iterator it = data.begin(); it != data.end(); ++it) { + iterator next = it; + ++next; + if (next == data.end()) + break; + iterator end = std::remove(next, data.end(), *it); + data.erase(end, data.end()); + } +} + + +std::string concatenate(std::list const & data, + char const separator) +{ + typedef std::list::const_iterator iterator; + iterator it = data.begin(); + iterator const end = data.end(); + if (it == end) + return std::string(); + + std::ostringstream result; + result << *it; + ++it; + for (; it != end; ++it) { + result << separator << *it; + } + return result.str(); +} + + +std::string const sanitize_path(std::string const & in) +{ + // Replace multiple, adjacent directory separators. + std::string out = subst(in, "\\\\", "\\"); + std::list out_list = tokenize(out, ';'); + remove_duplicates(out_list); + return concatenate(out_list, ';'); +} + + +bool replace_path_prefix(std::string & data, + std::string::size_type prefix_pos, + std::string const & path_prefix) +{ + std::string::size_type start_prefix = + data.find_first_of('"', prefix_pos); + if (start_prefix == std::string::npos) + return false; + start_prefix += 1; + + std::string::size_type end_line = + data.find_first_of('\n', prefix_pos); + if (end_line == std::string::npos) + return false; + + std::string::size_type end_prefix = + data.find_last_of('"', end_line); + if (end_prefix == std::string::npos || end_prefix == start_prefix) + return false; + + std::string::size_type const count = end_prefix - start_prefix; + std::string const old_prefix = data.substr(start_prefix, count); + std::string const prefix = + subst(sanitize_path(path_prefix + ';' + old_prefix), "\\", "\\\\"); + + data.erase(start_prefix, count); + data.insert(start_prefix, prefix); + + return true; +} + + +bool insert_path_prefix(std::string & data, + std::string::size_type xfonts_pos, + std::string const & path_prefix) +{ + std::string::size_type const xfonts_start = + data.find_last_of('\n', xfonts_pos); + + if (xfonts_start == std::string::npos) + return false; + + std::string const prefix = subst(sanitize_path(path_prefix), "\\", "\\\\"); + std::ostringstream ss; + ss << data.substr(0, xfonts_start) + << "\n" + "cat >>$outfile < const begin(fs); - std::istreambuf_iterator const end; + std::istreambuf_iterator const begin_ifs(ifs); + std::istreambuf_iterator const end_ifs; + std::string configure_data(begin_ifs, end_ifs); + ifs.close(); - std::string configure_data(begin, end); - std::string::size_type const xfonts_pos = configure_data.find("X FONTS"); - if (xfonts_pos == std::string::npos) { + // Does configure already contain a "path_prefix" entry + // or should we insert one? + std::string::size_type const prefix_pos = + configure_data.find("path_prefix"); + if (prefix_pos != std::string::npos) { + if (!replace_path_prefix(configure_data, prefix_pos, path_prefix)) { + pushstring("-1"); + return; + } + } else { + std::string::size_type const xfonts_pos = + configure_data.find("X FONTS"); + + if (xfonts_pos == std::string::npos) { + pushstring("-1"); + return; + } + + if (!insert_path_prefix(configure_data, xfonts_pos, path_prefix)) { + pushstring("-1"); + return; + } + } + + std::ofstream ofs(configure_file.c_str()); + if (!ofs) { pushstring("-1"); return; } - std::string::size_type const xfonts_start = - configure_data.find_last_of('\n', xfonts_pos); - if (xfonts_start == std::string::npos) { + ofs << configure_data; + pushstring("0"); +} + + +// Runs "sh configure" to generate things like lyxrc.defaults. +extern "C" +void __declspec(dllexport) run_configure(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) +{ + EXDLL_INIT(); + + std::string configure_file = pop_from_stack(); + std::string const path_prefix = pop_from_stack(); + + std::string const configure_dir = dirname(configure_file); + configure_file = basename(configure_file); + + if (configure_dir.empty()) { pushstring("-1"); return; } - fs.seekg(0); - fs << configure_data.substr(0, xfonts_start) - << "\n" - "cat >>$outfile <