X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fsupport%2Fos_win32.cpp;h=82e57d2eb69adfe1a72074505bae21856b58016b;hb=b96ce9a9c101a711ef8a1cdd5d6fe812a18966da;hp=a8ffaa54773f93a5e40220c31b6f5efd3842142b;hpb=3fce202517109a26e90a08759b82f8e6c2ae8903;p=lyx.git diff --git a/src/support/os_win32.cpp b/src/support/os_win32.cpp index a8ffaa5477..82e57d2eb6 100644 --- a/src/support/os_win32.cpp +++ b/src/support/os_win32.cpp @@ -15,10 +15,13 @@ #include +#include "LyXRC.h" + #include "support/os.h" #include "support/os_win32.h" #include "support/debug.h" +#include "support/environment.h" #include "support/FileName.h" #include "support/gettext.h" #include "support/filetools.h" @@ -35,6 +38,7 @@ #include #include // _getdrive +#include // GetFinalPathNameByHandle #include // SHGetFolderPath #include #include @@ -53,10 +57,17 @@ #define ASSOCF_INIT_IGNOREUNKNOWN 0 #endif +#if defined(__MINGW32__) +#include +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +#else extern "C" { extern void __wgetmainargs(int * argc, wchar_t *** argv, wchar_t *** envp, int expand_wildcards, int * new_mode); } +#endif using namespace std; @@ -87,9 +98,9 @@ BOOL terminate_handler(DWORD event) return FALSE; } -} // namespace anon +} // namespace -void init(int argc, char * argv[]) +void init(int argc, char ** argv[]) { /* Note from Angus, 17 Jan 2005: * @@ -148,11 +159,36 @@ void init(int argc, char * argv[]) */ + // Remove PYTHONPATH from the environment as it may point to an + // external python installation and cause reconfigure failures. + unsetEnv("PYTHONPATH"); + + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) + // Removing an argument from argv leads to an assertion on Windows + // when compiling with MSVC 2015 in debug mode (see bug #10440). + // To avoid this we make a copy of the array of pointers. + char ** newargv = (char **) malloc((argc + 1) * sizeof(char *)); + if (newargv) { + memcpy(newargv, *argv, (argc + 1) * sizeof(char *)); + *argv = newargv; + } else { + lyxerr << "LyX warning: Cannot make a copy of " + "command line arguments!" + << endl; + } +#endif + + // Get the wide program arguments array +#if defined(_MSC_VER) && (_MSC_VER >= 1900) + argv_ = CommandLineToArgvW(GetCommandLineW(), &argc_); +#else wchar_t ** envp = 0; int newmode = 0; __wgetmainargs(&argc_, &argv_, &envp, -1, &newmode); - LASSERT(argc == argc_, /**/); +#endif + LATTEST(argc == argc_); // If Cygwin is detected, query the cygdrive prefix. // The cygdrive prefix is needed for translating windows style paths @@ -204,11 +240,19 @@ void init(int argc, char * argv[]) string utf8_argv(int i) { - LASSERT(i < argc_, /**/); + LASSERT(i < argc_, return ""); return fromqstr(QString::fromWCharArray(argv_[i])); } +void remove_internal_args(int i, int num) +{ + argc_ -= num; + for (int j = i; j < argc_; ++j) + argv_[j] = argv_[j + num]; +} + + string current_root() { // _getdrive returns the current drive (1=A, 2=B, and so on). @@ -296,7 +340,7 @@ static QString const get_long_path(QString const & short_path) long_path.resize(result); result = GetLongPathNameW((wchar_t *) short_path.utf16(), &long_path[0], long_path.size()); - LASSERT(result <= long_path.size(), /**/); + LATTEST(result <= long_path.size()); } return (result == 0) ? short_path : QString::fromWCharArray(&long_path[0]); @@ -323,7 +367,7 @@ static QString const get_short_path(QString const & long_path, file_access how) short_path.resize(result); result = GetShortPathNameW((wchar_t *) long_path.utf16(), &short_path[0], short_path.size()); - LASSERT(result <= short_path.size(), /**/); + LATTEST(result <= short_path.size()); } return (result == 0) ? long_path : QString::fromWCharArray(&short_path[0]); @@ -372,20 +416,35 @@ string latex_path(string const & p) } -bool is_valid_strftime(string const & p) +string latex_path_list(string const & p) { - string::size_type pos = p.find_first_of('%'); - while (pos != string::npos) { - if (pos + 1 == string::npos) - break; - if (!containsOnly(p.substr(pos + 1, 1), - "aAbBcdfHIjmMpSUwWxXyYzZ%")) - return false; - if (pos + 2 == string::npos) - break; - pos = p.find_first_of('%', pos + 2); + if (p.empty()) + return p; + + // We may need a posix style path or a windows style path (depending + // on windows_style_tex_paths_), but we use always forward slashes, + // since this is standard for all tex engines. + + if (!windows_style_tex_paths_) { + string pathlist; + for (size_t i = 0, k = 0; i != string::npos; k = i) { + i = p.find(';', i); + string path = subst(p.substr(k, i - k), '\\', '/'); + if (FileName::isAbsolute(path)) { + string const drive = path.substr(0, 2); + string const cygprefix = cygdrive + "/" + + drive.substr(0, 1); + path = subst(path, drive, cygprefix); + } + pathlist += path; + if (i != string::npos) { + pathlist += ':'; + ++i; + } + } + return pathlist; } - return true; + return subst(p, '\\', '/'); } @@ -404,34 +463,17 @@ string const & nulldev() } -bool is_terminal(io_channel channel) -{ - switch (channel) { - case STDIN: - if (GetStdHandle(STD_INPUT_HANDLE) == NULL) - return false; - break; - case STDOUT: - if (GetStdHandle(STD_OUTPUT_HANDLE) == NULL) - return false; - break; - case STDERR: - if (GetStdHandle(STD_ERROR_HANDLE) == NULL) - return false; - break; - } - return true; -} - - shell_type shell() { return CMD_EXE; } -char path_separator() +char path_separator(path_type type) { + if (type == TEXENGINE) + return windows_style_tex_paths_ ? ';' : ':'; + return ';'; } @@ -483,7 +525,7 @@ string const GetFolderPath::operator()(folder_id _id) const id = CSIDL_APPDATA; break; default: - LASSERT(false, /**/); + LASSERT(false, return string()); } HRESULT const result = (folder_path_func_)(0, id, 0, SHGFP_TYPE_CURRENT, @@ -508,12 +550,43 @@ bool canAutoOpenFile(string const & ext, auto_open_mode const mode) } -bool autoOpenFile(string const & filename, auto_open_mode const mode) +bool autoOpenFile(string const & filename, auto_open_mode const mode, + string const & path) { + string const texinputs = os::latex_path_list( + replaceCurdirPath(path, lyxrc.texinputs_prefix)); + string const otherinputs = os::latex_path_list(path); + string const sep = windows_style_tex_paths_ ? ";" : ":"; + string const oldtexinputs = getEnv("TEXINPUTS"); + string const newtexinputs = "." + sep + texinputs + sep + oldtexinputs; + string const oldbibinputs = getEnv("BIBINPUTS"); + string const newbibinputs = "." + sep + otherinputs + sep + oldbibinputs; + string const oldbstinputs = getEnv("BSTINPUTS"); + string const newbstinputs = "." + sep + otherinputs + sep + oldbstinputs; + string const oldtexfonts = getEnv("TEXFONTS"); + string const newtexfonts = "." + sep + otherinputs + sep + oldtexfonts; + if (!path.empty() && !lyxrc.texinputs_prefix.empty()) { + setEnv("TEXINPUTS", newtexinputs); + setEnv("BIBINPUTS", newbibinputs); + setEnv("BSTINPUTS", newbstinputs); + setEnv("TEXFONTS", newtexfonts); + } + + QString const wname = toqstr(filename); + // reference: http://msdn.microsoft.com/en-us/library/bb762153.aspx - char const * action = (mode == VIEW) ? "open" : "edit"; - return reinterpret_cast(ShellExecute(NULL, action, - to_local8bit(from_utf8(filename)).c_str(), NULL, NULL, 1)) > 32; + wchar_t const * action = (mode == VIEW) ? L"open" : L"edit"; + bool success = reinterpret_cast(ShellExecuteW(NULL, action, + reinterpret_cast(wname.utf16()), + NULL, NULL, 1)) > 32; + + if (!path.empty() && !lyxrc.texinputs_prefix.empty()) { + setEnv("TEXINPUTS", oldtexinputs); + setEnv("BIBINPUTS", oldbibinputs); + setEnv("BSTINPUTS", oldbstinputs); + setEnv("TEXFONTS", oldtexfonts); + } + return success; } @@ -522,45 +595,18 @@ string real_path(string const & path) // See http://msdn.microsoft.com/en-us/library/aa366789(VS.85).aspx QString const qpath = get_long_path(toqstr(path)); HANDLE hpath = CreateFileW((wchar_t *) qpath.utf16(), GENERIC_READ, - FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, NULL); if (hpath == INVALID_HANDLE_VALUE) { // The file cannot be accessed. return path; } - // Get the file size. - DWORD size_hi = 0; - DWORD size_lo = GetFileSize(hpath, &size_hi); - - if (size_lo == 0 && size_hi == 0) { - // A zero-length file cannot be mapped. - CloseHandle(hpath); - return path; - } - - // Create a file mapping object. - HANDLE hmap = CreateFileMapping(hpath, NULL, PAGE_READONLY, 0, 1, NULL); - - if (!hmap) { - CloseHandle(hpath); - return path; - } - - // Create a file mapping to get the file name. - void * pmem = MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 1); - - if (!pmem) { - CloseHandle(hmap); - CloseHandle(hpath); - return path; - } - TCHAR realpath[MAX_PATH + 1]; - if (!GetMappedFileName(GetCurrentProcess(), pmem, realpath, MAX_PATH)) { - UnmapViewOfFile(pmem); - CloseHandle(hmap); + DWORD size = GetFinalPathNameByHandle(hpath, realpath, MAX_PATH, VOLUME_NAME_NT); + if (size > MAX_PATH) { CloseHandle(hpath); return path; } @@ -606,11 +652,9 @@ string real_path(string const & path) while (*p++) ; } while (!found && *p); } - UnmapViewOfFile(pmem); - CloseHandle(hmap); CloseHandle(hpath); string const retpath = subst(string(realpath), '\\', '/'); - return FileName::fromFilesystemEncoding(retpath).absFilename(); + return FileName::fromFilesystemEncoding(retpath).absFileName(); } } // namespace os