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
This commit is contained in:
Angus Leeming 2005-06-08 13:14:50 +00:00
parent 155b43abad
commit 87fbbe0a56
5 changed files with 216 additions and 43 deletions

View File

@ -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}"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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 <stdlib.h>
#include <fstream>
#include <iostream>
#include <list>
#include <sstream>
#include <string>
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<std::string> const tokenize(std::string data,
char const separator)
{
std::list<std::string> 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<std::string> & data)
{
typedef std::list<std::string>::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<std::string> const & data,
char const separator)
{
typedef std::list<std::string>::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<std::string> 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 <<EOF\n"
"\n"
"\\\\path_prefix \"" << prefix << "\"\n"
"EOF\n"
<< data.substr(xfonts_start);
data = ss.str();
return true;
}
} // namespace anon
@ -57,76 +201,97 @@ BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
}
// Inserts code into "configure" to output "path_prefix" to lyxrc.defaults.
extern "C"
void __declspec(dllexport) set(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
void __declspec(dllexport) set_path_prefix(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
{
char configure_file[MAX_PATH];
char path_prefix[MAX_PATH];
EXDLL_INIT();
popstring(configure_file);
popstring(path_prefix);
std::string const configure_file = pop_from_stack();
std::string const path_prefix = pop_from_stack();
std::fstream fs(configure_file);
if (!fs) {
std::ifstream ifs(configure_file.c_str());
if (!ifs) {
pushstring("-1");
return;
}
std::istreambuf_iterator<char> const begin(fs);
std::istreambuf_iterator<char> const end;
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();
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 <<EOF\n"
"\n"
"\\\\path_prefix \"" << subst(path_prefix, "\\", "\\\\") << "\"\n"
"EOF\n"
<< configure_data.substr(xfonts_start);
// Now we've rebuilt configure, run it to generate things like
// lyxrc.defaults.
std::string configure_dir(configure_file);
std::string::size_type const final_slash = configure_dir.find_last_of('\\');
if (final_slash == std::string::npos) {
pushstring("-1");
return;
}
configure_dir = configure_dir.substr(0, final_slash);
if (SetCurrentDirectory(configure_dir.c_str()) == 0) {
pushstring("-1");
return;
}
char path[MAX_PATH];
if (GetEnvironmentVariable("PATH", path, MAX_PATH) == 0) {
char path_orig[10*MAX_PATH];
if (GetEnvironmentVariable("PATH", path_orig, 10*MAX_PATH) == 0) {
pushstring("-1");
return;
}
std::string const path_str = std::string(path_prefix) + ';' + path;
if (SetEnvironmentVariable("PATH", path_str.c_str()) == 0) {
std::string const path = path_prefix + ';' + path_orig;
if (SetEnvironmentVariable("PATH", path.c_str()) == 0) {
pushstring("-1");
return;
}
if (system("start /min sh.exe configure") != 0) {
std::string const command = std::string("start /WAIT /B sh.exe ") + configure_file;
if (system(command.c_str()) != 0) {
pushstring("-1");
return;
}