mirror of
https://git.lyx.org/repos/lyx.git
synced 2025-01-20 23:00:29 +00:00
Backport of commit 13284.
Fix the way the installer handles the path_prefix stuff. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/branches/BRANCH_1_3_X@13288 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
87b4acd181
commit
34f04dda4a
@ -10,10 +10,11 @@
|
||||
* Full author contact details are available in file CREDITS or copy at
|
||||
* http://www.lyx.org/about/credits.php
|
||||
*
|
||||
* Define four functions that can be called from the NSIS installer:
|
||||
* Define five functions that can be called from the NSIS installer:
|
||||
*
|
||||
* set_path_prefix [ configure_file, path_prefix ]
|
||||
* create_bat_files [ bin_dir, lang ]
|
||||
* create_lyx_bat [ bin_dir, lang ]
|
||||
* create_relyx_bat [ bin_dir, lang ]
|
||||
* run_configure [ configure_file, path_prefix ]
|
||||
* set_env [ var_name, var_value ]
|
||||
*
|
||||
@ -28,17 +29,19 @@
|
||||
*
|
||||
* Compilation requires the exdll.h header file to be installed (here at
|
||||
* C:\Program Files\NSIS\Contrib\ExDLL\exdll.h). The file can be obtained
|
||||
* from http://cvs.sourceforge.net/viewcvs.py/nsis/NSIS/Contrib/ExDLL/
|
||||
* from http://cvs.sourceforge.net/viewcvs.py/nsis/NSIS/Contrib/ExDLL/
|
||||
*
|
||||
* Move the resulting lyx_configure.dll to /c/Program\ Files/NSIS/Plugins
|
||||
* Move the resulting lyx_configure.dll to C:\Program Files\NSIS\Plugins
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -106,10 +109,19 @@ std::list<std::string> const tokenize(std::string const & data,
|
||||
while (true) {
|
||||
std::string::size_type const end = data.find(separator, index);
|
||||
if (end == std::string::npos) {
|
||||
result.push_back(data);
|
||||
std::string::size_type const count =
|
||||
data.size() - index;
|
||||
std::string const elem = data.substr(index, count);
|
||||
if (elem.size() > 0) {
|
||||
result.push_back(elem);
|
||||
}
|
||||
break;
|
||||
}
|
||||
result.push_back(data.substr(0, end));
|
||||
std::string::size_type const count = end - index;
|
||||
std::string const elem = data.substr(index, count);
|
||||
if (elem.size() > 0) {
|
||||
result.push_back(elem);
|
||||
}
|
||||
index = (end+1 == data.size()) ? std::string::npos : end + 1;
|
||||
}
|
||||
return result;
|
||||
@ -188,8 +200,10 @@ std::string const sanitize_path_envvar(std::string const & in)
|
||||
// Ensure that each PATH element uses '\' directory separators
|
||||
// and doesn't end in a '\'.
|
||||
string_list::iterator const end = envvar.end();
|
||||
for (string_list::iterator it = envvar.begin(); it != end; ++it)
|
||||
*it = sanitize_win32_path(*it);
|
||||
for (string_list::iterator it = envvar.begin(); it != end; ++it) {
|
||||
std::string const new_path = sanitize_win32_path(*it);
|
||||
*it = new_path;
|
||||
}
|
||||
|
||||
remove_duplicates(envvar);
|
||||
return concatenate(envvar, ';');
|
||||
@ -260,47 +274,6 @@ bool insert_path_prefix(std::string & data,
|
||||
}
|
||||
|
||||
|
||||
// Inserts code into "configure" to output "path_prefix" to lyxrc.defaults.
|
||||
// \returns 0 on success, -1 on failure
|
||||
int set_path_prefix(std::string const & configure_file,
|
||||
std::string const & path_prefix)
|
||||
{
|
||||
std::ifstream ifs(configure_file.c_str());
|
||||
if (!ifs)
|
||||
return -1;
|
||||
|
||||
std::istreambuf_iterator<char> const begin_ifs(ifs);
|
||||
std::istreambuf_iterator<char> const end_ifs;
|
||||
std::string configure_data(begin_ifs, end_ifs);
|
||||
ifs.close();
|
||||
|
||||
// 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))
|
||||
return -1;
|
||||
} else {
|
||||
std::string::size_type const xfonts_pos =
|
||||
configure_data.find("X FONTS");
|
||||
|
||||
if (xfonts_pos == std::string::npos)
|
||||
return -1;
|
||||
|
||||
if (!insert_path_prefix(configure_data, xfonts_pos, path_prefix))
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::ofstream ofs(configure_file.c_str());
|
||||
if (!ofs)
|
||||
return -1;
|
||||
|
||||
ofs << configure_data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool write_bat(std::ostream & os, std::string const & quoted_exe)
|
||||
{
|
||||
os << "if \"%~1\" == \"~1\" goto win95\n"
|
||||
@ -314,35 +287,6 @@ bool write_bat(std::ostream & os, std::string const & quoted_exe)
|
||||
}
|
||||
|
||||
|
||||
// Creates the files lyx.bat and reLyX.bat in the LyX\bin folder.
|
||||
// \returns 0 on success, -1 on failure
|
||||
int create_bat_files(std::string const & bin_dir, std::string const & lang)
|
||||
{
|
||||
std::string const lyx_bat_file = bin_dir + "\\lyx.bat";
|
||||
std::ofstream lyx_bat(lyx_bat_file.c_str());
|
||||
if (!lyx_bat)
|
||||
return -1;
|
||||
|
||||
lyx_bat << "@echo off\n"
|
||||
<< "if \"%LANG%\"==\"\" SET LANG=" << lang << "\n";
|
||||
|
||||
std::string const lyx_exe_file = bin_dir + "\\lyx.exe";
|
||||
if (!write_bat(lyx_bat, "start \"LyX\" \"" + lyx_exe_file + "\""))
|
||||
return -1;
|
||||
|
||||
std::string const relyx_bat_file = bin_dir + "\\reLyX.bat";
|
||||
std::ofstream relyx_bat(relyx_bat_file.c_str());
|
||||
if (!relyx_bat)
|
||||
return -1;
|
||||
|
||||
std::string relyx_file = bin_dir + "\\reLyX";
|
||||
std::string relyx = "perl.exe \"" + relyx_file + "\"";
|
||||
if (!write_bat(relyx_bat, "perl.exe \"" + relyx_file + "\""))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// A wrapper for GetEnvironmentVariable
|
||||
bool get_environment_variable(std::string const & var, std::string & val)
|
||||
{
|
||||
@ -375,37 +319,165 @@ bool get_environment_variable(std::string const & var, std::string & val)
|
||||
}
|
||||
|
||||
|
||||
// Inserts code into "configure" to output "path_prefix" to lyxrc.defaults.
|
||||
// Throws std::runtime_error on failure.
|
||||
void set_path_prefix(std::string const & configure_file,
|
||||
std::string const & path_prefix)
|
||||
{
|
||||
std::ifstream ifs(configure_file.c_str());
|
||||
if (!ifs) {
|
||||
std::ostringstream ss;
|
||||
ss << "Unable to open " << configure_file << " for reading";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
std::istreambuf_iterator<char> const begin_ifs(ifs);
|
||||
std::istreambuf_iterator<char> const end_ifs;
|
||||
std::string configure_data(begin_ifs, end_ifs);
|
||||
ifs.close();
|
||||
|
||||
// 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)) {
|
||||
std::ostringstream ss;
|
||||
ss << "Unable to replace the existing path_prefix in "
|
||||
<< configure_file;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
} else {
|
||||
std::string::size_type const xfonts_pos =
|
||||
configure_data.find("if [ \"x$use_cygwin_path_fix");
|
||||
|
||||
if (xfonts_pos == std::string::npos) {
|
||||
std::ostringstream ss;
|
||||
ss << "Unable to find a position to insert the "
|
||||
"path_prefix entry in "
|
||||
<< configure_file;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
if (!insert_path_prefix(configure_data, xfonts_pos, path_prefix)) {
|
||||
std::ostringstream ss;
|
||||
ss << "Unable to insert a new path_prefix in "
|
||||
<< configure_file;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
std::ofstream ofs(configure_file.c_str());
|
||||
if (!ofs) {
|
||||
std::ostringstream ss;
|
||||
ss << "Unable to open " << configure_file << " for writing";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
ofs << configure_data;
|
||||
if (!ofs) {
|
||||
std::ostringstream ss;
|
||||
ss << "Failed to write " << configure_file;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Creates the lyx.bat file in the LyX\bin folder.
|
||||
// Throws std::runtime_error on failure.
|
||||
void create_lyx_bat(std::string const & bin_dir, std::string const & lang)
|
||||
{
|
||||
std::string const lyx_bat_file = bin_dir + "\\lyx.bat";
|
||||
std::ofstream ofs(lyx_bat_file.c_str());
|
||||
if (!ofs) {
|
||||
std::ostringstream ss;
|
||||
ss << "Unable to unable to open "
|
||||
<< lyx_bat_file << " for writing";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
ofs << "@echo off\n"
|
||||
<< "if \"%LANG%\"==\"\" SET LANG=" << lang << "\n";
|
||||
|
||||
std::string const lyx_exe_file = bin_dir + "\\lyx.exe";
|
||||
if (!write_bat(ofs, "start \"LyX\" \"" + lyx_exe_file + "\"")) {
|
||||
std::ostringstream ss;
|
||||
ss << "Failed to write to " << lyx_bat_file;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Creates the reLyX.bat file in the LyX\bin folder.
|
||||
// Throws std::runtime_error on failure.
|
||||
void create_relyx_bat(std::string const & bin_dir, std::string const & lang)
|
||||
{
|
||||
std::string const relyx_bat_file = bin_dir + "\\reLyX.bat";
|
||||
std::ofstream ofs(relyx_bat_file.c_str());
|
||||
if (!ofs) {
|
||||
std::ostringstream ss;
|
||||
ss << "Unable to unable to open "
|
||||
<< relyx_bat_file << " for writing";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
std::string relyx_file = bin_dir + "\\reLyX";
|
||||
std::string relyx = "perl.exe \"" + relyx_file + "\"";
|
||||
if (!write_bat(ofs, "perl.exe \"" + relyx_file + "\"")) {
|
||||
std::ostringstream ss;
|
||||
ss << "Failed to write to " << relyx_bat_file;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Runs "sh configure" to generate things like lyxrc.defaults.
|
||||
// \returns 0 on success, -1 on failure
|
||||
int run_configure(std::string const & abs_configure_file_in,
|
||||
std::string const & path_prefix)
|
||||
// Throws std::runtime_error on failure.
|
||||
void run_configure(std::string const & abs_configure_file_in,
|
||||
std::string const & path_prefix)
|
||||
{
|
||||
std::string const abs_configure_file =
|
||||
sanitize_win32_path(abs_configure_file_in);
|
||||
std::string const configure_dir = dirname(abs_configure_file);
|
||||
std::string const configure_file = basename(abs_configure_file);
|
||||
|
||||
if (configure_file.empty() || configure_dir.empty())
|
||||
return -1;
|
||||
if (configure_file.empty() || configure_dir.empty()) {
|
||||
std::ostringstream ss;
|
||||
ss << "Invalid path to configure file: "
|
||||
<< abs_configure_file;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
if (SetCurrentDirectory(configure_dir.c_str()) == 0)
|
||||
return -1;
|
||||
if (SetCurrentDirectory(configure_dir.c_str()) == 0) {
|
||||
std::ostringstream ss;
|
||||
ss << "Unable to cd "<< configure_dir;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
std::string path;
|
||||
if (!get_environment_variable("PATH", path))
|
||||
return -1;
|
||||
if (!get_environment_variable("PATH", path)) {
|
||||
std::ostringstream ss;
|
||||
ss << "Unable to grab the PATH environment variable";
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
path = sanitize_path_envvar(path_prefix + ';' + path);
|
||||
if (SetEnvironmentVariable("PATH", path.c_str()) == 0)
|
||||
return -1;
|
||||
if (SetEnvironmentVariable("PATH", path.c_str()) == 0) {
|
||||
std::ostringstream ss;
|
||||
ss << "Failed to set the PATH environment variable to:\n"
|
||||
<< path << '\n';
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
|
||||
// Even "start /WAIT /B sh.exe configure" returns
|
||||
// before the script is done, so just invoke "sh" directly.
|
||||
|
||||
// Assumes that configure_file does not need quoting.
|
||||
std::string const command = std::string("sh.exe ") + configure_file;
|
||||
if (system(command.c_str()) != 0)
|
||||
return -1;
|
||||
return 0;
|
||||
if (system(command.c_str()) != 0) {
|
||||
std::ostringstream ss;
|
||||
ss << "Failed to run: " << command;
|
||||
throw std::runtime_error(ss.str());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace anon
|
||||
@ -441,14 +513,53 @@ void __declspec(dllexport) set_path_prefix(HWND const /*hwndParent*/,
|
||||
return;
|
||||
}
|
||||
|
||||
int const result = set_path_prefix(configure_file, path_prefix);
|
||||
int result = 0;
|
||||
try {
|
||||
set_path_prefix(configure_file, path_prefix);
|
||||
}
|
||||
catch(std::exception const & ex) {
|
||||
std::cerr << "ERROR: set_path_prefix:\n\t"
|
||||
<< ex.what() << '\n';
|
||||
result = -1;
|
||||
}
|
||||
|
||||
push_to_stack(result);
|
||||
}
|
||||
|
||||
|
||||
// Creates the files lyx.bat and reLyX.bat in the LyX\bin folder.
|
||||
// Creates the lyx.bat file in the LyX\bin folder.
|
||||
extern "C"
|
||||
void __declspec(dllexport) create_bat_files(HWND const /*hwndParent*/,
|
||||
void __declspec(dllexport) create_lyx_bat(HWND const /*hwndParent*/,
|
||||
int const string_size,
|
||||
char * const variables,
|
||||
stack_t ** const stacktop)
|
||||
{
|
||||
EXDLL_INIT();
|
||||
|
||||
std::string const bin_dir = pop_from_stack();
|
||||
std::string const lang = pop_from_stack();
|
||||
if (bin_dir.empty() || lang.empty()) {
|
||||
push_to_stack(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
try {
|
||||
create_lyx_bat(bin_dir, lang);
|
||||
}
|
||||
catch(std::exception const & ex) {
|
||||
std::cerr << "ERROR: create_lyx_bat:\n\t"
|
||||
<< ex.what() << '\n';
|
||||
result = -1;
|
||||
}
|
||||
|
||||
push_to_stack(result);
|
||||
}
|
||||
|
||||
|
||||
// Creates the reLyX.bat file in the LyX\bin folder.
|
||||
extern "C"
|
||||
void __declspec(dllexport) create_relyx_bat(HWND const /*hwndParent*/,
|
||||
int const string_size,
|
||||
char * const variables,
|
||||
stack_t ** const stacktop)
|
||||
@ -462,7 +573,16 @@ void __declspec(dllexport) create_bat_files(HWND const /*hwndParent*/,
|
||||
return;
|
||||
}
|
||||
|
||||
int const result = create_bat_files(bin_dir, lang);
|
||||
int result = 0;
|
||||
try {
|
||||
create_relyx_bat(bin_dir, lang);
|
||||
}
|
||||
catch(std::exception const & ex) {
|
||||
std::cerr << "ERROR: create_relyx_bat:\n\t"
|
||||
<< ex.what() << '\n';
|
||||
result = -1;
|
||||
}
|
||||
|
||||
push_to_stack(result);
|
||||
}
|
||||
|
||||
@ -483,7 +603,16 @@ void __declspec(dllexport) run_configure(HWND const /*hwndParent*/,
|
||||
return;
|
||||
}
|
||||
|
||||
int const result = run_configure(configure_file, path_prefix);
|
||||
int result = 0;
|
||||
try {
|
||||
run_configure(configure_file, path_prefix);
|
||||
}
|
||||
catch(std::exception const & ex) {
|
||||
std::cerr << "ERROR: run_configure:\n\t"
|
||||
<< ex.what() << '\n';
|
||||
result = -1;
|
||||
}
|
||||
|
||||
push_to_stack(result);
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,13 @@ Section "-Installation actions" SecInstallation
|
||||
${endif}
|
||||
${endif}
|
||||
|
||||
lyx_configure::create_bat_files "$INSTDIR\bin" "$LangCode"
|
||||
lyx_configure::create_lyx_bat "$INSTDIR\bin" "$LangCode"
|
||||
Pop $0
|
||||
${if} $0 != 0
|
||||
MessageBox MB_OK "$(CreateCmdFilesFailed)"
|
||||
${endif}
|
||||
|
||||
lyx_configure::create_relyx_bat "$INSTDIR\bin" "$LangCode"
|
||||
Pop $0
|
||||
${if} $0 != 0
|
||||
MessageBox MB_OK "$(CreateCmdFilesFailed)"
|
||||
|
Loading…
x
Reference in New Issue
Block a user